Linux Audio

Check our new training course

Loading...
v3.5.6
   1/*
   2 * OMAP powerdomain control
   3 *
   4 * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
   5 * Copyright (C) 2007-2011 Nokia Corporation
   6 *
   7 * Written by Paul Walmsley
   8 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
   9 * State counting code by Tero Kristo <tero.kristo@nokia.com>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15#undef DEBUG
  16
  17#include <linux/kernel.h>
  18#include <linux/types.h>
  19#include <linux/list.h>
  20#include <linux/errno.h>
  21#include <linux/string.h>
 
  22#include <trace/events/power.h>
  23
  24#include "cm2xxx_3xxx.h"
  25#include "prcm44xx.h"
  26#include "cm44xx.h"
  27#include "prm2xxx_3xxx.h"
  28#include "prm44xx.h"
  29
  30#include <asm/cpu.h>
  31#include <plat/cpu.h>
  32#include "powerdomain.h"
  33#include "clockdomain.h"
  34#include <plat/prcm.h>
  35
 
  36#include "pm.h"
  37
  38#define PWRDM_TRACE_STATES_FLAG	(1<<31)
  39
  40enum {
  41	PWRDM_STATE_NOW = 0,
  42	PWRDM_STATE_PREV,
  43};
  44
 
 
 
 
 
 
 
 
 
  45
  46/* pwrdm_list contains all registered struct powerdomains */
  47static LIST_HEAD(pwrdm_list);
  48
  49static struct pwrdm_ops *arch_pwrdm;
  50
  51/* Private functions */
  52
  53static struct powerdomain *_pwrdm_lookup(const char *name)
  54{
  55	struct powerdomain *pwrdm, *temp_pwrdm;
  56
  57	pwrdm = NULL;
  58
  59	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
  60		if (!strcmp(name, temp_pwrdm->name)) {
  61			pwrdm = temp_pwrdm;
  62			break;
  63		}
  64	}
  65
  66	return pwrdm;
  67}
  68
  69/**
  70 * _pwrdm_register - register a powerdomain
  71 * @pwrdm: struct powerdomain * to register
  72 *
  73 * Adds a powerdomain to the internal powerdomain list.  Returns
  74 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
  75 * already registered by the provided name, or 0 upon success.
  76 */
  77static int _pwrdm_register(struct powerdomain *pwrdm)
  78{
  79	int i;
  80	struct voltagedomain *voltdm;
  81
  82	if (!pwrdm || !pwrdm->name)
  83		return -EINVAL;
  84
  85	if (cpu_is_omap44xx() &&
  86	    pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
  87		pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
  88		       pwrdm->name);
  89		return -EINVAL;
  90	}
  91
  92	if (_pwrdm_lookup(pwrdm->name))
  93		return -EEXIST;
  94
 
 
 
 
  95	voltdm = voltdm_lookup(pwrdm->voltdm.name);
  96	if (!voltdm) {
  97		pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
  98		       pwrdm->name, pwrdm->voltdm.name);
  99		return -EINVAL;
 100	}
 101	pwrdm->voltdm.ptr = voltdm;
 102	INIT_LIST_HEAD(&pwrdm->voltdm_node);
 103	voltdm_add_pwrdm(voltdm, pwrdm);
 
 104
 105	list_add(&pwrdm->node, &pwrdm_list);
 106
 107	/* Initialize the powerdomain's state counter */
 108	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
 109		pwrdm->state_counter[i] = 0;
 110
 111	pwrdm->ret_logic_off_counter = 0;
 112	for (i = 0; i < pwrdm->banks; i++)
 113		pwrdm->ret_mem_off_counter[i] = 0;
 114
 115	pwrdm_wait_transition(pwrdm);
 
 116	pwrdm->state = pwrdm_read_pwrst(pwrdm);
 117	pwrdm->state_counter[pwrdm->state] = 1;
 118
 119	pr_debug("powerdomain: registered %s\n", pwrdm->name);
 120
 121	return 0;
 122}
 123
 124static void _update_logic_membank_counters(struct powerdomain *pwrdm)
 125{
 126	int i;
 127	u8 prev_logic_pwrst, prev_mem_pwrst;
 128
 129	prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
 130	if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
 131	    (prev_logic_pwrst == PWRDM_POWER_OFF))
 132		pwrdm->ret_logic_off_counter++;
 133
 134	for (i = 0; i < pwrdm->banks; i++) {
 135		prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
 136
 137		if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
 138		    (prev_mem_pwrst == PWRDM_POWER_OFF))
 139			pwrdm->ret_mem_off_counter[i]++;
 140	}
 141}
 142
 143static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 144{
 145
 146	int prev, state, trace_state = 0;
 147
 148	if (pwrdm == NULL)
 149		return -EINVAL;
 150
 151	state = pwrdm_read_pwrst(pwrdm);
 152
 153	switch (flag) {
 154	case PWRDM_STATE_NOW:
 155		prev = pwrdm->state;
 156		break;
 157	case PWRDM_STATE_PREV:
 158		prev = pwrdm_read_prev_pwrst(pwrdm);
 159		if (pwrdm->state != prev)
 160			pwrdm->state_counter[prev]++;
 161		if (prev == PWRDM_POWER_RET)
 162			_update_logic_membank_counters(pwrdm);
 163		/*
 164		 * If the power domain did not hit the desired state,
 165		 * generate a trace event with both the desired and hit states
 166		 */
 167		if (state != prev) {
 
 168			trace_state = (PWRDM_TRACE_STATES_FLAG |
 169				       ((state & OMAP_POWERSTATE_MASK) << 8) |
 170				       ((prev & OMAP_POWERSTATE_MASK) << 0));
 171			trace_power_domain_target(pwrdm->name, trace_state,
 172						  smp_processor_id());
 
 173		}
 174		break;
 175	default:
 176		return -EINVAL;
 177	}
 178
 179	if (state != prev)
 180		pwrdm->state_counter[state]++;
 181
 182	pm_dbg_update_time(pwrdm, prev);
 183
 184	pwrdm->state = state;
 185
 186	return 0;
 187}
 188
 189static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
 190{
 191	pwrdm_clear_all_prev_pwrst(pwrdm);
 192	_pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
 193	return 0;
 194}
 195
 196static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
 197{
 198	_pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
 199	return 0;
 200}
 201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 202/* Public functions */
 203
 204/**
 205 * pwrdm_register_platform_funcs - register powerdomain implementation fns
 206 * @po: func pointers for arch specific implementations
 207 *
 208 * Register the list of function pointers used to implement the
 209 * powerdomain functions on different OMAP SoCs.  Should be called
 210 * before any other pwrdm_register*() function.  Returns -EINVAL if
 211 * @po is null, -EEXIST if platform functions have already been
 212 * registered, or 0 upon success.
 213 */
 214int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
 215{
 216	if (!po)
 217		return -EINVAL;
 218
 219	if (arch_pwrdm)
 220		return -EEXIST;
 221
 222	arch_pwrdm = po;
 223
 224	return 0;
 225}
 226
 227/**
 228 * pwrdm_register_pwrdms - register SoC powerdomains
 229 * @ps: pointer to an array of struct powerdomain to register
 230 *
 231 * Register the powerdomains available on a particular OMAP SoC.  Must
 232 * be called after pwrdm_register_platform_funcs().  May be called
 233 * multiple times.  Returns -EACCES if called before
 234 * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
 235 * null; or 0 upon success.
 236 */
 237int pwrdm_register_pwrdms(struct powerdomain **ps)
 238{
 239	struct powerdomain **p = NULL;
 240
 241	if (!arch_pwrdm)
 242		return -EEXIST;
 243
 244	if (!ps)
 245		return -EINVAL;
 246
 247	for (p = ps; *p; p++)
 248		_pwrdm_register(*p);
 249
 250	return 0;
 251}
 252
 253/**
 254 * pwrdm_complete_init - set up the powerdomain layer
 255 *
 256 * Do whatever is necessary to initialize registered powerdomains and
 257 * powerdomain code.  Currently, this programs the next power state
 258 * for each powerdomain to ON.  This prevents powerdomains from
 259 * unexpectedly losing context or entering high wakeup latency modes
 260 * with non-power-management-enabled kernels.  Must be called after
 261 * pwrdm_register_pwrdms().  Returns -EACCES if called before
 262 * pwrdm_register_pwrdms(), or 0 upon success.
 263 */
 264int pwrdm_complete_init(void)
 265{
 266	struct powerdomain *temp_p;
 267
 268	if (list_empty(&pwrdm_list))
 269		return -EACCES;
 270
 271	list_for_each_entry(temp_p, &pwrdm_list, node)
 272		pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
 273
 274	return 0;
 275}
 276
 277/**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 278 * pwrdm_lookup - look up a powerdomain by name, return a pointer
 279 * @name: name of powerdomain
 280 *
 281 * Find a registered powerdomain by its name @name.  Returns a pointer
 282 * to the struct powerdomain if found, or NULL otherwise.
 283 */
 284struct powerdomain *pwrdm_lookup(const char *name)
 285{
 286	struct powerdomain *pwrdm;
 287
 288	if (!name)
 289		return NULL;
 290
 291	pwrdm = _pwrdm_lookup(name);
 292
 293	return pwrdm;
 294}
 295
 296/**
 297 * pwrdm_for_each - call function on each registered clockdomain
 298 * @fn: callback function *
 299 *
 300 * Call the supplied function @fn for each registered powerdomain.
 301 * The callback function @fn can return anything but 0 to bail out
 302 * early from the iterator.  Returns the last return value of the
 303 * callback function, which should be 0 for success or anything else
 304 * to indicate failure; or -EINVAL if the function pointer is null.
 305 */
 306int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
 307		   void *user)
 308{
 309	struct powerdomain *temp_pwrdm;
 310	int ret = 0;
 311
 312	if (!fn)
 313		return -EINVAL;
 314
 315	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
 316		ret = (*fn)(temp_pwrdm, user);
 317		if (ret)
 318			break;
 319	}
 320
 321	return ret;
 322}
 323
 324/**
 325 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
 326 * @pwrdm: struct powerdomain * to add the clockdomain to
 327 * @clkdm: struct clockdomain * to associate with a powerdomain
 328 *
 329 * Associate the clockdomain @clkdm with a powerdomain @pwrdm.  This
 330 * enables the use of pwrdm_for_each_clkdm().  Returns -EINVAL if
 331 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
 332 * or 0 upon success.
 333 */
 334int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
 335{
 336	int i;
 337	int ret = -EINVAL;
 338
 339	if (!pwrdm || !clkdm)
 340		return -EINVAL;
 341
 342	pr_debug("powerdomain: associating clockdomain %s with powerdomain "
 343		 "%s\n", clkdm->name, pwrdm->name);
 344
 345	for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
 346		if (!pwrdm->pwrdm_clkdms[i])
 347			break;
 348#ifdef DEBUG
 349		if (pwrdm->pwrdm_clkdms[i] == clkdm) {
 350			ret = -EINVAL;
 351			goto pac_exit;
 352		}
 353#endif
 354	}
 355
 356	if (i == PWRDM_MAX_CLKDMS) {
 357		pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
 358			 "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
 359		WARN_ON(1);
 360		ret = -ENOMEM;
 361		goto pac_exit;
 362	}
 363
 364	pwrdm->pwrdm_clkdms[i] = clkdm;
 365
 366	ret = 0;
 367
 368pac_exit:
 369	return ret;
 370}
 371
 372/**
 373 * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
 374 * @pwrdm: struct powerdomain * to add the clockdomain to
 375 * @clkdm: struct clockdomain * to associate with a powerdomain
 376 *
 377 * Dissociate the clockdomain @clkdm from the powerdomain
 378 * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
 379 * if @clkdm was not associated with the powerdomain, or 0 upon
 380 * success.
 381 */
 382int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
 383{
 384	int ret = -EINVAL;
 385	int i;
 386
 387	if (!pwrdm || !clkdm)
 388		return -EINVAL;
 389
 390	pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
 391		 "%s\n", clkdm->name, pwrdm->name);
 392
 393	for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
 394		if (pwrdm->pwrdm_clkdms[i] == clkdm)
 395			break;
 396
 397	if (i == PWRDM_MAX_CLKDMS) {
 398		pr_debug("powerdomain: clkdm %s not associated with pwrdm "
 399			 "%s ?!\n", clkdm->name, pwrdm->name);
 400		ret = -ENOENT;
 401		goto pdc_exit;
 402	}
 403
 404	pwrdm->pwrdm_clkdms[i] = NULL;
 405
 406	ret = 0;
 407
 408pdc_exit:
 409	return ret;
 410}
 411
 412/**
 413 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
 414 * @pwrdm: struct powerdomain * to iterate over
 415 * @fn: callback function *
 416 *
 417 * Call the supplied function @fn for each clockdomain in the powerdomain
 418 * @pwrdm.  The callback function can return anything but 0 to bail
 419 * out early from the iterator.  Returns -EINVAL if presented with
 420 * invalid pointers; or passes along the last return value of the
 421 * callback function, which should be 0 for success or anything else
 422 * to indicate failure.
 423 */
 424int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
 425			 int (*fn)(struct powerdomain *pwrdm,
 426				   struct clockdomain *clkdm))
 427{
 428	int ret = 0;
 429	int i;
 430
 431	if (!fn)
 432		return -EINVAL;
 433
 434	for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
 435		ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
 436
 437	return ret;
 438}
 439
 440/**
 441 * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
 442 * @pwrdm: struct powerdomain *
 443 *
 444 * Return a pointer to the struct voltageomain that the specified powerdomain
 445 * @pwrdm exists in.
 446 */
 447struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
 448{
 449	return pwrdm->voltdm.ptr;
 450}
 451
 452/**
 453 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
 454 * @pwrdm: struct powerdomain *
 455 *
 456 * Return the number of controllable memory banks in powerdomain @pwrdm,
 457 * starting with 1.  Returns -EINVAL if the powerdomain pointer is null.
 458 */
 459int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
 460{
 461	if (!pwrdm)
 462		return -EINVAL;
 463
 464	return pwrdm->banks;
 465}
 466
 467/**
 468 * pwrdm_set_next_pwrst - set next powerdomain power state
 469 * @pwrdm: struct powerdomain * to set
 470 * @pwrst: one of the PWRDM_POWER_* macros
 471 *
 472 * Set the powerdomain @pwrdm's next power state to @pwrst.  The powerdomain
 473 * may not enter this state immediately if the preconditions for this state
 474 * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
 475 * null or if the power state is invalid for the powerdomin, or returns 0
 476 * upon success.
 477 */
 478int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 479{
 480	int ret = -EINVAL;
 481
 482	if (!pwrdm)
 483		return -EINVAL;
 484
 485	if (!(pwrdm->pwrsts & (1 << pwrst)))
 486		return -EINVAL;
 487
 488	pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
 489		 pwrdm->name, pwrst);
 490
 491	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
 492		/* Trace the pwrdm desired target state */
 493		trace_power_domain_target(pwrdm->name, pwrst,
 494					  smp_processor_id());
 495		/* Program the pwrdm desired target state */
 496		ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
 497	}
 498
 499	return ret;
 500}
 501
 502/**
 503 * pwrdm_read_next_pwrst - get next powerdomain power state
 504 * @pwrdm: struct powerdomain * to get power state
 505 *
 506 * Return the powerdomain @pwrdm's next power state.  Returns -EINVAL
 507 * if the powerdomain pointer is null or returns the next power state
 508 * upon success.
 509 */
 510int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
 511{
 512	int ret = -EINVAL;
 513
 514	if (!pwrdm)
 515		return -EINVAL;
 516
 517	if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
 518		ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
 519
 520	return ret;
 521}
 522
 523/**
 524 * pwrdm_read_pwrst - get current powerdomain power state
 525 * @pwrdm: struct powerdomain * to get power state
 526 *
 527 * Return the powerdomain @pwrdm's current power state.	Returns -EINVAL
 528 * if the powerdomain pointer is null or returns the current power state
 529 * upon success.
 
 530 */
 531int pwrdm_read_pwrst(struct powerdomain *pwrdm)
 532{
 533	int ret = -EINVAL;
 534
 535	if (!pwrdm)
 536		return -EINVAL;
 537
 
 
 
 538	if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
 539		ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
 540
 541	return ret;
 542}
 543
 544/**
 545 * pwrdm_read_prev_pwrst - get previous powerdomain power state
 546 * @pwrdm: struct powerdomain * to get previous power state
 547 *
 548 * Return the powerdomain @pwrdm's previous power state.  Returns -EINVAL
 549 * if the powerdomain pointer is null or returns the previous power state
 550 * upon success.
 551 */
 552int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
 553{
 554	int ret = -EINVAL;
 555
 556	if (!pwrdm)
 557		return -EINVAL;
 558
 559	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst)
 560		ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
 561
 562	return ret;
 563}
 564
 565/**
 566 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
 567 * @pwrdm: struct powerdomain * to set
 568 * @pwrst: one of the PWRDM_POWER_* macros
 569 *
 570 * Set the next power state @pwrst that the logic portion of the
 571 * powerdomain @pwrdm will enter when the powerdomain enters retention.
 572 * This will be either RETENTION or OFF, if supported.  Returns
 573 * -EINVAL if the powerdomain pointer is null or the target power
 574 * state is not not supported, or returns 0 upon success.
 575 */
 576int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 577{
 578	int ret = -EINVAL;
 579
 580	if (!pwrdm)
 581		return -EINVAL;
 582
 583	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
 584		return -EINVAL;
 585
 586	pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
 587		 pwrdm->name, pwrst);
 588
 589	if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
 590		ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
 591
 592	return ret;
 593}
 594
 595/**
 596 * pwrdm_set_mem_onst - set memory power state while powerdomain ON
 597 * @pwrdm: struct powerdomain * to set
 598 * @bank: memory bank number to set (0-3)
 599 * @pwrst: one of the PWRDM_POWER_* macros
 600 *
 601 * Set the next power state @pwrst that memory bank @bank of the
 602 * powerdomain @pwrdm will enter when the powerdomain enters the ON
 603 * state.  @bank will be a number from 0 to 3, and represents different
 604 * types of memory, depending on the powerdomain.  Returns -EINVAL if
 605 * the powerdomain pointer is null or the target power state is not
 606 * not supported for this memory bank, -EEXIST if the target memory
 607 * bank does not exist or is not controllable, or returns 0 upon
 608 * success.
 609 */
 610int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 611{
 612	int ret = -EINVAL;
 613
 614	if (!pwrdm)
 615		return -EINVAL;
 616
 617	if (pwrdm->banks < (bank + 1))
 618		return -EEXIST;
 619
 620	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
 621		return -EINVAL;
 622
 623	pr_debug("powerdomain: setting next memory powerstate for domain %s "
 624		 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
 625
 626	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
 627		ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
 628
 629	return ret;
 630}
 631
 632/**
 633 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
 634 * @pwrdm: struct powerdomain * to set
 635 * @bank: memory bank number to set (0-3)
 636 * @pwrst: one of the PWRDM_POWER_* macros
 637 *
 638 * Set the next power state @pwrst that memory bank @bank of the
 639 * powerdomain @pwrdm will enter when the powerdomain enters the
 640 * RETENTION state.  Bank will be a number from 0 to 3, and represents
 641 * different types of memory, depending on the powerdomain.  @pwrst
 642 * will be either RETENTION or OFF, if supported.  Returns -EINVAL if
 643 * the powerdomain pointer is null or the target power state is not
 644 * not supported for this memory bank, -EEXIST if the target memory
 645 * bank does not exist or is not controllable, or returns 0 upon
 646 * success.
 647 */
 648int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 649{
 650	int ret = -EINVAL;
 651
 652	if (!pwrdm)
 653		return -EINVAL;
 654
 655	if (pwrdm->banks < (bank + 1))
 656		return -EEXIST;
 657
 658	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
 659		return -EINVAL;
 660
 661	pr_debug("powerdomain: setting next memory powerstate for domain %s "
 662		 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
 663
 664	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
 665		ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
 666
 667	return ret;
 668}
 669
 670/**
 671 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
 672 * @pwrdm: struct powerdomain * to get current logic retention power state
 673 *
 674 * Return the power state that the logic portion of powerdomain @pwrdm
 675 * will enter when the powerdomain enters retention.  Returns -EINVAL
 676 * if the powerdomain pointer is null or returns the logic retention
 677 * power state upon success.
 678 */
 679int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
 680{
 681	int ret = -EINVAL;
 682
 683	if (!pwrdm)
 684		return -EINVAL;
 685
 686	if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
 687		ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
 688
 689	return ret;
 690}
 691
 692/**
 693 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
 694 * @pwrdm: struct powerdomain * to get previous logic power state
 695 *
 696 * Return the powerdomain @pwrdm's previous logic power state.  Returns
 697 * -EINVAL if the powerdomain pointer is null or returns the previous
 698 * logic power state upon success.
 699 */
 700int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
 701{
 702	int ret = -EINVAL;
 703
 704	if (!pwrdm)
 705		return -EINVAL;
 706
 707	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
 708		ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
 709
 710	return ret;
 711}
 712
 713/**
 714 * pwrdm_read_logic_retst - get next powerdomain logic power state
 715 * @pwrdm: struct powerdomain * to get next logic power state
 716 *
 717 * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
 718 * if the powerdomain pointer is null or returns the next logic
 719 * power state upon success.
 720 */
 721int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
 722{
 723	int ret = -EINVAL;
 724
 725	if (!pwrdm)
 726		return -EINVAL;
 727
 728	if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
 729		ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
 730
 731	return ret;
 732}
 733
 734/**
 735 * pwrdm_read_mem_pwrst - get current memory bank power state
 736 * @pwrdm: struct powerdomain * to get current memory bank power state
 737 * @bank: memory bank number (0-3)
 738 *
 739 * Return the powerdomain @pwrdm's current memory power state for bank
 740 * @bank.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
 741 * the target memory bank does not exist or is not controllable, or
 742 * returns the current memory power state upon success.
 743 */
 744int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 745{
 746	int ret = -EINVAL;
 747
 748	if (!pwrdm)
 749		return ret;
 750
 751	if (pwrdm->banks < (bank + 1))
 752		return ret;
 753
 754	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 755		bank = 1;
 756
 757	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst)
 758		ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank);
 759
 760	return ret;
 761}
 762
 763/**
 764 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
 765 * @pwrdm: struct powerdomain * to get previous memory bank power state
 766 * @bank: memory bank number (0-3)
 767 *
 768 * Return the powerdomain @pwrdm's previous memory power state for
 769 * bank @bank.  Returns -EINVAL if the powerdomain pointer is null,
 770 * -EEXIST if the target memory bank does not exist or is not
 771 * controllable, or returns the previous memory power state upon
 772 * success.
 773 */
 774int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 775{
 776	int ret = -EINVAL;
 777
 778	if (!pwrdm)
 779		return ret;
 780
 781	if (pwrdm->banks < (bank + 1))
 782		return ret;
 783
 784	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 785		bank = 1;
 786
 787	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst)
 788		ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank);
 789
 790	return ret;
 791}
 792
 793/**
 794 * pwrdm_read_mem_retst - get next memory bank power state
 795 * @pwrdm: struct powerdomain * to get mext memory bank power state
 796 * @bank: memory bank number (0-3)
 797 *
 798 * Return the powerdomain pwrdm's next memory power state for bank
 799 * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
 800 * the target memory bank does not exist or is not controllable, or
 801 * returns the next memory power state upon success.
 802 */
 803int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
 804{
 805	int ret = -EINVAL;
 806
 807	if (!pwrdm)
 808		return ret;
 809
 810	if (pwrdm->banks < (bank + 1))
 811		return ret;
 812
 813	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
 814		ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
 815
 816	return ret;
 817}
 818
 819/**
 820 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
 821 * @pwrdm: struct powerdomain * to clear
 822 *
 823 * Clear the powerdomain's previous power state register @pwrdm.
 824 * Clears the entire register, including logic and memory bank
 825 * previous power states.  Returns -EINVAL if the powerdomain pointer
 826 * is null, or returns 0 upon success.
 827 */
 828int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
 829{
 830	int ret = -EINVAL;
 831
 832	if (!pwrdm)
 833		return ret;
 834
 835	/*
 836	 * XXX should get the powerdomain's current state here;
 837	 * warn & fail if it is not ON.
 838	 */
 839
 840	pr_debug("powerdomain: clearing previous power state reg for %s\n",
 841		 pwrdm->name);
 842
 843	if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
 844		ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
 845
 846	return ret;
 847}
 848
 849/**
 850 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
 851 * @pwrdm: struct powerdomain *
 852 *
 853 * Enable automatic context save-and-restore upon power state change
 854 * for some devices in the powerdomain @pwrdm.  Warning: this only
 855 * affects a subset of devices in a powerdomain; check the TRM
 856 * closely.  Returns -EINVAL if the powerdomain pointer is null or if
 857 * the powerdomain does not support automatic save-and-restore, or
 858 * returns 0 upon success.
 859 */
 860int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
 861{
 862	int ret = -EINVAL;
 863
 864	if (!pwrdm)
 865		return ret;
 866
 867	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
 868		return ret;
 869
 870	pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
 871		 pwrdm->name);
 872
 873	if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
 874		ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
 875
 876	return ret;
 877}
 878
 879/**
 880 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
 881 * @pwrdm: struct powerdomain *
 882 *
 883 * Disable automatic context save-and-restore upon power state change
 884 * for some devices in the powerdomain @pwrdm.  Warning: this only
 885 * affects a subset of devices in a powerdomain; check the TRM
 886 * closely.  Returns -EINVAL if the powerdomain pointer is null or if
 887 * the powerdomain does not support automatic save-and-restore, or
 888 * returns 0 upon success.
 889 */
 890int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
 891{
 892	int ret = -EINVAL;
 893
 894	if (!pwrdm)
 895		return ret;
 896
 897	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
 898		return ret;
 899
 900	pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
 901		 pwrdm->name);
 902
 903	if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
 904		ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
 905
 906	return ret;
 907}
 908
 909/**
 910 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
 911 * @pwrdm: struct powerdomain *
 912 *
 913 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
 914 * for some devices, or 0 if it does not.
 915 */
 916bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
 917{
 918	return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
 919}
 920
 921/**
 922 * pwrdm_set_lowpwrstchange - Request a low power state change
 923 * @pwrdm: struct powerdomain *
 924 *
 925 * Allows a powerdomain to transtion to a lower power sleep state
 926 * from an existing sleep state without waking up the powerdomain.
 927 * Returns -EINVAL if the powerdomain pointer is null or if the
 928 * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
 929 * upon success.
 930 */
 931int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
 932{
 933	int ret = -EINVAL;
 934
 935	if (!pwrdm)
 936		return -EINVAL;
 937
 938	if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
 939		return -EINVAL;
 940
 941	pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
 942		 pwrdm->name);
 943
 944	if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange)
 945		ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
 946
 947	return ret;
 948}
 949
 950/**
 951 * pwrdm_wait_transition - wait for powerdomain power transition to finish
 952 * @pwrdm: struct powerdomain * to wait for
 953 *
 954 * If the powerdomain @pwrdm is in the process of a state transition,
 955 * spin until it completes the power transition, or until an iteration
 956 * bailout value is reached. Returns -EINVAL if the powerdomain
 957 * pointer is null, -EAGAIN if the bailout value was reached, or
 958 * returns 0 upon success.
 959 */
 960int pwrdm_wait_transition(struct powerdomain *pwrdm)
 961{
 962	int ret = -EINVAL;
 963
 964	if (!pwrdm)
 965		return -EINVAL;
 966
 967	if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
 968		ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
 
 969
 970	return ret;
 971}
 972
 973int pwrdm_state_switch(struct powerdomain *pwrdm)
 974{
 975	int ret;
 976
 977	ret = pwrdm_wait_transition(pwrdm);
 978	if (!ret)
 979		ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
 980
 981	return ret;
 982}
 983
 984int pwrdm_pre_transition(void)
 985{
 986	pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
 
 
 
 
 987	return 0;
 988}
 989
 990int pwrdm_post_transition(void)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 991{
 992	pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
 993	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 994}
 995
 996/**
 997 * pwrdm_get_context_loss_count - get powerdomain's context loss count
 998 * @pwrdm: struct powerdomain * to wait for
 999 *
1000 * Context loss count is the sum of powerdomain off-mode counter, the
1001 * logic off counter and the per-bank memory off counter.  Returns negative
1002 * (and WARNs) upon error, otherwise, returns the context loss count.
1003 */
1004int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
1005{
1006	int i, count;
1007
1008	if (!pwrdm) {
1009		WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
1010		return -ENODEV;
1011	}
1012
1013	count = pwrdm->state_counter[PWRDM_POWER_OFF];
1014	count += pwrdm->ret_logic_off_counter;
1015
1016	for (i = 0; i < pwrdm->banks; i++)
1017		count += pwrdm->ret_mem_off_counter[i];
1018
1019	/*
1020	 * Context loss count has to be a non-negative value. Clear the sign
1021	 * bit to get a value range from 0 to INT_MAX.
1022	 */
1023	count &= INT_MAX;
1024
1025	pr_debug("powerdomain: %s: context loss count = %d\n",
1026		 pwrdm->name, count);
1027
1028	return count;
1029}
1030
1031/**
1032 * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
1033 * @pwrdm: struct powerdomain *
1034 *
1035 * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
1036 * can lose either memory or logic context or if @pwrdm is invalid, or
1037 * returns 0 otherwise.  This function is not concerned with how the
1038 * powerdomain registers are programmed (i.e., to go off or not); it's
1039 * concerned with whether it's ever possible for this powerdomain to
1040 * go off while some other part of the chip is active.  This function
1041 * assumes that every powerdomain can go to either ON or INACTIVE.
1042 */
1043bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
1044{
1045	int i;
1046
1047	if (IS_ERR_OR_NULL(pwrdm)) {
1048		pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
1049			 __func__);
1050		return 1;
1051	}
1052
1053	if (pwrdm->pwrsts & PWRSTS_OFF)
1054		return 1;
1055
1056	if (pwrdm->pwrsts & PWRSTS_RET) {
1057		if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
1058			return 1;
1059
1060		for (i = 0; i < pwrdm->banks; i++)
1061			if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
1062				return 1;
1063	}
1064
1065	for (i = 0; i < pwrdm->banks; i++)
1066		if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
1067			return 1;
1068
1069	return 0;
1070}
v4.17
   1/*
   2 * OMAP powerdomain control
   3 *
   4 * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
   5 * Copyright (C) 2007-2011 Nokia Corporation
   6 *
   7 * Written by Paul Walmsley
   8 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
   9 * State counting code by Tero Kristo <tero.kristo@nokia.com>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15#undef DEBUG
  16
  17#include <linux/kernel.h>
  18#include <linux/types.h>
  19#include <linux/list.h>
  20#include <linux/errno.h>
  21#include <linux/string.h>
  22#include <linux/spinlock.h>
  23#include <trace/events/power.h>
  24
  25#include "cm2xxx_3xxx.h"
  26#include "prcm44xx.h"
  27#include "cm44xx.h"
  28#include "prm2xxx_3xxx.h"
  29#include "prm44xx.h"
  30
  31#include <asm/cpu.h>
  32
  33#include "powerdomain.h"
  34#include "clockdomain.h"
  35#include "voltage.h"
  36
  37#include "soc.h"
  38#include "pm.h"
  39
  40#define PWRDM_TRACE_STATES_FLAG	(1<<31)
  41
  42enum {
  43	PWRDM_STATE_NOW = 0,
  44	PWRDM_STATE_PREV,
  45};
  46
  47/*
  48 * Types of sleep_switch used internally in omap_set_pwrdm_state()
  49 * and its associated static functions
  50 *
  51 * XXX Better documentation is needed here
  52 */
  53#define ALREADYACTIVE_SWITCH		0
  54#define FORCEWAKEUP_SWITCH		1
  55#define LOWPOWERSTATE_SWITCH		2
  56
  57/* pwrdm_list contains all registered struct powerdomains */
  58static LIST_HEAD(pwrdm_list);
  59
  60static struct pwrdm_ops *arch_pwrdm;
  61
  62/* Private functions */
  63
  64static struct powerdomain *_pwrdm_lookup(const char *name)
  65{
  66	struct powerdomain *pwrdm, *temp_pwrdm;
  67
  68	pwrdm = NULL;
  69
  70	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
  71		if (!strcmp(name, temp_pwrdm->name)) {
  72			pwrdm = temp_pwrdm;
  73			break;
  74		}
  75	}
  76
  77	return pwrdm;
  78}
  79
  80/**
  81 * _pwrdm_register - register a powerdomain
  82 * @pwrdm: struct powerdomain * to register
  83 *
  84 * Adds a powerdomain to the internal powerdomain list.  Returns
  85 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
  86 * already registered by the provided name, or 0 upon success.
  87 */
  88static int _pwrdm_register(struct powerdomain *pwrdm)
  89{
  90	int i;
  91	struct voltagedomain *voltdm;
  92
  93	if (!pwrdm || !pwrdm->name)
  94		return -EINVAL;
  95
  96	if (cpu_is_omap44xx() &&
  97	    pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
  98		pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
  99		       pwrdm->name);
 100		return -EINVAL;
 101	}
 102
 103	if (_pwrdm_lookup(pwrdm->name))
 104		return -EEXIST;
 105
 106	if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm)
 107		if (!arch_pwrdm->pwrdm_has_voltdm())
 108			goto skip_voltdm;
 109
 110	voltdm = voltdm_lookup(pwrdm->voltdm.name);
 111	if (!voltdm) {
 112		pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
 113		       pwrdm->name, pwrdm->voltdm.name);
 114		return -EINVAL;
 115	}
 116	pwrdm->voltdm.ptr = voltdm;
 117	INIT_LIST_HEAD(&pwrdm->voltdm_node);
 118skip_voltdm:
 119	spin_lock_init(&pwrdm->_lock);
 120
 121	list_add(&pwrdm->node, &pwrdm_list);
 122
 123	/* Initialize the powerdomain's state counter */
 124	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
 125		pwrdm->state_counter[i] = 0;
 126
 127	pwrdm->ret_logic_off_counter = 0;
 128	for (i = 0; i < pwrdm->banks; i++)
 129		pwrdm->ret_mem_off_counter[i] = 0;
 130
 131	if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
 132		arch_pwrdm->pwrdm_wait_transition(pwrdm);
 133	pwrdm->state = pwrdm_read_pwrst(pwrdm);
 134	pwrdm->state_counter[pwrdm->state] = 1;
 135
 136	pr_debug("powerdomain: registered %s\n", pwrdm->name);
 137
 138	return 0;
 139}
 140
 141static void _update_logic_membank_counters(struct powerdomain *pwrdm)
 142{
 143	int i;
 144	u8 prev_logic_pwrst, prev_mem_pwrst;
 145
 146	prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
 147	if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
 148	    (prev_logic_pwrst == PWRDM_POWER_OFF))
 149		pwrdm->ret_logic_off_counter++;
 150
 151	for (i = 0; i < pwrdm->banks; i++) {
 152		prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
 153
 154		if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
 155		    (prev_mem_pwrst == PWRDM_POWER_OFF))
 156			pwrdm->ret_mem_off_counter[i]++;
 157	}
 158}
 159
 160static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
 161{
 162
 163	int prev, next, state, trace_state = 0;
 164
 165	if (pwrdm == NULL)
 166		return -EINVAL;
 167
 168	state = pwrdm_read_pwrst(pwrdm);
 169
 170	switch (flag) {
 171	case PWRDM_STATE_NOW:
 172		prev = pwrdm->state;
 173		break;
 174	case PWRDM_STATE_PREV:
 175		prev = pwrdm_read_prev_pwrst(pwrdm);
 176		if (pwrdm->state != prev)
 177			pwrdm->state_counter[prev]++;
 178		if (prev == PWRDM_POWER_RET)
 179			_update_logic_membank_counters(pwrdm);
 180		/*
 181		 * If the power domain did not hit the desired state,
 182		 * generate a trace event with both the desired and hit states
 183		 */
 184		next = pwrdm_read_next_pwrst(pwrdm);
 185		if (next != prev) {
 186			trace_state = (PWRDM_TRACE_STATES_FLAG |
 187				       ((next & OMAP_POWERSTATE_MASK) << 8) |
 188				       ((prev & OMAP_POWERSTATE_MASK) << 0));
 189			trace_power_domain_target_rcuidle(pwrdm->name,
 190							  trace_state,
 191							  raw_smp_processor_id());
 192		}
 193		break;
 194	default:
 195		return -EINVAL;
 196	}
 197
 198	if (state != prev)
 199		pwrdm->state_counter[state]++;
 200
 201	pm_dbg_update_time(pwrdm, prev);
 202
 203	pwrdm->state = state;
 204
 205	return 0;
 206}
 207
 208static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
 209{
 210	pwrdm_clear_all_prev_pwrst(pwrdm);
 211	_pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
 212	return 0;
 213}
 214
 215static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
 216{
 217	_pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
 218	return 0;
 219}
 220
 221/**
 222 * _pwrdm_save_clkdm_state_and_activate - prepare for power state change
 223 * @pwrdm: struct powerdomain * to operate on
 224 * @curr_pwrst: current power state of @pwrdm
 225 * @pwrst: power state to switch to
 226 *
 227 * Determine whether the powerdomain needs to be turned on before
 228 * attempting to switch power states.  Called by
 229 * omap_set_pwrdm_state().  NOTE that if the powerdomain contains
 230 * multiple clockdomains, this code assumes that the first clockdomain
 231 * supports software-supervised wakeup mode - potentially a problem.
 232 * Returns the power state switch mode currently in use (see the
 233 * "Types of sleep_switch" comment above).
 234 */
 235static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
 236					       u8 curr_pwrst, u8 pwrst)
 237{
 238	u8 sleep_switch;
 239
 240	if (curr_pwrst < PWRDM_POWER_ON) {
 241		if (curr_pwrst > pwrst &&
 242		    pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
 243		    arch_pwrdm->pwrdm_set_lowpwrstchange) {
 244			sleep_switch = LOWPOWERSTATE_SWITCH;
 245		} else {
 246			clkdm_deny_idle_nolock(pwrdm->pwrdm_clkdms[0]);
 247			sleep_switch = FORCEWAKEUP_SWITCH;
 248		}
 249	} else {
 250		sleep_switch = ALREADYACTIVE_SWITCH;
 251	}
 252
 253	return sleep_switch;
 254}
 255
 256/**
 257 * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
 258 * @pwrdm: struct powerdomain * to operate on
 259 * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
 260 *
 261 * Restore the clockdomain state perturbed by
 262 * _pwrdm_save_clkdm_state_and_activate(), and call the power state
 263 * bookkeeping code.  Called by omap_set_pwrdm_state().  NOTE that if
 264 * the powerdomain contains multiple clockdomains, this assumes that
 265 * the first associated clockdomain supports either
 266 * hardware-supervised idle control in the register, or
 267 * software-supervised sleep.  No return value.
 268 */
 269static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
 270				       u8 sleep_switch)
 271{
 272	switch (sleep_switch) {
 273	case FORCEWAKEUP_SWITCH:
 274		clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
 275		break;
 276	case LOWPOWERSTATE_SWITCH:
 277		if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
 278		    arch_pwrdm->pwrdm_set_lowpwrstchange)
 279			arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
 280		pwrdm_state_switch_nolock(pwrdm);
 281		break;
 282	}
 283}
 284
 285/* Public functions */
 286
 287/**
 288 * pwrdm_register_platform_funcs - register powerdomain implementation fns
 289 * @po: func pointers for arch specific implementations
 290 *
 291 * Register the list of function pointers used to implement the
 292 * powerdomain functions on different OMAP SoCs.  Should be called
 293 * before any other pwrdm_register*() function.  Returns -EINVAL if
 294 * @po is null, -EEXIST if platform functions have already been
 295 * registered, or 0 upon success.
 296 */
 297int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
 298{
 299	if (!po)
 300		return -EINVAL;
 301
 302	if (arch_pwrdm)
 303		return -EEXIST;
 304
 305	arch_pwrdm = po;
 306
 307	return 0;
 308}
 309
 310/**
 311 * pwrdm_register_pwrdms - register SoC powerdomains
 312 * @ps: pointer to an array of struct powerdomain to register
 313 *
 314 * Register the powerdomains available on a particular OMAP SoC.  Must
 315 * be called after pwrdm_register_platform_funcs().  May be called
 316 * multiple times.  Returns -EACCES if called before
 317 * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
 318 * null; or 0 upon success.
 319 */
 320int pwrdm_register_pwrdms(struct powerdomain **ps)
 321{
 322	struct powerdomain **p = NULL;
 323
 324	if (!arch_pwrdm)
 325		return -EEXIST;
 326
 327	if (!ps)
 328		return -EINVAL;
 329
 330	for (p = ps; *p; p++)
 331		_pwrdm_register(*p);
 332
 333	return 0;
 334}
 335
 336/**
 337 * pwrdm_complete_init - set up the powerdomain layer
 338 *
 339 * Do whatever is necessary to initialize registered powerdomains and
 340 * powerdomain code.  Currently, this programs the next power state
 341 * for each powerdomain to ON.  This prevents powerdomains from
 342 * unexpectedly losing context or entering high wakeup latency modes
 343 * with non-power-management-enabled kernels.  Must be called after
 344 * pwrdm_register_pwrdms().  Returns -EACCES if called before
 345 * pwrdm_register_pwrdms(), or 0 upon success.
 346 */
 347int pwrdm_complete_init(void)
 348{
 349	struct powerdomain *temp_p;
 350
 351	if (list_empty(&pwrdm_list))
 352		return -EACCES;
 353
 354	list_for_each_entry(temp_p, &pwrdm_list, node)
 355		pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
 356
 357	return 0;
 358}
 359
 360/**
 361 * pwrdm_lock - acquire a Linux spinlock on a powerdomain
 362 * @pwrdm: struct powerdomain * to lock
 363 *
 364 * Acquire the powerdomain spinlock on @pwrdm.  No return value.
 365 */
 366void pwrdm_lock(struct powerdomain *pwrdm)
 367	__acquires(&pwrdm->_lock)
 368{
 369	spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
 370}
 371
 372/**
 373 * pwrdm_unlock - release a Linux spinlock on a powerdomain
 374 * @pwrdm: struct powerdomain * to unlock
 375 *
 376 * Release the powerdomain spinlock on @pwrdm.  No return value.
 377 */
 378void pwrdm_unlock(struct powerdomain *pwrdm)
 379	__releases(&pwrdm->_lock)
 380{
 381	spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
 382}
 383
 384/**
 385 * pwrdm_lookup - look up a powerdomain by name, return a pointer
 386 * @name: name of powerdomain
 387 *
 388 * Find a registered powerdomain by its name @name.  Returns a pointer
 389 * to the struct powerdomain if found, or NULL otherwise.
 390 */
 391struct powerdomain *pwrdm_lookup(const char *name)
 392{
 393	struct powerdomain *pwrdm;
 394
 395	if (!name)
 396		return NULL;
 397
 398	pwrdm = _pwrdm_lookup(name);
 399
 400	return pwrdm;
 401}
 402
 403/**
 404 * pwrdm_for_each - call function on each registered clockdomain
 405 * @fn: callback function *
 406 *
 407 * Call the supplied function @fn for each registered powerdomain.
 408 * The callback function @fn can return anything but 0 to bail out
 409 * early from the iterator.  Returns the last return value of the
 410 * callback function, which should be 0 for success or anything else
 411 * to indicate failure; or -EINVAL if the function pointer is null.
 412 */
 413int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
 414		   void *user)
 415{
 416	struct powerdomain *temp_pwrdm;
 417	int ret = 0;
 418
 419	if (!fn)
 420		return -EINVAL;
 421
 422	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
 423		ret = (*fn)(temp_pwrdm, user);
 424		if (ret)
 425			break;
 426	}
 427
 428	return ret;
 429}
 430
 431/**
 432 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
 433 * @pwrdm: struct powerdomain * to add the clockdomain to
 434 * @clkdm: struct clockdomain * to associate with a powerdomain
 435 *
 436 * Associate the clockdomain @clkdm with a powerdomain @pwrdm.  This
 437 * enables the use of pwrdm_for_each_clkdm().  Returns -EINVAL if
 438 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
 439 * or 0 upon success.
 440 */
 441int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
 442{
 443	int i;
 444	int ret = -EINVAL;
 445
 446	if (!pwrdm || !clkdm)
 447		return -EINVAL;
 448
 449	pr_debug("powerdomain: %s: associating clockdomain %s\n",
 450		 pwrdm->name, clkdm->name);
 451
 452	for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
 453		if (!pwrdm->pwrdm_clkdms[i])
 454			break;
 455#ifdef DEBUG
 456		if (pwrdm->pwrdm_clkdms[i] == clkdm) {
 457			ret = -EINVAL;
 458			goto pac_exit;
 459		}
 460#endif
 461	}
 462
 463	if (i == PWRDM_MAX_CLKDMS) {
 464		pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n",
 465			 pwrdm->name, clkdm->name);
 466		WARN_ON(1);
 467		ret = -ENOMEM;
 468		goto pac_exit;
 469	}
 470
 471	pwrdm->pwrdm_clkdms[i] = clkdm;
 472
 473	ret = 0;
 474
 475pac_exit:
 476	return ret;
 477}
 478
 479/**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 480 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
 481 * @pwrdm: struct powerdomain *
 482 *
 483 * Return the number of controllable memory banks in powerdomain @pwrdm,
 484 * starting with 1.  Returns -EINVAL if the powerdomain pointer is null.
 485 */
 486int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
 487{
 488	if (!pwrdm)
 489		return -EINVAL;
 490
 491	return pwrdm->banks;
 492}
 493
 494/**
 495 * pwrdm_set_next_pwrst - set next powerdomain power state
 496 * @pwrdm: struct powerdomain * to set
 497 * @pwrst: one of the PWRDM_POWER_* macros
 498 *
 499 * Set the powerdomain @pwrdm's next power state to @pwrst.  The powerdomain
 500 * may not enter this state immediately if the preconditions for this state
 501 * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
 502 * null or if the power state is invalid for the powerdomin, or returns 0
 503 * upon success.
 504 */
 505int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 506{
 507	int ret = -EINVAL;
 508
 509	if (!pwrdm)
 510		return -EINVAL;
 511
 512	if (!(pwrdm->pwrsts & (1 << pwrst)))
 513		return -EINVAL;
 514
 515	pr_debug("powerdomain: %s: setting next powerstate to %0x\n",
 516		 pwrdm->name, pwrst);
 517
 518	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
 519		/* Trace the pwrdm desired target state */
 520		trace_power_domain_target_rcuidle(pwrdm->name, pwrst,
 521						  raw_smp_processor_id());
 522		/* Program the pwrdm desired target state */
 523		ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
 524	}
 525
 526	return ret;
 527}
 528
 529/**
 530 * pwrdm_read_next_pwrst - get next powerdomain power state
 531 * @pwrdm: struct powerdomain * to get power state
 532 *
 533 * Return the powerdomain @pwrdm's next power state.  Returns -EINVAL
 534 * if the powerdomain pointer is null or returns the next power state
 535 * upon success.
 536 */
 537int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
 538{
 539	int ret = -EINVAL;
 540
 541	if (!pwrdm)
 542		return -EINVAL;
 543
 544	if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
 545		ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
 546
 547	return ret;
 548}
 549
 550/**
 551 * pwrdm_read_pwrst - get current powerdomain power state
 552 * @pwrdm: struct powerdomain * to get power state
 553 *
 554 * Return the powerdomain @pwrdm's current power state.	Returns -EINVAL
 555 * if the powerdomain pointer is null or returns the current power state
 556 * upon success. Note that if the power domain only supports the ON state
 557 * then just return ON as the current state.
 558 */
 559int pwrdm_read_pwrst(struct powerdomain *pwrdm)
 560{
 561	int ret = -EINVAL;
 562
 563	if (!pwrdm)
 564		return -EINVAL;
 565
 566	if (pwrdm->pwrsts == PWRSTS_ON)
 567		return PWRDM_POWER_ON;
 568
 569	if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
 570		ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
 571
 572	return ret;
 573}
 574
 575/**
 576 * pwrdm_read_prev_pwrst - get previous powerdomain power state
 577 * @pwrdm: struct powerdomain * to get previous power state
 578 *
 579 * Return the powerdomain @pwrdm's previous power state.  Returns -EINVAL
 580 * if the powerdomain pointer is null or returns the previous power state
 581 * upon success.
 582 */
 583int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
 584{
 585	int ret = -EINVAL;
 586
 587	if (!pwrdm)
 588		return -EINVAL;
 589
 590	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst)
 591		ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
 592
 593	return ret;
 594}
 595
 596/**
 597 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
 598 * @pwrdm: struct powerdomain * to set
 599 * @pwrst: one of the PWRDM_POWER_* macros
 600 *
 601 * Set the next power state @pwrst that the logic portion of the
 602 * powerdomain @pwrdm will enter when the powerdomain enters retention.
 603 * This will be either RETENTION or OFF, if supported.  Returns
 604 * -EINVAL if the powerdomain pointer is null or the target power
 605 * state is not not supported, or returns 0 upon success.
 606 */
 607int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 608{
 609	int ret = -EINVAL;
 610
 611	if (!pwrdm)
 612		return -EINVAL;
 613
 614	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
 615		return -EINVAL;
 616
 617	pr_debug("powerdomain: %s: setting next logic powerstate to %0x\n",
 618		 pwrdm->name, pwrst);
 619
 620	if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
 621		ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
 622
 623	return ret;
 624}
 625
 626/**
 627 * pwrdm_set_mem_onst - set memory power state while powerdomain ON
 628 * @pwrdm: struct powerdomain * to set
 629 * @bank: memory bank number to set (0-3)
 630 * @pwrst: one of the PWRDM_POWER_* macros
 631 *
 632 * Set the next power state @pwrst that memory bank @bank of the
 633 * powerdomain @pwrdm will enter when the powerdomain enters the ON
 634 * state.  @bank will be a number from 0 to 3, and represents different
 635 * types of memory, depending on the powerdomain.  Returns -EINVAL if
 636 * the powerdomain pointer is null or the target power state is not
 637 * not supported for this memory bank, -EEXIST if the target memory
 638 * bank does not exist or is not controllable, or returns 0 upon
 639 * success.
 640 */
 641int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 642{
 643	int ret = -EINVAL;
 644
 645	if (!pwrdm)
 646		return -EINVAL;
 647
 648	if (pwrdm->banks < (bank + 1))
 649		return -EEXIST;
 650
 651	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
 652		return -EINVAL;
 653
 654	pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n",
 655		 pwrdm->name, bank, pwrst);
 656
 657	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
 658		ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
 659
 660	return ret;
 661}
 662
 663/**
 664 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
 665 * @pwrdm: struct powerdomain * to set
 666 * @bank: memory bank number to set (0-3)
 667 * @pwrst: one of the PWRDM_POWER_* macros
 668 *
 669 * Set the next power state @pwrst that memory bank @bank of the
 670 * powerdomain @pwrdm will enter when the powerdomain enters the
 671 * RETENTION state.  Bank will be a number from 0 to 3, and represents
 672 * different types of memory, depending on the powerdomain.  @pwrst
 673 * will be either RETENTION or OFF, if supported.  Returns -EINVAL if
 674 * the powerdomain pointer is null or the target power state is not
 675 * not supported for this memory bank, -EEXIST if the target memory
 676 * bank does not exist or is not controllable, or returns 0 upon
 677 * success.
 678 */
 679int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
 680{
 681	int ret = -EINVAL;
 682
 683	if (!pwrdm)
 684		return -EINVAL;
 685
 686	if (pwrdm->banks < (bank + 1))
 687		return -EEXIST;
 688
 689	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
 690		return -EINVAL;
 691
 692	pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n",
 693		 pwrdm->name, bank, pwrst);
 694
 695	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
 696		ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
 697
 698	return ret;
 699}
 700
 701/**
 702 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
 703 * @pwrdm: struct powerdomain * to get current logic retention power state
 704 *
 705 * Return the power state that the logic portion of powerdomain @pwrdm
 706 * will enter when the powerdomain enters retention.  Returns -EINVAL
 707 * if the powerdomain pointer is null or returns the logic retention
 708 * power state upon success.
 709 */
 710int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
 711{
 712	int ret = -EINVAL;
 713
 714	if (!pwrdm)
 715		return -EINVAL;
 716
 717	if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
 718		ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
 719
 720	return ret;
 721}
 722
 723/**
 724 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
 725 * @pwrdm: struct powerdomain * to get previous logic power state
 726 *
 727 * Return the powerdomain @pwrdm's previous logic power state.  Returns
 728 * -EINVAL if the powerdomain pointer is null or returns the previous
 729 * logic power state upon success.
 730 */
 731int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
 732{
 733	int ret = -EINVAL;
 734
 735	if (!pwrdm)
 736		return -EINVAL;
 737
 738	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
 739		ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
 740
 741	return ret;
 742}
 743
 744/**
 745 * pwrdm_read_logic_retst - get next powerdomain logic power state
 746 * @pwrdm: struct powerdomain * to get next logic power state
 747 *
 748 * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
 749 * if the powerdomain pointer is null or returns the next logic
 750 * power state upon success.
 751 */
 752int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
 753{
 754	int ret = -EINVAL;
 755
 756	if (!pwrdm)
 757		return -EINVAL;
 758
 759	if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
 760		ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
 761
 762	return ret;
 763}
 764
 765/**
 766 * pwrdm_read_mem_pwrst - get current memory bank power state
 767 * @pwrdm: struct powerdomain * to get current memory bank power state
 768 * @bank: memory bank number (0-3)
 769 *
 770 * Return the powerdomain @pwrdm's current memory power state for bank
 771 * @bank.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
 772 * the target memory bank does not exist or is not controllable, or
 773 * returns the current memory power state upon success.
 774 */
 775int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 776{
 777	int ret = -EINVAL;
 778
 779	if (!pwrdm)
 780		return ret;
 781
 782	if (pwrdm->banks < (bank + 1))
 783		return ret;
 784
 785	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 786		bank = 1;
 787
 788	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst)
 789		ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank);
 790
 791	return ret;
 792}
 793
 794/**
 795 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
 796 * @pwrdm: struct powerdomain * to get previous memory bank power state
 797 * @bank: memory bank number (0-3)
 798 *
 799 * Return the powerdomain @pwrdm's previous memory power state for
 800 * bank @bank.  Returns -EINVAL if the powerdomain pointer is null,
 801 * -EEXIST if the target memory bank does not exist or is not
 802 * controllable, or returns the previous memory power state upon
 803 * success.
 804 */
 805int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 806{
 807	int ret = -EINVAL;
 808
 809	if (!pwrdm)
 810		return ret;
 811
 812	if (pwrdm->banks < (bank + 1))
 813		return ret;
 814
 815	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
 816		bank = 1;
 817
 818	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst)
 819		ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank);
 820
 821	return ret;
 822}
 823
 824/**
 825 * pwrdm_read_mem_retst - get next memory bank power state
 826 * @pwrdm: struct powerdomain * to get mext memory bank power state
 827 * @bank: memory bank number (0-3)
 828 *
 829 * Return the powerdomain pwrdm's next memory power state for bank
 830 * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
 831 * the target memory bank does not exist or is not controllable, or
 832 * returns the next memory power state upon success.
 833 */
 834int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
 835{
 836	int ret = -EINVAL;
 837
 838	if (!pwrdm)
 839		return ret;
 840
 841	if (pwrdm->banks < (bank + 1))
 842		return ret;
 843
 844	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
 845		ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
 846
 847	return ret;
 848}
 849
 850/**
 851 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
 852 * @pwrdm: struct powerdomain * to clear
 853 *
 854 * Clear the powerdomain's previous power state register @pwrdm.
 855 * Clears the entire register, including logic and memory bank
 856 * previous power states.  Returns -EINVAL if the powerdomain pointer
 857 * is null, or returns 0 upon success.
 858 */
 859int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
 860{
 861	int ret = -EINVAL;
 862
 863	if (!pwrdm)
 864		return ret;
 865
 866	/*
 867	 * XXX should get the powerdomain's current state here;
 868	 * warn & fail if it is not ON.
 869	 */
 870
 871	pr_debug("powerdomain: %s: clearing previous power state reg\n",
 872		 pwrdm->name);
 873
 874	if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
 875		ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
 876
 877	return ret;
 878}
 879
 880/**
 881 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
 882 * @pwrdm: struct powerdomain *
 883 *
 884 * Enable automatic context save-and-restore upon power state change
 885 * for some devices in the powerdomain @pwrdm.  Warning: this only
 886 * affects a subset of devices in a powerdomain; check the TRM
 887 * closely.  Returns -EINVAL if the powerdomain pointer is null or if
 888 * the powerdomain does not support automatic save-and-restore, or
 889 * returns 0 upon success.
 890 */
 891int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
 892{
 893	int ret = -EINVAL;
 894
 895	if (!pwrdm)
 896		return ret;
 897
 898	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
 899		return ret;
 900
 901	pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name);
 
 902
 903	if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
 904		ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
 905
 906	return ret;
 907}
 908
 909/**
 910 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
 911 * @pwrdm: struct powerdomain *
 912 *
 913 * Disable automatic context save-and-restore upon power state change
 914 * for some devices in the powerdomain @pwrdm.  Warning: this only
 915 * affects a subset of devices in a powerdomain; check the TRM
 916 * closely.  Returns -EINVAL if the powerdomain pointer is null or if
 917 * the powerdomain does not support automatic save-and-restore, or
 918 * returns 0 upon success.
 919 */
 920int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
 921{
 922	int ret = -EINVAL;
 923
 924	if (!pwrdm)
 925		return ret;
 926
 927	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
 928		return ret;
 929
 930	pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name);
 
 931
 932	if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
 933		ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
 934
 935	return ret;
 936}
 937
 938/**
 939 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
 940 * @pwrdm: struct powerdomain *
 941 *
 942 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
 943 * for some devices, or 0 if it does not.
 944 */
 945bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
 946{
 947	return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
 948}
 949
 950int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
 
 
 
 
 
 
 
 
 
 
 951{
 952	int ret;
 
 
 
 953
 954	if (!pwrdm || !arch_pwrdm)
 955		return -EINVAL;
 956
 957	ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
 958	if (!ret)
 959		ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
 
 
 960
 961	return ret;
 962}
 963
 964int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
 
 
 
 
 
 
 
 
 
 
 965{
 966	int ret;
 
 
 
 967
 968	pwrdm_lock(pwrdm);
 969	ret = pwrdm_state_switch_nolock(pwrdm);
 970	pwrdm_unlock(pwrdm);
 971
 972	return ret;
 973}
 974
 975int pwrdm_pre_transition(struct powerdomain *pwrdm)
 976{
 977	if (pwrdm)
 978		_pwrdm_pre_transition_cb(pwrdm, NULL);
 979	else
 980		pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
 
 981
 982	return 0;
 983}
 984
 985int pwrdm_post_transition(struct powerdomain *pwrdm)
 986{
 987	if (pwrdm)
 988		_pwrdm_post_transition_cb(pwrdm, NULL);
 989	else
 990		pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
 991
 992	return 0;
 993}
 994
 995/**
 996 * pwrdm_get_valid_lp_state() - Find best match deep power state
 997 * @pwrdm:	power domain for which we want to find best match
 998 * @is_logic_state: Are we looking for logic state match here? Should
 999 *		    be one of PWRDM_xxx macro values
1000 * @req_state:	requested power state
1001 *
1002 * Returns: closest match for requested power state. default fallback
1003 * is RET for logic state and ON for power state.
1004 *
1005 * This does a search from the power domain data looking for the
1006 * closest valid power domain state that the hardware can achieve.
1007 * PRCM definitions for PWRSTCTRL allows us to program whatever
1008 * configuration we'd like, and PRCM will actually attempt such
1009 * a transition, however if the powerdomain does not actually support it,
1010 * we endup with a hung system. The valid power domain states are already
1011 * available in our powerdomain data files. So this function tries to do
1012 * the following:
1013 * a) find if we have an exact match to the request - no issues.
1014 * b) else find if a deeper power state is possible.
1015 * c) failing which, it tries to find closest higher power state for the
1016 * request.
1017 */
1018u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
1019			    bool is_logic_state, u8 req_state)
1020{
1021	u8 pwrdm_states = is_logic_state ? pwrdm->pwrsts_logic_ret :
1022			pwrdm->pwrsts;
1023	/* For logic, ret is highest and others, ON is highest */
1024	u8 default_pwrst = is_logic_state ? PWRDM_POWER_RET : PWRDM_POWER_ON;
1025	u8 new_pwrst;
1026	bool found;
1027
1028	/* If it is already supported, nothing to search */
1029	if (pwrdm_states & BIT(req_state))
1030		return req_state;
1031
1032	if (!req_state)
1033		goto up_search;
1034
1035	/*
1036	 * So, we dont have a exact match
1037	 * Can we get a deeper power state match?
1038	 */
1039	new_pwrst = req_state - 1;
1040	found = true;
1041	while (!(pwrdm_states & BIT(new_pwrst))) {
1042		/* No match even at OFF? Not available */
1043		if (new_pwrst == PWRDM_POWER_OFF) {
1044			found = false;
1045			break;
1046		}
1047		new_pwrst--;
1048	}
1049
1050	if (found)
1051		goto done;
1052
1053up_search:
1054	/* OK, no deeper ones, can we get a higher match? */
1055	new_pwrst = req_state + 1;
1056	while (!(pwrdm_states & BIT(new_pwrst))) {
1057		if (new_pwrst > PWRDM_POWER_ON) {
1058			WARN(1, "powerdomain: %s: Fix max powerstate to ON\n",
1059			     pwrdm->name);
1060			return PWRDM_POWER_ON;
1061		}
1062
1063		if (new_pwrst == default_pwrst)
1064			break;
1065		new_pwrst++;
1066	}
1067done:
1068	return new_pwrst;
1069}
1070
1071/**
1072 * omap_set_pwrdm_state - change a powerdomain's current power state
1073 * @pwrdm: struct powerdomain * to change the power state of
1074 * @pwrst: power state to change to
1075 *
1076 * Change the current hardware power state of the powerdomain
1077 * represented by @pwrdm to the power state represented by @pwrst.
1078 * Returns -EINVAL if @pwrdm is null or invalid or if the
1079 * powerdomain's current power state could not be read, or returns 0
1080 * upon success or if @pwrdm does not support @pwrst or any
1081 * lower-power state.  XXX Should not return 0 if the @pwrdm does not
1082 * support @pwrst or any lower-power state: this should be an error.
1083 */
1084int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
1085{
1086	u8 next_pwrst, sleep_switch;
1087	int curr_pwrst;
1088	int ret = 0;
1089
1090	if (!pwrdm || IS_ERR(pwrdm))
1091		return -EINVAL;
1092
1093	while (!(pwrdm->pwrsts & (1 << pwrst))) {
1094		if (pwrst == PWRDM_POWER_OFF)
1095			return ret;
1096		pwrst--;
1097	}
1098
1099	pwrdm_lock(pwrdm);
1100
1101	curr_pwrst = pwrdm_read_pwrst(pwrdm);
1102	if (curr_pwrst < 0) {
1103		ret = -EINVAL;
1104		goto osps_out;
1105	}
1106
1107	next_pwrst = pwrdm_read_next_pwrst(pwrdm);
1108	if (curr_pwrst == pwrst && next_pwrst == pwrst)
1109		goto osps_out;
1110
1111	sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
1112							    pwrst);
1113
1114	ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
1115	if (ret)
1116		pr_err("%s: unable to set power state of powerdomain: %s\n",
1117		       __func__, pwrdm->name);
1118
1119	_pwrdm_restore_clkdm_state(pwrdm, sleep_switch);
1120
1121osps_out:
1122	pwrdm_unlock(pwrdm);
1123
1124	return ret;
1125}
1126
1127/**
1128 * pwrdm_get_context_loss_count - get powerdomain's context loss count
1129 * @pwrdm: struct powerdomain * to wait for
1130 *
1131 * Context loss count is the sum of powerdomain off-mode counter, the
1132 * logic off counter and the per-bank memory off counter.  Returns negative
1133 * (and WARNs) upon error, otherwise, returns the context loss count.
1134 */
1135int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
1136{
1137	int i, count;
1138
1139	if (!pwrdm) {
1140		WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
1141		return -ENODEV;
1142	}
1143
1144	count = pwrdm->state_counter[PWRDM_POWER_OFF];
1145	count += pwrdm->ret_logic_off_counter;
1146
1147	for (i = 0; i < pwrdm->banks; i++)
1148		count += pwrdm->ret_mem_off_counter[i];
1149
1150	/*
1151	 * Context loss count has to be a non-negative value. Clear the sign
1152	 * bit to get a value range from 0 to INT_MAX.
1153	 */
1154	count &= INT_MAX;
1155
1156	pr_debug("powerdomain: %s: context loss count = %d\n",
1157		 pwrdm->name, count);
1158
1159	return count;
1160}
1161
1162/**
1163 * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
1164 * @pwrdm: struct powerdomain *
1165 *
1166 * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
1167 * can lose either memory or logic context or if @pwrdm is invalid, or
1168 * returns 0 otherwise.  This function is not concerned with how the
1169 * powerdomain registers are programmed (i.e., to go off or not); it's
1170 * concerned with whether it's ever possible for this powerdomain to
1171 * go off while some other part of the chip is active.  This function
1172 * assumes that every powerdomain can go to either ON or INACTIVE.
1173 */
1174bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
1175{
1176	int i;
1177
1178	if (!pwrdm) {
1179		pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
1180			 __func__);
1181		return 1;
1182	}
1183
1184	if (pwrdm->pwrsts & PWRSTS_OFF)
1185		return 1;
1186
1187	if (pwrdm->pwrsts & PWRSTS_RET) {
1188		if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
1189			return 1;
1190
1191		for (i = 0; i < pwrdm->banks; i++)
1192			if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
1193				return 1;
1194	}
1195
1196	for (i = 0; i < pwrdm->banks; i++)
1197		if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
1198			return 1;
1199
1200	return 0;
1201}