PageRenderTime 101ms CodeModel.GetById 10ms app.highlight 78ms RepoModel.GetById 1ms app.codeStats 1ms

/arch/arm/mach-omap2/omap_hwmod.c

https://github.com/AICP/kernel_asus_grouper
C | 2667 lines | 1327 code | 420 blank | 920 comment | 323 complexity | ab8c59af5c0f55d1fc49fa74e236d2f5 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * omap_hwmod implementation for OMAP2/3/4
   3 *
   4 * Copyright (C) 2009-2011 Nokia Corporation
   5 * Copyright (C) 2011 Texas Instruments, Inc.
   6 *
   7 * Paul Walmsley, Benoît Cousson, Kevin Hilman
   8 *
   9 * Created in collaboration with (alphabetical order): Thara Gopinath,
  10 * Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari Poussa, Anand
  11 * Sawant, Santosh Shilimkar, Richard Woodruff
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License version 2 as
  15 * published by the Free Software Foundation.
  16 *
  17 * Introduction
  18 * ------------
  19 * One way to view an OMAP SoC is as a collection of largely unrelated
  20 * IP blocks connected by interconnects.  The IP blocks include
  21 * devices such as ARM processors, audio serial interfaces, UARTs,
  22 * etc.  Some of these devices, like the DSP, are created by TI;
  23 * others, like the SGX, largely originate from external vendors.  In
  24 * TI's documentation, on-chip devices are referred to as "OMAP
  25 * modules."  Some of these IP blocks are identical across several
  26 * OMAP versions.  Others are revised frequently.
  27 *
  28 * These OMAP modules are tied together by various interconnects.
  29 * Most of the address and data flow between modules is via OCP-based
  30 * interconnects such as the L3 and L4 buses; but there are other
  31 * interconnects that distribute the hardware clock tree, handle idle
  32 * and reset signaling, supply power, and connect the modules to
  33 * various pads or balls on the OMAP package.
  34 *
  35 * OMAP hwmod provides a consistent way to describe the on-chip
  36 * hardware blocks and their integration into the rest of the chip.
  37 * This description can be automatically generated from the TI
  38 * hardware database.  OMAP hwmod provides a standard, consistent API
  39 * to reset, enable, idle, and disable these hardware blocks.  And
  40 * hwmod provides a way for other core code, such as the Linux device
  41 * code or the OMAP power management and address space mapping code,
  42 * to query the hardware database.
  43 *
  44 * Using hwmod
  45 * -----------
  46 * Drivers won't call hwmod functions directly.  That is done by the
  47 * omap_device code, and in rare occasions, by custom integration code
  48 * in arch/arm/ *omap*.  The omap_device code includes functions to
  49 * build a struct platform_device using omap_hwmod data, and that is
  50 * currently how hwmod data is communicated to drivers and to the
  51 * Linux driver model.  Most drivers will call omap_hwmod functions only
  52 * indirectly, via pm_runtime*() functions.
  53 *
  54 * From a layering perspective, here is where the OMAP hwmod code
  55 * fits into the kernel software stack:
  56 *
  57 *            +-------------------------------+
  58 *            |      Device driver code       |
  59 *            |      (e.g., drivers/)         |
  60 *            +-------------------------------+
  61 *            |      Linux driver model       |
  62 *            |     (platform_device /        |
  63 *            |  platform_driver data/code)   |
  64 *            +-------------------------------+
  65 *            | OMAP core-driver integration  |
  66 *            |(arch/arm/mach-omap2/devices.c)|
  67 *            +-------------------------------+
  68 *            |      omap_device code         |
  69 *            | (../plat-omap/omap_device.c)  |
  70 *            +-------------------------------+
  71 *   ---->    |    omap_hwmod code/data       |    <-----
  72 *            | (../mach-omap2/omap_hwmod*)   |
  73 *            +-------------------------------+
  74 *            | OMAP clock/PRCM/register fns  |
  75 *            | (__raw_{read,write}l, clk*)   |
  76 *            +-------------------------------+
  77 *
  78 * Device drivers should not contain any OMAP-specific code or data in
  79 * them.  They should only contain code to operate the IP block that
  80 * the driver is responsible for.  This is because these IP blocks can
  81 * also appear in other SoCs, either from TI (such as DaVinci) or from
  82 * other manufacturers; and drivers should be reusable across other
  83 * platforms.
  84 *
  85 * The OMAP hwmod code also will attempt to reset and idle all on-chip
  86 * devices upon boot.  The goal here is for the kernel to be
  87 * completely self-reliant and independent from bootloaders.  This is
  88 * to ensure a repeatable configuration, both to ensure consistent
  89 * runtime behavior, and to make it easier for others to reproduce
  90 * bugs.
  91 *
  92 * OMAP module activity states
  93 * ---------------------------
  94 * The hwmod code considers modules to be in one of several activity
  95 * states.  IP blocks start out in an UNKNOWN state, then once they
  96 * are registered via the hwmod code, proceed to the REGISTERED state.
  97 * Once their clock names are resolved to clock pointers, the module
  98 * enters the CLKS_INITED state; and finally, once the module has been
  99 * reset and the integration registers programmed, the INITIALIZED state
 100 * is entered.  The hwmod code will then place the module into either
 101 * the IDLE state to save power, or in the case of a critical system
 102 * module, the ENABLED state.
 103 *
 104 * OMAP core integration code can then call omap_hwmod*() functions
 105 * directly to move the module between the IDLE, ENABLED, and DISABLED
 106 * states, as needed.  This is done during both the PM idle loop, and
 107 * in the OMAP core integration code's implementation of the PM runtime
 108 * functions.
 109 *
 110 * References
 111 * ----------
 112 * This is a partial list.
 113 * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
 114 * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
 115 * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
 116 * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
 117 * - Open Core Protocol Specification 2.2
 118 *
 119 * To do:
 120 * - handle IO mapping
 121 * - bus throughput & module latency measurement code
 122 *
 123 * XXX add tests at the beginning of each function to ensure the hwmod is
 124 * in the appropriate state
 125 * XXX error return values should be checked to ensure that they are
 126 * appropriate
 127 */
 128#undef DEBUG
 129
 130#include <linux/kernel.h>
 131#include <linux/errno.h>
 132#include <linux/io.h>
 133#include <linux/clk.h>
 134#include <linux/delay.h>
 135#include <linux/err.h>
 136#include <linux/list.h>
 137#include <linux/mutex.h>
 138#include <linux/spinlock.h>
 139
 140#include <plat/common.h>
 141#include <plat/cpu.h>
 142#include "clockdomain.h"
 143#include "powerdomain.h"
 144#include <plat/clock.h>
 145#include <plat/omap_hwmod.h>
 146#include <plat/prcm.h>
 147
 148#include "cm2xxx_3xxx.h"
 149#include "cminst44xx.h"
 150#include "prm2xxx_3xxx.h"
 151#include "prm44xx.h"
 152#include "prminst44xx.h"
 153#include "mux.h"
 154
 155/* Maximum microseconds to wait for OMAP module to softreset */
 156#define MAX_MODULE_SOFTRESET_WAIT	10000
 157
 158/* Name of the OMAP hwmod for the MPU */
 159#define MPU_INITIATOR_NAME		"mpu"
 160
 161/* omap_hwmod_list contains all registered struct omap_hwmods */
 162static LIST_HEAD(omap_hwmod_list);
 163
 164/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
 165static struct omap_hwmod *mpu_oh;
 166
 167
 168/* Private functions */
 169
 170/**
 171 * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy
 172 * @oh: struct omap_hwmod *
 173 *
 174 * Load the current value of the hwmod OCP_SYSCONFIG register into the
 175 * struct omap_hwmod for later use.  Returns -EINVAL if the hwmod has no
 176 * OCP_SYSCONFIG register or 0 upon success.
 177 */
 178static int _update_sysc_cache(struct omap_hwmod *oh)
 179{
 180	if (!oh->class->sysc) {
 181		WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
 182		return -EINVAL;
 183	}
 184
 185	/* XXX ensure module interface clock is up */
 186
 187	oh->_sysc_cache = omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
 188
 189	if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
 190		oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
 191
 192	return 0;
 193}
 194
 195/**
 196 * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register
 197 * @v: OCP_SYSCONFIG value to write
 198 * @oh: struct omap_hwmod *
 199 *
 200 * Write @v into the module class' OCP_SYSCONFIG register, if it has
 201 * one.  No return value.
 202 */
 203static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
 204{
 205	if (!oh->class->sysc) {
 206		WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
 207		return;
 208	}
 209
 210	/* XXX ensure module interface clock is up */
 211
 212	/* Module might have lost context, always update cache and register */
 213	oh->_sysc_cache = v;
 214	omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
 215}
 216
 217/**
 218 * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v
 219 * @oh: struct omap_hwmod *
 220 * @standbymode: MIDLEMODE field bits
 221 * @v: pointer to register contents to modify
 222 *
 223 * Update the master standby mode bits in @v to be @standbymode for
 224 * the @oh hwmod.  Does not write to the hardware.  Returns -EINVAL
 225 * upon error or 0 upon success.
 226 */
 227static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
 228				   u32 *v)
 229{
 230	u32 mstandby_mask;
 231	u8 mstandby_shift;
 232
 233	if (!oh->class->sysc ||
 234	    !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE))
 235		return -EINVAL;
 236
 237	if (!oh->class->sysc->sysc_fields) {
 238		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 239		return -EINVAL;
 240	}
 241
 242	mstandby_shift = oh->class->sysc->sysc_fields->midle_shift;
 243	mstandby_mask = (0x3 << mstandby_shift);
 244
 245	*v &= ~mstandby_mask;
 246	*v |= __ffs(standbymode) << mstandby_shift;
 247
 248	return 0;
 249}
 250
 251/**
 252 * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v
 253 * @oh: struct omap_hwmod *
 254 * @idlemode: SIDLEMODE field bits
 255 * @v: pointer to register contents to modify
 256 *
 257 * Update the slave idle mode bits in @v to be @idlemode for the @oh
 258 * hwmod.  Does not write to the hardware.  Returns -EINVAL upon error
 259 * or 0 upon success.
 260 */
 261static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
 262{
 263	u32 sidle_mask;
 264	u8 sidle_shift;
 265
 266	if (!oh->class->sysc ||
 267	    !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE))
 268		return -EINVAL;
 269
 270	if (!oh->class->sysc->sysc_fields) {
 271		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 272		return -EINVAL;
 273	}
 274
 275	sidle_shift = oh->class->sysc->sysc_fields->sidle_shift;
 276	sidle_mask = (0x3 << sidle_shift);
 277
 278	*v &= ~sidle_mask;
 279	*v |= __ffs(idlemode) << sidle_shift;
 280
 281	return 0;
 282}
 283
 284/**
 285 * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
 286 * @oh: struct omap_hwmod *
 287 * @clockact: CLOCKACTIVITY field bits
 288 * @v: pointer to register contents to modify
 289 *
 290 * Update the clockactivity mode bits in @v to be @clockact for the
 291 * @oh hwmod.  Used for additional powersaving on some modules.  Does
 292 * not write to the hardware.  Returns -EINVAL upon error or 0 upon
 293 * success.
 294 */
 295static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
 296{
 297	u32 clkact_mask;
 298	u8  clkact_shift;
 299
 300	if (!oh->class->sysc ||
 301	    !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
 302		return -EINVAL;
 303
 304	if (!oh->class->sysc->sysc_fields) {
 305		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 306		return -EINVAL;
 307	}
 308
 309	clkact_shift = oh->class->sysc->sysc_fields->clkact_shift;
 310	clkact_mask = (0x3 << clkact_shift);
 311
 312	*v &= ~clkact_mask;
 313	*v |= clockact << clkact_shift;
 314
 315	return 0;
 316}
 317
 318/**
 319 * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
 320 * @oh: struct omap_hwmod *
 321 * @v: pointer to register contents to modify
 322 *
 323 * Set the SOFTRESET bit in @v for hwmod @oh.  Returns -EINVAL upon
 324 * error or 0 upon success.
 325 */
 326static int _set_softreset(struct omap_hwmod *oh, u32 *v)
 327{
 328	u32 softrst_mask;
 329
 330	if (!oh->class->sysc ||
 331	    !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
 332		return -EINVAL;
 333
 334	if (!oh->class->sysc->sysc_fields) {
 335		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 336		return -EINVAL;
 337	}
 338
 339	softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
 340
 341	*v |= softrst_mask;
 342
 343	return 0;
 344}
 345
 346/**
 347 * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
 348 * @oh: struct omap_hwmod *
 349 * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
 350 * @v: pointer to register contents to modify
 351 *
 352 * Update the module autoidle bit in @v to be @autoidle for the @oh
 353 * hwmod.  The autoidle bit controls whether the module can gate
 354 * internal clocks automatically when it isn't doing anything; the
 355 * exact function of this bit varies on a per-module basis.  This
 356 * function does not write to the hardware.  Returns -EINVAL upon
 357 * error or 0 upon success.
 358 */
 359static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
 360				u32 *v)
 361{
 362	u32 autoidle_mask;
 363	u8 autoidle_shift;
 364
 365	if (!oh->class->sysc ||
 366	    !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE))
 367		return -EINVAL;
 368
 369	if (!oh->class->sysc->sysc_fields) {
 370		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 371		return -EINVAL;
 372	}
 373
 374	autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
 375	autoidle_mask = (0x1 << autoidle_shift);
 376
 377	*v &= ~autoidle_mask;
 378	*v |= autoidle << autoidle_shift;
 379
 380	return 0;
 381}
 382
 383/**
 384 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
 385 * @oh: struct omap_hwmod *
 386 *
 387 * Allow the hardware module @oh to send wakeups.  Returns -EINVAL
 388 * upon error or 0 upon success.
 389 */
 390static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
 391{
 392	if (!oh->class->sysc ||
 393	    !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
 394	      (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
 395	      (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
 396		return -EINVAL;
 397
 398	if (!oh->class->sysc->sysc_fields) {
 399		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 400		return -EINVAL;
 401	}
 402
 403	if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
 404		*v |= 0x1 << oh->class->sysc->sysc_fields->enwkup_shift;
 405
 406	if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
 407		_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
 408	if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
 409		_set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
 410
 411	/* XXX test pwrdm_get_wken for this hwmod's subsystem */
 412
 413	oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
 414
 415	return 0;
 416}
 417
 418/**
 419 * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
 420 * @oh: struct omap_hwmod *
 421 *
 422 * Prevent the hardware module @oh to send wakeups.  Returns -EINVAL
 423 * upon error or 0 upon success.
 424 */
 425static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
 426{
 427	if (!oh->class->sysc ||
 428	    !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
 429	      (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
 430	      (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
 431		return -EINVAL;
 432
 433	if (!oh->class->sysc->sysc_fields) {
 434		WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
 435		return -EINVAL;
 436	}
 437
 438	if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
 439		*v &= ~(0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
 440
 441	if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
 442		_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
 443	if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
 444		_set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
 445
 446	/* XXX test pwrdm_get_wken for this hwmod's subsystem */
 447
 448	oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
 449
 450	return 0;
 451}
 452
 453/**
 454 * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active
 455 * @oh: struct omap_hwmod *
 456 *
 457 * Prevent the hardware module @oh from entering idle while the
 458 * hardare module initiator @init_oh is active.  Useful when a module
 459 * will be accessed by a particular initiator (e.g., if a module will
 460 * be accessed by the IVA, there should be a sleepdep between the IVA
 461 * initiator and the module).  Only applies to modules in smart-idle
 462 * mode.  If the clockdomain is marked as not needing autodeps, return
 463 * 0 without doing anything.  Otherwise, returns -EINVAL upon error or
 464 * passes along clkdm_add_sleepdep() value upon success.
 465 */
 466static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 467{
 468	if (!oh->_clk)
 469		return -EINVAL;
 470
 471	if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
 472		return 0;
 473
 474	return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
 475}
 476
 477/**
 478 * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active
 479 * @oh: struct omap_hwmod *
 480 *
 481 * Allow the hardware module @oh to enter idle while the hardare
 482 * module initiator @init_oh is active.  Useful when a module will not
 483 * be accessed by a particular initiator (e.g., if a module will not
 484 * be accessed by the IVA, there should be no sleepdep between the IVA
 485 * initiator and the module).  Only applies to modules in smart-idle
 486 * mode.  If the clockdomain is marked as not needing autodeps, return
 487 * 0 without doing anything.  Returns -EINVAL upon error or passes
 488 * along clkdm_del_sleepdep() value upon success.
 489 */
 490static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 491{
 492	if (!oh->_clk)
 493		return -EINVAL;
 494
 495	if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
 496		return 0;
 497
 498	return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
 499}
 500
 501/**
 502 * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
 503 * @oh: struct omap_hwmod *
 504 *
 505 * Called from _init_clocks().  Populates the @oh _clk (main
 506 * functional clock pointer) if a main_clk is present.  Returns 0 on
 507 * success or -EINVAL on error.
 508 */
 509static int _init_main_clk(struct omap_hwmod *oh)
 510{
 511	int ret = 0;
 512
 513	if (!oh->main_clk)
 514		return 0;
 515
 516	oh->_clk = omap_clk_get_by_name(oh->main_clk);
 517	if (!oh->_clk) {
 518		pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n",
 519			   oh->name, oh->main_clk);
 520		return -EINVAL;
 521	}
 522
 523	if (!oh->_clk->clkdm)
 524		pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
 525			   oh->main_clk, oh->_clk->name);
 526
 527	return ret;
 528}
 529
 530/**
 531 * _init_interface_clks - get a struct clk * for the the hwmod's interface clks
 532 * @oh: struct omap_hwmod *
 533 *
 534 * Called from _init_clocks().  Populates the @oh OCP slave interface
 535 * clock pointers.  Returns 0 on success or -EINVAL on error.
 536 */
 537static int _init_interface_clks(struct omap_hwmod *oh)
 538{
 539	struct clk *c;
 540	int i;
 541	int ret = 0;
 542
 543	if (oh->slaves_cnt == 0)
 544		return 0;
 545
 546	for (i = 0; i < oh->slaves_cnt; i++) {
 547		struct omap_hwmod_ocp_if *os = oh->slaves[i];
 548
 549		if (!os->clk)
 550			continue;
 551
 552		c = omap_clk_get_by_name(os->clk);
 553		if (!c) {
 554			pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
 555				   oh->name, os->clk);
 556			ret = -EINVAL;
 557		}
 558		os->_clk = c;
 559	}
 560
 561	return ret;
 562}
 563
 564/**
 565 * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks
 566 * @oh: struct omap_hwmod *
 567 *
 568 * Called from _init_clocks().  Populates the @oh omap_hwmod_opt_clk
 569 * clock pointers.  Returns 0 on success or -EINVAL on error.
 570 */
 571static int _init_opt_clks(struct omap_hwmod *oh)
 572{
 573	struct omap_hwmod_opt_clk *oc;
 574	struct clk *c;
 575	int i;
 576	int ret = 0;
 577
 578	for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
 579		c = omap_clk_get_by_name(oc->clk);
 580		if (!c) {
 581			pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
 582				   oh->name, oc->clk);
 583			ret = -EINVAL;
 584		}
 585		oc->_clk = c;
 586	}
 587
 588	return ret;
 589}
 590
 591/**
 592 * _enable_clocks - enable hwmod main clock and interface clocks
 593 * @oh: struct omap_hwmod *
 594 *
 595 * Enables all clocks necessary for register reads and writes to succeed
 596 * on the hwmod @oh.  Returns 0.
 597 */
 598static int _enable_clocks(struct omap_hwmod *oh)
 599{
 600	int i;
 601
 602	pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
 603
 604	if (oh->_clk)
 605		clk_enable(oh->_clk);
 606
 607	if (oh->slaves_cnt > 0) {
 608		for (i = 0; i < oh->slaves_cnt; i++) {
 609			struct omap_hwmod_ocp_if *os = oh->slaves[i];
 610			struct clk *c = os->_clk;
 611
 612			if (c && (os->flags & OCPIF_SWSUP_IDLE))
 613				clk_enable(c);
 614		}
 615	}
 616
 617	/* The opt clocks are controlled by the device driver. */
 618
 619	return 0;
 620}
 621
 622/**
 623 * _disable_clocks - disable hwmod main clock and interface clocks
 624 * @oh: struct omap_hwmod *
 625 *
 626 * Disables the hwmod @oh main functional and interface clocks.  Returns 0.
 627 */
 628static int _disable_clocks(struct omap_hwmod *oh)
 629{
 630	int i;
 631
 632	pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
 633
 634	if (oh->_clk)
 635		clk_disable(oh->_clk);
 636
 637	if (oh->slaves_cnt > 0) {
 638		for (i = 0; i < oh->slaves_cnt; i++) {
 639			struct omap_hwmod_ocp_if *os = oh->slaves[i];
 640			struct clk *c = os->_clk;
 641
 642			if (c && (os->flags & OCPIF_SWSUP_IDLE))
 643				clk_disable(c);
 644		}
 645	}
 646
 647	/* The opt clocks are controlled by the device driver. */
 648
 649	return 0;
 650}
 651
 652static void _enable_optional_clocks(struct omap_hwmod *oh)
 653{
 654	struct omap_hwmod_opt_clk *oc;
 655	int i;
 656
 657	pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
 658
 659	for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
 660		if (oc->_clk) {
 661			pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
 662				 oc->_clk->name);
 663			clk_enable(oc->_clk);
 664		}
 665}
 666
 667static void _disable_optional_clocks(struct omap_hwmod *oh)
 668{
 669	struct omap_hwmod_opt_clk *oc;
 670	int i;
 671
 672	pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
 673
 674	for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
 675		if (oc->_clk) {
 676			pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
 677				 oc->_clk->name);
 678			clk_disable(oc->_clk);
 679		}
 680}
 681
 682/**
 683 * _enable_module - enable CLKCTRL modulemode on OMAP4
 684 * @oh: struct omap_hwmod *
 685 *
 686 * Enables the PRCM module mode related to the hwmod @oh.
 687 * No return value.
 688 */
 689static void _enable_module(struct omap_hwmod *oh)
 690{
 691	/* The module mode does not exist prior OMAP4 */
 692	if (cpu_is_omap24xx() || cpu_is_omap34xx())
 693		return;
 694
 695	if (!oh->clkdm || !oh->prcm.omap4.modulemode)
 696		return;
 697
 698	pr_debug("omap_hwmod: %s: _enable_module: %d\n",
 699		 oh->name, oh->prcm.omap4.modulemode);
 700
 701	omap4_cminst_module_enable(oh->prcm.omap4.modulemode,
 702				   oh->clkdm->prcm_partition,
 703				   oh->clkdm->cm_inst,
 704				   oh->clkdm->clkdm_offs,
 705				   oh->prcm.omap4.clkctrl_offs);
 706}
 707
 708/**
 709 * _disable_module - enable CLKCTRL modulemode on OMAP4
 710 * @oh: struct omap_hwmod *
 711 *
 712 * Disable the PRCM module mode related to the hwmod @oh.
 713 * No return value.
 714 */
 715static void _disable_module(struct omap_hwmod *oh)
 716{
 717	/* The module mode does not exist prior OMAP4 */
 718	if (cpu_is_omap24xx() || cpu_is_omap34xx())
 719		return;
 720
 721	if (!oh->clkdm || !oh->prcm.omap4.modulemode)
 722		return;
 723
 724	pr_debug("omap_hwmod: %s: _disable_module\n", oh->name);
 725
 726	omap4_cminst_module_disable(oh->clkdm->prcm_partition,
 727				    oh->clkdm->cm_inst,
 728				    oh->clkdm->clkdm_offs,
 729				    oh->prcm.omap4.clkctrl_offs);
 730}
 731
 732/**
 733 * _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh
 734 * @oh: struct omap_hwmod *oh
 735 *
 736 * Count and return the number of MPU IRQs associated with the hwmod
 737 * @oh.  Used to allocate struct resource data.  Returns 0 if @oh is
 738 * NULL.
 739 */
 740static int _count_mpu_irqs(struct omap_hwmod *oh)
 741{
 742	struct omap_hwmod_irq_info *ohii;
 743	int i = 0;
 744
 745	if (!oh || !oh->mpu_irqs)
 746		return 0;
 747
 748	do {
 749		ohii = &oh->mpu_irqs[i++];
 750	} while (ohii->irq != -1);
 751
 752	return i-1;
 753}
 754
 755/**
 756 * _count_sdma_reqs - count the number of SDMA request lines associated with @oh
 757 * @oh: struct omap_hwmod *oh
 758 *
 759 * Count and return the number of SDMA request lines associated with
 760 * the hwmod @oh.  Used to allocate struct resource data.  Returns 0
 761 * if @oh is NULL.
 762 */
 763static int _count_sdma_reqs(struct omap_hwmod *oh)
 764{
 765	struct omap_hwmod_dma_info *ohdi;
 766	int i = 0;
 767
 768	if (!oh || !oh->sdma_reqs)
 769		return 0;
 770
 771	do {
 772		ohdi = &oh->sdma_reqs[i++];
 773	} while (ohdi->dma_req != -1);
 774
 775	return i-1;
 776}
 777
 778/**
 779 * _count_ocp_if_addr_spaces - count the number of address space entries for @oh
 780 * @oh: struct omap_hwmod *oh
 781 *
 782 * Count and return the number of address space ranges associated with
 783 * the hwmod @oh.  Used to allocate struct resource data.  Returns 0
 784 * if @oh is NULL.
 785 */
 786static int _count_ocp_if_addr_spaces(struct omap_hwmod_ocp_if *os)
 787{
 788	struct omap_hwmod_addr_space *mem;
 789	int i = 0;
 790
 791	if (!os || !os->addr)
 792		return 0;
 793
 794	do {
 795		mem = &os->addr[i++];
 796	} while (mem->pa_start != mem->pa_end);
 797
 798	return i-1;
 799}
 800
 801/**
 802 * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
 803 * @oh: struct omap_hwmod *
 804 *
 805 * Returns the array index of the OCP slave port that the MPU
 806 * addresses the device on, or -EINVAL upon error or not found.
 807 */
 808static int __init _find_mpu_port_index(struct omap_hwmod *oh)
 809{
 810	int i;
 811	int found = 0;
 812
 813	if (!oh || oh->slaves_cnt == 0)
 814		return -EINVAL;
 815
 816	for (i = 0; i < oh->slaves_cnt; i++) {
 817		struct omap_hwmod_ocp_if *os = oh->slaves[i];
 818
 819		if (os->user & OCP_USER_MPU) {
 820			found = 1;
 821			break;
 822		}
 823	}
 824
 825	if (found)
 826		pr_debug("omap_hwmod: %s: MPU OCP slave port ID  %d\n",
 827			 oh->name, i);
 828	else
 829		pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n",
 830			 oh->name);
 831
 832	return (found) ? i : -EINVAL;
 833}
 834
 835/**
 836 * _find_mpu_rt_base - find hwmod register target base addr accessible by MPU
 837 * @oh: struct omap_hwmod *
 838 *
 839 * Return the virtual address of the base of the register target of
 840 * device @oh, or NULL on error.
 841 */
 842static void __iomem * __init _find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
 843{
 844	struct omap_hwmod_ocp_if *os;
 845	struct omap_hwmod_addr_space *mem;
 846	int i = 0, found = 0;
 847	void __iomem *va_start;
 848
 849	if (!oh || oh->slaves_cnt == 0)
 850		return NULL;
 851
 852	os = oh->slaves[index];
 853
 854	if (!os->addr)
 855		return NULL;
 856
 857	do {
 858		mem = &os->addr[i++];
 859		if (mem->flags & ADDR_TYPE_RT)
 860			found = 1;
 861	} while (!found && mem->pa_start != mem->pa_end);
 862
 863	if (found) {
 864		va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
 865		if (!va_start) {
 866			pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
 867			return NULL;
 868		}
 869		pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
 870			 oh->name, va_start);
 871	} else {
 872		pr_debug("omap_hwmod: %s: no MPU register target found\n",
 873			 oh->name);
 874	}
 875
 876	return (found) ? va_start : NULL;
 877}
 878
 879/**
 880 * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
 881 * @oh: struct omap_hwmod *
 882 *
 883 * If module is marked as SWSUP_SIDLE, force the module out of slave
 884 * idle; otherwise, configure it for smart-idle.  If module is marked
 885 * as SWSUP_MSUSPEND, force the module out of master standby;
 886 * otherwise, configure it for smart-standby.  No return value.
 887 */
 888static void _enable_sysc(struct omap_hwmod *oh)
 889{
 890	u8 idlemode, sf;
 891	u32 v;
 892
 893	if (!oh->class->sysc)
 894		return;
 895
 896	v = oh->_sysc_cache;
 897	sf = oh->class->sysc->sysc_flags;
 898
 899	if (sf & SYSC_HAS_SIDLEMODE) {
 900		idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
 901			HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
 902		_set_slave_idlemode(oh, idlemode, &v);
 903	}
 904
 905	if (sf & SYSC_HAS_MIDLEMODE) {
 906		if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
 907			idlemode = HWMOD_IDLEMODE_NO;
 908		} else {
 909			if (sf & SYSC_HAS_ENAWAKEUP)
 910				_enable_wakeup(oh, &v);
 911			if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
 912				idlemode = HWMOD_IDLEMODE_SMART_WKUP;
 913			else
 914				idlemode = HWMOD_IDLEMODE_SMART;
 915		}
 916		_set_master_standbymode(oh, idlemode, &v);
 917	}
 918
 919	/*
 920	 * XXX The clock framework should handle this, by
 921	 * calling into this code.  But this must wait until the
 922	 * clock structures are tagged with omap_hwmod entries
 923	 */
 924	if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) &&
 925	    (sf & SYSC_HAS_CLOCKACTIVITY))
 926		_set_clockactivity(oh, oh->class->sysc->clockact, &v);
 927
 928	/* If slave is in SMARTIDLE, also enable wakeup */
 929	if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
 930		_enable_wakeup(oh, &v);
 931
 932	_write_sysconfig(v, oh);
 933
 934	/*
 935	 * Set the autoidle bit only after setting the smartidle bit
 936	 * Setting this will not have any impact on the other modules.
 937	 */
 938	if (sf & SYSC_HAS_AUTOIDLE) {
 939		idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
 940			0 : 1;
 941		_set_module_autoidle(oh, idlemode, &v);
 942		_write_sysconfig(v, oh);
 943	}
 944}
 945
 946/**
 947 * _idle_sysc - try to put a module into idle via OCP_SYSCONFIG
 948 * @oh: struct omap_hwmod *
 949 *
 950 * If module is marked as SWSUP_SIDLE, force the module into slave
 951 * idle; otherwise, configure it for smart-idle.  If module is marked
 952 * as SWSUP_MSUSPEND, force the module into master standby; otherwise,
 953 * configure it for smart-standby.  No return value.
 954 */
 955static void _idle_sysc(struct omap_hwmod *oh)
 956{
 957	u8 idlemode, sf;
 958	u32 v;
 959
 960	if (!oh->class->sysc)
 961		return;
 962
 963	v = oh->_sysc_cache;
 964	sf = oh->class->sysc->sysc_flags;
 965
 966	if (sf & SYSC_HAS_SIDLEMODE) {
 967		idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
 968			HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
 969		_set_slave_idlemode(oh, idlemode, &v);
 970	}
 971
 972	if (sf & SYSC_HAS_MIDLEMODE) {
 973		if (oh->flags & HWMOD_SWSUP_MSTANDBY) {
 974			idlemode = HWMOD_IDLEMODE_FORCE;
 975		} else {
 976			if (sf & SYSC_HAS_ENAWAKEUP)
 977				_enable_wakeup(oh, &v);
 978			if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
 979				idlemode = HWMOD_IDLEMODE_SMART_WKUP;
 980			else
 981				idlemode = HWMOD_IDLEMODE_SMART;
 982		}
 983		_set_master_standbymode(oh, idlemode, &v);
 984	}
 985
 986	/* If slave is in SMARTIDLE, also enable wakeup */
 987	if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
 988		_enable_wakeup(oh, &v);
 989
 990	_write_sysconfig(v, oh);
 991}
 992
 993/**
 994 * _shutdown_sysc - force a module into idle via OCP_SYSCONFIG
 995 * @oh: struct omap_hwmod *
 996 *
 997 * Force the module into slave idle and master suspend. No return
 998 * value.
 999 */
1000static void _shutdown_sysc(struct omap_hwmod *oh)
1001{
1002	u32 v;
1003	u8 sf;
1004
1005	if (!oh->class->sysc)
1006		return;
1007
1008	v = oh->_sysc_cache;
1009	sf = oh->class->sysc->sysc_flags;
1010
1011	if (sf & SYSC_HAS_SIDLEMODE)
1012		_set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
1013
1014	if (sf & SYSC_HAS_MIDLEMODE)
1015		_set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
1016
1017	if (sf & SYSC_HAS_AUTOIDLE)
1018		_set_module_autoidle(oh, 1, &v);
1019
1020	_write_sysconfig(v, oh);
1021}
1022
1023/**
1024 * _lookup - find an omap_hwmod by name
1025 * @name: find an omap_hwmod by name
1026 *
1027 * Return a pointer to an omap_hwmod by name, or NULL if not found.
1028 */
1029static struct omap_hwmod *_lookup(const char *name)
1030{
1031	struct omap_hwmod *oh, *temp_oh;
1032
1033	oh = NULL;
1034
1035	list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
1036		if (!strcmp(name, temp_oh->name)) {
1037			oh = temp_oh;
1038			break;
1039		}
1040	}
1041
1042	return oh;
1043}
1044/**
1045 * _init_clkdm - look up a clockdomain name, store pointer in omap_hwmod
1046 * @oh: struct omap_hwmod *
1047 *
1048 * Convert a clockdomain name stored in a struct omap_hwmod into a
1049 * clockdomain pointer, and save it into the struct omap_hwmod.
1050 * return -EINVAL if clkdm_name does not exist or if the lookup failed.
1051 */
1052static int _init_clkdm(struct omap_hwmod *oh)
1053{
1054	if (cpu_is_omap24xx() || cpu_is_omap34xx())
1055		return 0;
1056
1057	if (!oh->clkdm_name) {
1058		pr_warning("omap_hwmod: %s: no clkdm_name\n", oh->name);
1059		return -EINVAL;
1060	}
1061
1062	oh->clkdm = clkdm_lookup(oh->clkdm_name);
1063	if (!oh->clkdm) {
1064		pr_warning("omap_hwmod: %s: could not associate to clkdm %s\n",
1065			oh->name, oh->clkdm_name);
1066		return -EINVAL;
1067	}
1068
1069	pr_debug("omap_hwmod: %s: associated to clkdm %s\n",
1070		oh->name, oh->clkdm_name);
1071
1072	return 0;
1073}
1074
1075/**
1076 * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as
1077 * well the clockdomain.
1078 * @oh: struct omap_hwmod *
1079 * @data: not used; pass NULL
1080 *
1081 * Called by omap_hwmod_setup_*() (after omap2_clk_init()).
1082 * Resolves all clock names embedded in the hwmod.  Returns 0 on
1083 * success, or a negative error code on failure.
1084 */
1085static int _init_clocks(struct omap_hwmod *oh, void *data)
1086{
1087	int ret = 0;
1088
1089	if (oh->_state != _HWMOD_STATE_REGISTERED)
1090		return 0;
1091
1092	pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
1093
1094	ret |= _init_main_clk(oh);
1095	ret |= _init_interface_clks(oh);
1096	ret |= _init_opt_clks(oh);
1097	ret |= _init_clkdm(oh);
1098
1099	if (!ret)
1100		oh->_state = _HWMOD_STATE_CLKS_INITED;
1101	else
1102		pr_warning("omap_hwmod: %s: cannot _init_clocks\n", oh->name);
1103
1104	return ret;
1105}
1106
1107/**
1108 * _wait_target_ready - wait for a module to leave slave idle
1109 * @oh: struct omap_hwmod *
1110 *
1111 * Wait for a module @oh to leave slave idle.  Returns 0 if the module
1112 * does not have an IDLEST bit or if the module successfully leaves
1113 * slave idle; otherwise, pass along the return value of the
1114 * appropriate *_cm*_wait_module_ready() function.
1115 */
1116static int _wait_target_ready(struct omap_hwmod *oh)
1117{
1118	struct omap_hwmod_ocp_if *os;
1119	int ret;
1120
1121	if (!oh)
1122		return -EINVAL;
1123
1124	if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1125		return 0;
1126
1127	os = oh->slaves[oh->_mpu_port_index];
1128
1129	if (oh->flags & HWMOD_NO_IDLEST)
1130		return 0;
1131
1132	/* XXX check module SIDLEMODE */
1133
1134	/* XXX check clock enable states */
1135
1136	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1137		ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
1138						 oh->prcm.omap2.idlest_reg_id,
1139						 oh->prcm.omap2.idlest_idle_bit);
1140	} else if (cpu_is_omap44xx()) {
1141		if (!oh->clkdm)
1142			return -EINVAL;
1143
1144		ret = omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition,
1145						     oh->clkdm->cm_inst,
1146						     oh->clkdm->clkdm_offs,
1147						     oh->prcm.omap4.clkctrl_offs);
1148	} else {
1149		BUG();
1150	};
1151
1152	return ret;
1153}
1154
1155/**
1156 * _wait_target_disable - wait for a module to be disabled
1157 * @oh: struct omap_hwmod *
1158 *
1159 * Wait for a module @oh to enter slave idle.  Returns 0 if the module
1160 * does not have an IDLEST bit or if the module successfully enters
1161 * slave idle; otherwise, pass along the return value of the
1162 * appropriate *_cm*_wait_module_idle() function.
1163 */
1164static int _wait_target_disable(struct omap_hwmod *oh)
1165{
1166	/* TODO: For now just handle OMAP4+ */
1167	if (cpu_is_omap24xx() || cpu_is_omap34xx())
1168		return 0;
1169
1170	if (!oh)
1171		return -EINVAL;
1172
1173	if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1174		return 0;
1175
1176	if (oh->flags & HWMOD_NO_IDLEST)
1177		return 0;
1178
1179	return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition,
1180					     oh->clkdm->cm_inst,
1181					     oh->clkdm->clkdm_offs,
1182					     oh->prcm.omap4.clkctrl_offs);
1183}
1184
1185/**
1186 * _lookup_hardreset - fill register bit info for this hwmod/reset line
1187 * @oh: struct omap_hwmod *
1188 * @name: name of the reset line in the context of this hwmod
1189 * @ohri: struct omap_hwmod_rst_info * that this function will fill in
1190 *
1191 * Return the bit position of the reset line that match the
1192 * input name. Return -ENOENT if not found.
1193 */
1194static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name,
1195			    struct omap_hwmod_rst_info *ohri)
1196{
1197	int i;
1198
1199	for (i = 0; i < oh->rst_lines_cnt; i++) {
1200		const char *rst_line = oh->rst_lines[i].name;
1201		if (!strcmp(rst_line, name)) {
1202			ohri->rst_shift = oh->rst_lines[i].rst_shift;
1203			ohri->st_shift = oh->rst_lines[i].st_shift;
1204			pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n",
1205				 oh->name, __func__, rst_line, ohri->rst_shift,
1206				 ohri->st_shift);
1207
1208			return 0;
1209		}
1210	}
1211
1212	return -ENOENT;
1213}
1214
1215/**
1216 * _assert_hardreset - assert the HW reset line of submodules
1217 * contained in the hwmod module.
1218 * @oh: struct omap_hwmod *
1219 * @name: name of the reset line to lookup and assert
1220 *
1221 * Some IP like dsp, ipu or iva contain processor that require
1222 * an HW reset line to be assert / deassert in order to enable fully
1223 * the IP.
1224 */
1225static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
1226{
1227	struct omap_hwmod_rst_info ohri;
1228	u8 ret;
1229
1230	if (!oh)
1231		return -EINVAL;
1232
1233	ret = _lookup_hardreset(oh, name, &ohri);
1234	if (IS_ERR_VALUE(ret))
1235		return ret;
1236
1237	if (cpu_is_omap24xx() || cpu_is_omap34xx())
1238		return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
1239						  ohri.rst_shift);
1240	else if (cpu_is_omap44xx())
1241		return omap4_prminst_assert_hardreset(ohri.rst_shift,
1242				  oh->clkdm->pwrdm.ptr->prcm_partition,
1243				  oh->clkdm->pwrdm.ptr->prcm_offs,
1244				  oh->prcm.omap4.rstctrl_offs);
1245	else
1246		return -EINVAL;
1247}
1248
1249/**
1250 * _deassert_hardreset - deassert the HW reset line of submodules contained
1251 * in the hwmod module.
1252 * @oh: struct omap_hwmod *
1253 * @name: name of the reset line to look up and deassert
1254 *
1255 * Some IP like dsp, ipu or iva contain processor that require
1256 * an HW reset line to be assert / deassert in order to enable fully
1257 * the IP.
1258 */
1259static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1260{
1261	struct omap_hwmod_rst_info ohri;
1262	int ret;
1263
1264	if (!oh)
1265		return -EINVAL;
1266
1267	ret = _lookup_hardreset(oh, name, &ohri);
1268	if (IS_ERR_VALUE(ret))
1269		return ret;
1270
1271	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1272		ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
1273						   ohri.rst_shift,
1274						   ohri.st_shift);
1275	} else if (cpu_is_omap44xx()) {
1276		if (ohri.st_shift)
1277			pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
1278			       oh->name, name);
1279		ret = omap4_prminst_deassert_hardreset(ohri.rst_shift,
1280				  oh->clkdm->pwrdm.ptr->prcm_partition,
1281				  oh->clkdm->pwrdm.ptr->prcm_offs,
1282				  oh->prcm.omap4.rstctrl_offs);
1283	} else {
1284		return -EINVAL;
1285	}
1286
1287	if (ret == -EBUSY)
1288		pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
1289
1290	return ret;
1291}
1292
1293/**
1294 * _read_hardreset - read the HW reset line state of submodules
1295 * contained in the hwmod module
1296 * @oh: struct omap_hwmod *
1297 * @name: name of the reset line to look up and read
1298 *
1299 * Return the state of the reset line.
1300 */
1301static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1302{
1303	struct omap_hwmod_rst_info ohri;
1304	u8 ret;
1305
1306	if (!oh)
1307		return -EINVAL;
1308
1309	ret = _lookup_hardreset(oh, name, &ohri);
1310	if (IS_ERR_VALUE(ret))
1311		return ret;
1312
1313	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1314		return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
1315						       ohri.st_shift);
1316	} else if (cpu_is_omap44xx()) {
1317		return omap4_prminst_is_hardreset_asserted(ohri.rst_shift,
1318				  oh->clkdm->pwrdm.ptr->prcm_partition,
1319				  oh->clkdm->pwrdm.ptr->prcm_offs,
1320				  oh->prcm.omap4.rstctrl_offs);
1321	} else {
1322		return -EINVAL;
1323	}
1324}
1325
1326/**
1327 * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit
1328 * @oh: struct omap_hwmod *
1329 *
1330 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit.  hwmod must be
1331 * enabled for this to work.  Returns -EINVAL if the hwmod cannot be
1332 * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
1333 * the module did not reset in time, or 0 upon success.
1334 *
1335 * In OMAP3 a specific SYSSTATUS register is used to get the reset status.
1336 * Starting in OMAP4, some IPs do not have SYSSTATUS registers and instead
1337 * use the SYSCONFIG softreset bit to provide the status.
1338 *
1339 * Note that some IP like McBSP do have reset control but don't have
1340 * reset status.
1341 */
1342static int _ocp_softreset(struct omap_hwmod *oh)
1343{
1344	u32 v;
1345	int c = 0;
1346	int ret = 0;
1347
1348	if (!oh->class->sysc ||
1349	    !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
1350		return -EINVAL;
1351
1352	/* clocks must be on for this operation */
1353	if (oh->_state != _HWMOD_STATE_ENABLED) {
1354		pr_warning("omap_hwmod: %s: reset can only be entered from "
1355			   "enabled state\n", oh->name);
1356		return -EINVAL;
1357	}
1358
1359	/* For some modules, all optionnal clocks need to be enabled as well */
1360	if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1361		_enable_optional_clocks(oh);
1362
1363	pr_debug("omap_hwmod: %s: resetting via OCP SOFTRESET\n", oh->name);
1364
1365	v = oh->_sysc_cache;
1366	ret = _set_softreset(oh, &v);
1367	if (ret)
1368		goto dis_opt_clks;
1369	_write_sysconfig(v, oh);
1370
1371	if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
1372		omap_test_timeout((omap_hwmod_read(oh,
1373						    oh->class->sysc->syss_offs)
1374				   & SYSS_RESETDONE_MASK),
1375				  MAX_MODULE_SOFTRESET_WAIT, c);
1376	else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS)
1377		omap_test_timeout(!(omap_hwmod_read(oh,
1378						     oh->class->sysc->sysc_offs)
1379				   & SYSC_TYPE2_SOFTRESET_MASK),
1380				  MAX_MODULE_SOFTRESET_WAIT, c);
1381
1382	if (c == MAX_MODULE_SOFTRESET_WAIT)
1383		pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
1384			   oh->name, MAX_MODULE_SOFTRESET_WAIT);
1385	else
1386		pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
1387
1388	/*
1389	 * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
1390	 * _wait_target_ready() or _reset()
1391	 */
1392
1393	ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
1394
1395dis_opt_clks:
1396	if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1397		_disable_optional_clocks(oh);
1398
1399	return ret;
1400}
1401
1402/**
1403 * _reset - reset an omap_hwmod
1404 * @oh: struct omap_hwmod *
1405 *
1406 * Resets an omap_hwmod @oh.  The default software reset mechanism for
1407 * most OMAP IP blocks is triggered via the OCP_SYSCONFIG.SOFTRESET
1408 * bit.  However, some hwmods cannot be reset via this method: some
1409 * are not targets and therefore have no OCP header registers to
1410 * access; others (like the IVA) have idiosyncratic reset sequences.
1411 * So for these relatively rare cases, custom reset code can be
1412 * supplied in the struct omap_hwmod_class .reset function pointer.
1413 * Passes along the return value from either _reset() or the custom
1414 * reset function - these must return -EINVAL if the hwmod cannot be
1415 * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
1416 * the module did not reset in time, or 0 upon success.
1417 */
1418static int _reset(struct omap_hwmod *oh)
1419{
1420	int ret;
1421
1422	pr_debug("omap_hwmod: %s: resetting\n", oh->name);
1423
1424	ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh);
1425
1426	return ret;
1427}
1428
1429/**
1430 * _enable - enable an omap_hwmod
1431 * @oh: struct omap_hwmod *
1432 *
1433 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
1434 * register target.  Returns -EINVAL if the hwmod is in the wrong
1435 * state or passes along the return value of _wait_target_ready().
1436 */
1437static int _enable(struct omap_hwmod *oh)
1438{
1439	int r;
1440	int hwsup = 0;
1441
1442	pr_debug("omap_hwmod: %s: enabling\n", oh->name);
1443
1444	if (oh->_state != _HWMOD_STATE_INITIALIZED &&
1445	    oh->_state != _HWMOD_STATE_IDLE &&
1446	    oh->_state != _HWMOD_STATE_DISABLED) {
1447		WARN(1, "omap_hwmod: %s: enabled state can only be entered "
1448		     "from initialized, idle, or disabled state\n", oh->name);
1449		return -EINVAL;
1450	}
1451
1452
1453	/*
1454	 * If an IP contains only one HW reset line, then de-assert it in order
1455	 * to allow the module state transition. Otherwise the PRCM will return
1456	 * Intransition status, and the init will failed.
1457	 */
1458	if ((oh->_state == _HWMOD_STATE_INITIALIZED ||
1459	     oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1)
1460		_deassert_hardreset(oh, oh->rst_lines[0].name);
1461
1462	/* Mux pins for device runtime if populated */
1463	if (oh->mux && (!oh->mux->enabled ||
1464			((oh->_state == _HWMOD_STATE_IDLE) &&
1465			 oh->mux->pads_dynamic)))
1466		omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
1467
1468	_add_initiator_dep(oh, mpu_oh);
1469
1470	if (oh->clkdm) {
1471		/*
1472		 * A clockdomain must be in SW_SUP before enabling
1473		 * completely the module. The clockdomain can be set
1474		 * in HW_AUTO only when the module become ready.
1475		 */
1476		hwsup = clkdm_in_hwsup(oh->clkdm);
1477		r = clkdm_hwmod_enable(oh->clkdm, oh);
1478		if (r) {
1479			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
1480			     oh->name, oh->clkdm->name, r);
1481			return r;
1482		}
1483	}
1484
1485	_enable_clocks(oh);
1486	_enable_module(oh);
1487
1488	r = _wait_target_ready(oh);
1489	if (!r) {
1490		/*
1491		 * Set the clockdomain to HW_AUTO only if the target is ready,
1492		 * assuming that the previous state was HW_AUTO
1493		 */
1494		if (oh->clkdm && hwsup)
1495			clkdm_allow_idle(oh->clkdm);
1496
1497		oh->_state = _HWMOD_STATE_ENABLED;
1498
1499		/* Access the sysconfig only if the target is ready */
1500		if (oh->class->sysc) {
1501			if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
1502				_update_sysc_cache(oh);
1503			_enable_sysc(oh);
1504		}
1505	} else {
1506		_disable_clocks(oh);
1507		pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
1508			 oh->name, r);
1509
1510		if (oh->clkdm)
1511			clkdm_hwmod_disable(oh->clkdm, oh);
1512	}
1513
1514	return r;
1515}
1516
1517/**
1518 * _idle - idle an omap_hwmod
1519 * @oh: struct omap_hwmod *
1520 *
1521 * Idles an omap_hwmod @oh.  This should be called once the hwmod has
1522 * no further work.  Returns -EINVAL if the hwmod is in the wrong
1523 * state or returns 0.
1524 */
1525static int _idle(struct omap_hwmod *oh)
1526{
1527	int ret;
1528
1529	pr_debug("omap_hwmod: %s: idling\n", oh->name);
1530
1531	if (oh->_state != _HWMOD_STATE_ENABLED) {
1532		WARN(1, "omap_hwmod: %s: idle state can only be entered from "
1533		     "enabled state\n", oh->name);
1534		return -EINVAL;
1535	}
1536
1537	if (oh->class->sysc)
1538		_idle_sysc(oh);
1539	_del_initiator_dep(oh, mpu_oh);
1540	_disable_module(oh);
1541	ret = _wait_target_disable(oh);
1542	if (ret)
1543		pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1544			oh->name);
1545	/*
1546	 * The module must be in idle mode before disabling any parents
1547	 * clocks. Otherwise, the parent clock might be disabled before
1548	 * the module transition is done, and thus will prevent the
1549	 * transition to complete properly.
1550	 */
1551	_disable_clocks(oh);
1552	if (oh->clkdm)
1553		clkdm_hwmod_disable(oh->clkdm, oh);
1554
1555	/* Mux pins for device idle if populated */
1556	if (oh->mux && oh->mux->pads_dynamic)
1557		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
1558
1559	oh->_state = _HWMOD_STATE_IDLE;
1560
1561	return 0;
1562}
1563
1564/**
1565 * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit
1566 * @oh: struct omap_hwmod *
1567 * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
1568 *
1569 * Sets the IP block's OCP autoidle bit in hardware, and updates our
1570 * local copy. Intended to be used by drivers that require
1571 * direct manipulation of the AUTOIDLE bits.
1572 * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes
1573 * along the return value from _set_module_autoidle().
1574 *
1575 * Any users of this function should be scrutinized carefully.
1576 */
1577int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle)
1578{
1579	u32 v;
1580	int retval = 0;
1581	unsigned long flags;
1582
1583	if (!oh || oh->_state != _HWMOD_STATE_ENABLED)
1584		return -EINVAL;
1585
1586	spin_lock_irqsave(&oh->_lock, flags);
1587
1588	v = oh->_sysc_cache;
1589
1590	retval = _set_module_autoidle(oh, autoidle, &v);
1591
1592	if (!retval)
1593		_write_sysconfig(v, oh);
1594
1595	spin_unlock_irqrestore(&oh->_lock, flags);
1596
1597	return retval;
1598}
1599
1600/**
1601 * _shutdown - shutdown an omap_hwmod
1602 * @oh: struct omap_hwmod *
1603 *
1604 * Shut down an omap_hwmod @oh.  This should be called when the driver
1605 * used for the hwmod is removed or unloaded or if the driver is not
1606 * used by the system.  Returns -EINVAL if the hwmod is in the wrong
1607 * state or returns 0.
1608 */
1609static int _shutdown(struct omap_hwmod *oh)
1610{
1611	int ret;
1612	u8 prev_state;
1613
1614	if (oh->_state != _HWMOD_STATE_IDLE &&
1615	    oh->_state != _HWMOD_STATE_ENABLED) {
1616		WARN(1, "omap_hwmod: %s: disabled state can only be entered "
1617		     "from idle, or enabled state\n", oh->name);
1618		return -EINVAL;
1619	}
1620
1621	pr_debug("omap_hwmod: %s: disabling\n", oh->name);
1622
1623	if (oh->class->pre_shutdown) {
1624		prev_state = oh->_state;
1625		if (oh->_state == _HWMOD_STATE_IDLE)
1626			_enable(oh);
1627		ret = oh->class->pre_shutdown(oh);
1628		if (ret) {
1629			if (prev_state == _HWMOD_STATE_IDLE)
1630				_idle(oh);
1631			return ret;
1632		}
1633	}
1634
1635	if (oh->class->sysc) {
1636		if (oh->_state == _HWMOD_STATE_IDLE)
1637			_enable(oh);
1638		_shutdown_sysc(oh);
1639	}
1640
1641	/* clocks and deps are already disabled in idle */
1642	if (oh->_state == _HWMOD_STATE_ENABLED) {
1643		_del_initiator_dep(oh, mpu_oh);
1644		/* XXX what about the other system initiators here? dma, dsp */
1645		_disable_module(oh);
1646		ret = _wait_target_disable(oh);
1647		if (ret)
1648			pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1649				oh->name);
1650		_disable_clocks(oh);
1651		if (oh->clkdm)
1652			clkdm_hwmod_disable(oh->clkdm, oh);
1653	}
1654	/* XXX Should this code also force-disable the optional clocks? */
1655
1656	/*
1657	 * If an IP contains only one HW reset line, then assert it
1658	 * after disabling the clocks and before shutting down the IP.
1659	 */
1660	if (oh->rst_lines_cnt == 1)
1661		_assert_hardreset(oh, oh->rst_lines[0].name);
1662
1663	/* Mux pins to safe mode or use populated off mode values */
1664	if (oh->mux)
1665		omap_hwmod_mux(oh->mux, _HWMOD_STATE_DISABLED);
1666
1667	oh->_state = _HWMOD_STATE_DISABLED;
1668
1669	return 0;
1670}
1671
1672/**
1673 * _setup - do initial configuration of omap_hwmod
1674 * @oh: struct omap_hwmod *
1675 *
1676 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
1677 * OCP_SYSCONFIG register.  Returns 0.
1678 */
1679static int _setup(struct omap_hwmod *oh, void *data)
1680{
1681	int i, r;
1682	u8 postsetup_state;
1683
1684	if (oh->_state != _HWMOD_STATE_CLKS_INITED)
1685		return 0;
1686
1687	/* Set iclk autoidle mode */
1688	if (oh->slaves_cnt > 0) {
1689		for (i = 0; i < oh->slaves_cnt; i++) {
1690			struct omap_hwmod_ocp_if *os = oh->slaves[i];
1691			struct clk *c = os->_clk;
1692
1693			if (!c)
1694				continue;
1695
1696			if (os->flags & OCPIF_SWSUP_IDLE) {
1697				/* XXX omap_iclk_deny_idle(c); */
1698			} else {
1699				/* XXX omap_iclk_allow_idle(c); */
1700				clk_enable(c);
1701			}
1702		}
1703	}
1704
1705	oh->_state = _HWMOD_STATE_INITIALIZED;
1706
1707	/*
1708	 * In the case of hwmod with hardreset that should not be
1709	 * de-assert at boot time, we have to keep the module
1710	 * initialized, because we cannot enable it properly with the
1711	 * reset asserted. Exit without warning because that behavior is
1712	 * expected.
1713	 */
1714	if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt == 1)
1715		return 0;
1716
1717	r = _enable(oh);
1718	if (r) {
1719		pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
1720			   oh->name, oh->_state);
1721		return 0;
1722	}
1723
1724	if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
1725		_reset(oh);
1726
1727		/*
1728		 * OCP_SYSCONFIG bits need to be reprogrammed after a softreset.
1729		 * The _enable() function should be split to
1730		 * avoid the rewrite of the OCP_SYSCONFIG register.
1731		 */
1732		if (oh->class->sysc) {
1733			_update_sysc_cache(oh);
1734			_enable_sysc(oh);
1735		}
1736	}
1737
1738	postsetup_state = oh->_postsetup_state;
1739	if (postsetup_state == _HWMOD_STATE_UNKNOWN)
1740		postsetup_state = _HWMOD_STATE_ENABLED;
1741
1742	/*
1743	 * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
1744	 * it should be set by the core code as a runtime flag during startup
1745	 */
1746	if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
1747	    (postsetup_state == _HWMOD_STATE_IDLE))
1748		postsetup_state = _HWMOD_STATE_ENABLED;
1749
1750	if (postsetup_state == _HWMOD_STATE_IDLE)
1751		_idle(oh);
1752	else if (postsetup_state == _HWMOD_STATE_DISABLED)
1753		_shutdown(oh);
1754	else if (postsetup_state != _HWMOD_STATE_ENABLED)
1755		WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
1756		     oh->name, postsetup_state);
1757
1758	return 0;
1759}
1760
1761/**
1762 * _register - register a struct omap_hwmod
1763 * @oh: struct omap_hwmod *
1764 *
1765 * Registers the omap_hwmod @oh.  Returns -EEXIST if an omap_hwmod
1766 * already has been registered by the same name; -EINVAL if the
1767 * omap_hwmod is in the wrong state, if @oh is NULL, if the
1768 * omap_hwmod's class field is NULL; if the omap_hwmod is missing a
1769 * name, or if the omap_hwmod's class is missing a name; or 0 upon
1770 * success.
1771 *
1772 * XXX The data should be copied into bootmem, so the original data
1773 * should be marked __initdata and freed after init.  This would allow
1774 * unneeded omap_hwmods to be freed on multi-OMAP configurations.  Note
1775 * that the copy process would be relatively complex due to the large number
1776 * of substructures.
1777 */
1778static int __init _register(struct omap_hwmod *oh)
1779{
1780	int ms_id;
1781
1782	if (!oh || !oh->name || !oh->class || !oh->class->name ||
1783	    (oh->_state != _HWMOD_STATE_UNKNOWN))
1784		return -EINVAL;
1785
1786	pr_debug("omap_hwmod: %s: registering\n", oh->name);
1787
1788	if (_lookup(oh->name))
1789		r

Large files files are truncated, but you can click here to view the full file