Linux Audio

Check our new training course

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