powerdomain.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234
  1. /*
  2. * OMAP powerdomain control
  3. *
  4. * Copyright (C) 2007-2008 Texas Instruments, Inc.
  5. * Copyright (C) 2007-2008 Nokia Corporation
  6. *
  7. * Written by Paul Walmsley
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #undef DEBUG
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/types.h>
  17. #include <linux/delay.h>
  18. #include <linux/spinlock.h>
  19. #include <linux/list.h>
  20. #include <linux/errno.h>
  21. #include <linux/err.h>
  22. #include <linux/io.h>
  23. #include <asm/atomic.h>
  24. #include "cm.h"
  25. #include "cm-regbits-34xx.h"
  26. #include "prm.h"
  27. #include "prm-regbits-34xx.h"
  28. #include <plat/cpu.h>
  29. #include <plat/powerdomain.h>
  30. #include <plat/clockdomain.h>
  31. #include "pm.h"
  32. enum {
  33. PWRDM_STATE_NOW = 0,
  34. PWRDM_STATE_PREV,
  35. };
  36. /* pwrdm_list contains all registered struct powerdomains */
  37. static LIST_HEAD(pwrdm_list);
  38. /*
  39. * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to
  40. * protect pwrdm_clkdms[] during clkdm add/del ops
  41. */
  42. static DEFINE_RWLOCK(pwrdm_rwlock);
  43. /* Private functions */
  44. static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
  45. {
  46. u32 v;
  47. v = prm_read_mod_reg(domain, idx);
  48. v &= mask;
  49. v >>= __ffs(mask);
  50. return v;
  51. }
  52. static struct powerdomain *_pwrdm_lookup(const char *name)
  53. {
  54. struct powerdomain *pwrdm, *temp_pwrdm;
  55. pwrdm = NULL;
  56. list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
  57. if (!strcmp(name, temp_pwrdm->name)) {
  58. pwrdm = temp_pwrdm;
  59. break;
  60. }
  61. }
  62. return pwrdm;
  63. }
  64. /* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
  65. static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
  66. struct pwrdm_dep *deps)
  67. {
  68. struct pwrdm_dep *pd;
  69. if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
  70. return ERR_PTR(-EINVAL);
  71. for (pd = deps; pd->pwrdm_name; pd++) {
  72. if (!omap_chip_is(pd->omap_chip))
  73. continue;
  74. if (!pd->pwrdm && pd->pwrdm_name)
  75. pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
  76. if (pd->pwrdm == pwrdm)
  77. break;
  78. }
  79. if (!pd->pwrdm_name)
  80. return ERR_PTR(-ENOENT);
  81. return pd->pwrdm;
  82. }
  83. static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
  84. {
  85. int prev;
  86. int state;
  87. if (pwrdm == NULL)
  88. return -EINVAL;
  89. state = pwrdm_read_pwrst(pwrdm);
  90. switch (flag) {
  91. case PWRDM_STATE_NOW:
  92. prev = pwrdm->state;
  93. break;
  94. case PWRDM_STATE_PREV:
  95. prev = pwrdm_read_prev_pwrst(pwrdm);
  96. if (pwrdm->state != prev)
  97. pwrdm->state_counter[prev]++;
  98. break;
  99. default:
  100. return -EINVAL;
  101. }
  102. if (state != prev)
  103. pwrdm->state_counter[state]++;
  104. pm_dbg_update_time(pwrdm, prev);
  105. pwrdm->state = state;
  106. return 0;
  107. }
  108. static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
  109. {
  110. pwrdm_clear_all_prev_pwrst(pwrdm);
  111. _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
  112. return 0;
  113. }
  114. static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
  115. {
  116. _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
  117. return 0;
  118. }
  119. static __init void _pwrdm_setup(struct powerdomain *pwrdm)
  120. {
  121. int i;
  122. for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
  123. pwrdm->state_counter[i] = 0;
  124. pwrdm_wait_transition(pwrdm);
  125. pwrdm->state = pwrdm_read_pwrst(pwrdm);
  126. pwrdm->state_counter[pwrdm->state] = 1;
  127. }
  128. /* Public functions */
  129. /**
  130. * pwrdm_init - set up the powerdomain layer
  131. *
  132. * Loop through the list of powerdomains, registering all that are
  133. * available on the current CPU. If pwrdm_list is supplied and not
  134. * null, all of the referenced powerdomains will be registered. No
  135. * return value.
  136. */
  137. void pwrdm_init(struct powerdomain **pwrdm_list)
  138. {
  139. struct powerdomain **p = NULL;
  140. if (pwrdm_list) {
  141. for (p = pwrdm_list; *p; p++) {
  142. pwrdm_register(*p);
  143. _pwrdm_setup(*p);
  144. }
  145. }
  146. }
  147. /**
  148. * pwrdm_register - register a powerdomain
  149. * @pwrdm: struct powerdomain * to register
  150. *
  151. * Adds a powerdomain to the internal powerdomain list. Returns
  152. * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
  153. * already registered by the provided name, or 0 upon success.
  154. */
  155. int pwrdm_register(struct powerdomain *pwrdm)
  156. {
  157. unsigned long flags;
  158. int ret = -EINVAL;
  159. if (!pwrdm)
  160. return -EINVAL;
  161. if (!omap_chip_is(pwrdm->omap_chip))
  162. return -EINVAL;
  163. write_lock_irqsave(&pwrdm_rwlock, flags);
  164. if (_pwrdm_lookup(pwrdm->name)) {
  165. ret = -EEXIST;
  166. goto pr_unlock;
  167. }
  168. list_add(&pwrdm->node, &pwrdm_list);
  169. pr_debug("powerdomain: registered %s\n", pwrdm->name);
  170. ret = 0;
  171. pr_unlock:
  172. write_unlock_irqrestore(&pwrdm_rwlock, flags);
  173. return ret;
  174. }
  175. /**
  176. * pwrdm_unregister - unregister a powerdomain
  177. * @pwrdm: struct powerdomain * to unregister
  178. *
  179. * Removes a powerdomain from the internal powerdomain list. Returns
  180. * -EINVAL if pwrdm argument is NULL.
  181. */
  182. int pwrdm_unregister(struct powerdomain *pwrdm)
  183. {
  184. unsigned long flags;
  185. if (!pwrdm)
  186. return -EINVAL;
  187. write_lock_irqsave(&pwrdm_rwlock, flags);
  188. list_del(&pwrdm->node);
  189. write_unlock_irqrestore(&pwrdm_rwlock, flags);
  190. pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
  191. return 0;
  192. }
  193. /**
  194. * pwrdm_lookup - look up a powerdomain by name, return a pointer
  195. * @name: name of powerdomain
  196. *
  197. * Find a registered powerdomain by its name. Returns a pointer to the
  198. * struct powerdomain if found, or NULL otherwise.
  199. */
  200. struct powerdomain *pwrdm_lookup(const char *name)
  201. {
  202. struct powerdomain *pwrdm;
  203. unsigned long flags;
  204. if (!name)
  205. return NULL;
  206. read_lock_irqsave(&pwrdm_rwlock, flags);
  207. pwrdm = _pwrdm_lookup(name);
  208. read_unlock_irqrestore(&pwrdm_rwlock, flags);
  209. return pwrdm;
  210. }
  211. /**
  212. * pwrdm_for_each_nolock - call function on each registered clockdomain
  213. * @fn: callback function *
  214. *
  215. * Call the supplied function for each registered powerdomain. The
  216. * callback function can return anything but 0 to bail out early from
  217. * the iterator. Returns the last return value of the callback function, which
  218. * should be 0 for success or anything else to indicate failure; or -EINVAL if
  219. * the function pointer is null.
  220. */
  221. int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
  222. void *user)
  223. {
  224. struct powerdomain *temp_pwrdm;
  225. int ret = 0;
  226. if (!fn)
  227. return -EINVAL;
  228. list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
  229. ret = (*fn)(temp_pwrdm, user);
  230. if (ret)
  231. break;
  232. }
  233. return ret;
  234. }
  235. /**
  236. * pwrdm_for_each - call function on each registered clockdomain
  237. * @fn: callback function *
  238. *
  239. * This function is the same as 'pwrdm_for_each_nolock()', but keeps the
  240. * &pwrdm_rwlock locked for reading, so no powerdomain structure manipulation
  241. * functions should be called from the callback, although hardware powerdomain
  242. * control functions are fine.
  243. */
  244. int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
  245. void *user)
  246. {
  247. unsigned long flags;
  248. int ret;
  249. read_lock_irqsave(&pwrdm_rwlock, flags);
  250. ret = pwrdm_for_each_nolock(fn, user);
  251. read_unlock_irqrestore(&pwrdm_rwlock, flags);
  252. return ret;
  253. }
  254. /**
  255. * pwrdm_add_clkdm - add a clockdomain to a powerdomain
  256. * @pwrdm: struct powerdomain * to add the clockdomain to
  257. * @clkdm: struct clockdomain * to associate with a powerdomain
  258. *
  259. * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This
  260. * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
  261. * presented with invalid pointers; -ENOMEM if memory could not be allocated;
  262. * or 0 upon success.
  263. */
  264. int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
  265. {
  266. unsigned long flags;
  267. int i;
  268. int ret = -EINVAL;
  269. if (!pwrdm || !clkdm)
  270. return -EINVAL;
  271. pr_debug("powerdomain: associating clockdomain %s with powerdomain "
  272. "%s\n", clkdm->name, pwrdm->name);
  273. write_lock_irqsave(&pwrdm_rwlock, flags);
  274. for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
  275. if (!pwrdm->pwrdm_clkdms[i])
  276. break;
  277. #ifdef DEBUG
  278. if (pwrdm->pwrdm_clkdms[i] == clkdm) {
  279. ret = -EINVAL;
  280. goto pac_exit;
  281. }
  282. #endif
  283. }
  284. if (i == PWRDM_MAX_CLKDMS) {
  285. pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
  286. "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
  287. WARN_ON(1);
  288. ret = -ENOMEM;
  289. goto pac_exit;
  290. }
  291. pwrdm->pwrdm_clkdms[i] = clkdm;
  292. ret = 0;
  293. pac_exit:
  294. write_unlock_irqrestore(&pwrdm_rwlock, flags);
  295. return ret;
  296. }
  297. /**
  298. * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
  299. * @pwrdm: struct powerdomain * to add the clockdomain to
  300. * @clkdm: struct clockdomain * to associate with a powerdomain
  301. *
  302. * Dissociate the clockdomain 'clkdm' from the powerdomain
  303. * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
  304. * -ENOENT if the clkdm was not associated with the powerdomain, or 0
  305. * upon success.
  306. */
  307. int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
  308. {
  309. unsigned long flags;
  310. int ret = -EINVAL;
  311. int i;
  312. if (!pwrdm || !clkdm)
  313. return -EINVAL;
  314. pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
  315. "%s\n", clkdm->name, pwrdm->name);
  316. write_lock_irqsave(&pwrdm_rwlock, flags);
  317. for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
  318. if (pwrdm->pwrdm_clkdms[i] == clkdm)
  319. break;
  320. if (i == PWRDM_MAX_CLKDMS) {
  321. pr_debug("powerdomain: clkdm %s not associated with pwrdm "
  322. "%s ?!\n", clkdm->name, pwrdm->name);
  323. ret = -ENOENT;
  324. goto pdc_exit;
  325. }
  326. pwrdm->pwrdm_clkdms[i] = NULL;
  327. ret = 0;
  328. pdc_exit:
  329. write_unlock_irqrestore(&pwrdm_rwlock, flags);
  330. return ret;
  331. }
  332. /**
  333. * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
  334. * @pwrdm: struct powerdomain * to iterate over
  335. * @fn: callback function *
  336. *
  337. * Call the supplied function for each clockdomain in the powerdomain
  338. * 'pwrdm'. The callback function can return anything but 0 to bail
  339. * out early from the iterator. The callback function is called with
  340. * the pwrdm_rwlock held for reading, so no powerdomain structure
  341. * manipulation functions should be called from the callback, although
  342. * hardware powerdomain control functions are fine. Returns -EINVAL
  343. * if presented with invalid pointers; or passes along the last return
  344. * value of the callback function, which should be 0 for success or
  345. * anything else to indicate failure.
  346. */
  347. int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
  348. int (*fn)(struct powerdomain *pwrdm,
  349. struct clockdomain *clkdm))
  350. {
  351. unsigned long flags;
  352. int ret = 0;
  353. int i;
  354. if (!fn)
  355. return -EINVAL;
  356. read_lock_irqsave(&pwrdm_rwlock, flags);
  357. for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
  358. ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
  359. read_unlock_irqrestore(&pwrdm_rwlock, flags);
  360. return ret;
  361. }
  362. /**
  363. * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
  364. * @pwrdm1: wake this struct powerdomain * up (dependent)
  365. * @pwrdm2: when this struct powerdomain * wakes up (source)
  366. *
  367. * When the powerdomain represented by pwrdm2 wakes up (due to an
  368. * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP,
  369. * this feature is designed to reduce wakeup latency of the dependent
  370. * powerdomain. Returns -EINVAL if presented with invalid powerdomain
  371. * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
  372. * 0 upon success.
  373. */
  374. int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
  375. {
  376. struct powerdomain *p;
  377. if (!pwrdm1)
  378. return -EINVAL;
  379. p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
  380. if (IS_ERR(p)) {
  381. pr_debug("powerdomain: hardware cannot set/clear wake up of "
  382. "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
  383. return PTR_ERR(p);
  384. }
  385. pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
  386. pwrdm1->name, pwrdm2->name);
  387. prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
  388. pwrdm1->prcm_offs, PM_WKDEP);
  389. return 0;
  390. }
  391. /**
  392. * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
  393. * @pwrdm1: wake this struct powerdomain * up (dependent)
  394. * @pwrdm2: when this struct powerdomain * wakes up (source)
  395. *
  396. * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
  397. * wakes up. Returns -EINVAL if presented with invalid powerdomain
  398. * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
  399. * 0 upon success.
  400. */
  401. int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
  402. {
  403. struct powerdomain *p;
  404. if (!pwrdm1)
  405. return -EINVAL;
  406. p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
  407. if (IS_ERR(p)) {
  408. pr_debug("powerdomain: hardware cannot set/clear wake up of "
  409. "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
  410. return PTR_ERR(p);
  411. }
  412. pr_debug("powerdomain: hardware will no longer wake up %s after %s "
  413. "wakes up\n", pwrdm1->name, pwrdm2->name);
  414. prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
  415. pwrdm1->prcm_offs, PM_WKDEP);
  416. return 0;
  417. }
  418. /**
  419. * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
  420. * @pwrdm1: wake this struct powerdomain * up (dependent)
  421. * @pwrdm2: when this struct powerdomain * wakes up (source)
  422. *
  423. * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
  424. * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
  425. * if either powerdomain pointer is invalid; or -ENOENT if the hardware
  426. * is incapable.
  427. *
  428. * REVISIT: Currently this function only represents software-controllable
  429. * wakeup dependencies. Wakeup dependencies fixed in hardware are not
  430. * yet handled here.
  431. */
  432. int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
  433. {
  434. struct powerdomain *p;
  435. if (!pwrdm1)
  436. return -EINVAL;
  437. p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
  438. if (IS_ERR(p)) {
  439. pr_debug("powerdomain: hardware cannot set/clear wake up of "
  440. "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
  441. return PTR_ERR(p);
  442. }
  443. return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
  444. (1 << pwrdm2->dep_bit));
  445. }
  446. /**
  447. * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
  448. * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
  449. * @pwrdm2: when this struct powerdomain * is active (source)
  450. *
  451. * Prevent pwrdm1 from automatically going inactive (and then to
  452. * retention or off) if pwrdm2 is still active. Returns -EINVAL if
  453. * presented with invalid powerdomain pointers or called on a machine
  454. * that does not support software-configurable hardware sleep dependencies,
  455. * -ENOENT if the specified dependency cannot be set in hardware, or
  456. * 0 upon success.
  457. */
  458. int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
  459. {
  460. struct powerdomain *p;
  461. if (!cpu_is_omap34xx())
  462. return -EINVAL;
  463. if (!pwrdm1)
  464. return -EINVAL;
  465. p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
  466. if (IS_ERR(p)) {
  467. pr_debug("powerdomain: hardware cannot set/clear sleep "
  468. "dependency affecting %s from %s\n", pwrdm1->name,
  469. pwrdm2->name);
  470. return PTR_ERR(p);
  471. }
  472. pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
  473. pwrdm1->name, pwrdm2->name);
  474. cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
  475. pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
  476. return 0;
  477. }
  478. /**
  479. * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
  480. * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
  481. * @pwrdm2: when this struct powerdomain * is active (source)
  482. *
  483. * Allow pwrdm1 to automatically go inactive (and then to retention or
  484. * off), independent of the activity state of pwrdm2. Returns -EINVAL
  485. * if presented with invalid powerdomain pointers or called on a machine
  486. * that does not support software-configurable hardware sleep dependencies,
  487. * -ENOENT if the specified dependency cannot be cleared in hardware, or
  488. * 0 upon success.
  489. */
  490. int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
  491. {
  492. struct powerdomain *p;
  493. if (!cpu_is_omap34xx())
  494. return -EINVAL;
  495. if (!pwrdm1)
  496. return -EINVAL;
  497. p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
  498. if (IS_ERR(p)) {
  499. pr_debug("powerdomain: hardware cannot set/clear sleep "
  500. "dependency affecting %s from %s\n", pwrdm1->name,
  501. pwrdm2->name);
  502. return PTR_ERR(p);
  503. }
  504. pr_debug("powerdomain: will no longer prevent %s from sleeping if "
  505. "%s is active\n", pwrdm1->name, pwrdm2->name);
  506. cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
  507. pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
  508. return 0;
  509. }
  510. /**
  511. * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
  512. * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
  513. * @pwrdm2: when this struct powerdomain * is active (source)
  514. *
  515. * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
  516. * not be allowed to automatically go inactive if pwrdm2 is active;
  517. * 0 if pwrdm1's automatic power state inactivity transition is independent
  518. * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
  519. * on a machine that does not support software-configurable hardware sleep
  520. * dependencies; or -ENOENT if the hardware is incapable.
  521. *
  522. * REVISIT: Currently this function only represents software-controllable
  523. * sleep dependencies. Sleep dependencies fixed in hardware are not
  524. * yet handled here.
  525. */
  526. int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
  527. {
  528. struct powerdomain *p;
  529. if (!cpu_is_omap34xx())
  530. return -EINVAL;
  531. if (!pwrdm1)
  532. return -EINVAL;
  533. p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
  534. if (IS_ERR(p)) {
  535. pr_debug("powerdomain: hardware cannot set/clear sleep "
  536. "dependency affecting %s from %s\n", pwrdm1->name,
  537. pwrdm2->name);
  538. return PTR_ERR(p);
  539. }
  540. return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
  541. (1 << pwrdm2->dep_bit));
  542. }
  543. /**
  544. * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
  545. * @pwrdm: struct powerdomain *
  546. *
  547. * Return the number of controllable memory banks in powerdomain pwrdm,
  548. * starting with 1. Returns -EINVAL if the powerdomain pointer is null.
  549. */
  550. int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
  551. {
  552. if (!pwrdm)
  553. return -EINVAL;
  554. return pwrdm->banks;
  555. }
  556. /**
  557. * pwrdm_set_next_pwrst - set next powerdomain power state
  558. * @pwrdm: struct powerdomain * to set
  559. * @pwrst: one of the PWRDM_POWER_* macros
  560. *
  561. * Set the powerdomain pwrdm's next power state to pwrst. The powerdomain
  562. * may not enter this state immediately if the preconditions for this state
  563. * have not been satisfied. Returns -EINVAL if the powerdomain pointer is
  564. * null or if the power state is invalid for the powerdomin, or returns 0
  565. * upon success.
  566. */
  567. int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
  568. {
  569. if (!pwrdm)
  570. return -EINVAL;
  571. if (!(pwrdm->pwrsts & (1 << pwrst)))
  572. return -EINVAL;
  573. pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
  574. pwrdm->name, pwrst);
  575. prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
  576. (pwrst << OMAP_POWERSTATE_SHIFT),
  577. pwrdm->prcm_offs, PM_PWSTCTRL);
  578. return 0;
  579. }
  580. /**
  581. * pwrdm_read_next_pwrst - get next powerdomain power state
  582. * @pwrdm: struct powerdomain * to get power state
  583. *
  584. * Return the powerdomain pwrdm's next power state. Returns -EINVAL
  585. * if the powerdomain pointer is null or returns the next power state
  586. * upon success.
  587. */
  588. int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  589. {
  590. if (!pwrdm)
  591. return -EINVAL;
  592. return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
  593. OMAP_POWERSTATE_MASK);
  594. }
  595. /**
  596. * pwrdm_read_pwrst - get current powerdomain power state
  597. * @pwrdm: struct powerdomain * to get power state
  598. *
  599. * Return the powerdomain pwrdm's current power state. Returns -EINVAL
  600. * if the powerdomain pointer is null or returns the current power state
  601. * upon success.
  602. */
  603. int pwrdm_read_pwrst(struct powerdomain *pwrdm)
  604. {
  605. if (!pwrdm)
  606. return -EINVAL;
  607. return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
  608. OMAP_POWERSTATEST_MASK);
  609. }
  610. /**
  611. * pwrdm_read_prev_pwrst - get previous powerdomain power state
  612. * @pwrdm: struct powerdomain * to get previous power state
  613. *
  614. * Return the powerdomain pwrdm's previous power state. Returns -EINVAL
  615. * if the powerdomain pointer is null or returns the previous power state
  616. * upon success.
  617. */
  618. int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
  619. {
  620. if (!pwrdm)
  621. return -EINVAL;
  622. return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
  623. OMAP3430_LASTPOWERSTATEENTERED_MASK);
  624. }
  625. /**
  626. * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
  627. * @pwrdm: struct powerdomain * to set
  628. * @pwrst: one of the PWRDM_POWER_* macros
  629. *
  630. * Set the next power state that the logic portion of the powerdomain
  631. * pwrdm will enter when the powerdomain enters retention. This will
  632. * be either RETENTION or OFF, if supported. Returns -EINVAL if the
  633. * powerdomain pointer is null or the target power state is not not
  634. * supported, or returns 0 upon success.
  635. */
  636. int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
  637. {
  638. if (!pwrdm)
  639. return -EINVAL;
  640. if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
  641. return -EINVAL;
  642. pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
  643. pwrdm->name, pwrst);
  644. /*
  645. * The register bit names below may not correspond to the
  646. * actual names of the bits in each powerdomain's register,
  647. * but the type of value returned is the same for each
  648. * powerdomain.
  649. */
  650. prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE,
  651. (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)),
  652. pwrdm->prcm_offs, PM_PWSTCTRL);
  653. return 0;
  654. }
  655. /**
  656. * pwrdm_set_mem_onst - set memory power state while powerdomain ON
  657. * @pwrdm: struct powerdomain * to set
  658. * @bank: memory bank number to set (0-3)
  659. * @pwrst: one of the PWRDM_POWER_* macros
  660. *
  661. * Set the next power state that memory bank x of the powerdomain
  662. * pwrdm will enter when the powerdomain enters the ON state. Bank
  663. * will be a number from 0 to 3, and represents different types of
  664. * memory, depending on the powerdomain. Returns -EINVAL if the
  665. * powerdomain pointer is null or the target power state is not not
  666. * supported for this memory bank, -EEXIST if the target memory bank
  667. * does not exist or is not controllable, or returns 0 upon success.
  668. */
  669. int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
  670. {
  671. u32 m;
  672. if (!pwrdm)
  673. return -EINVAL;
  674. if (pwrdm->banks < (bank + 1))
  675. return -EEXIST;
  676. if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
  677. return -EINVAL;
  678. pr_debug("powerdomain: setting next memory powerstate for domain %s "
  679. "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
  680. /*
  681. * The register bit names below may not correspond to the
  682. * actual names of the bits in each powerdomain's register,
  683. * but the type of value returned is the same for each
  684. * powerdomain.
  685. */
  686. switch (bank) {
  687. case 0:
  688. m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK;
  689. break;
  690. case 1:
  691. m = OMAP3430_L1FLATMEMONSTATE_MASK;
  692. break;
  693. case 2:
  694. m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK;
  695. break;
  696. case 3:
  697. m = OMAP3430_L2FLATMEMONSTATE_MASK;
  698. break;
  699. default:
  700. WARN_ON(1); /* should never happen */
  701. return -EEXIST;
  702. }
  703. prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
  704. pwrdm->prcm_offs, PM_PWSTCTRL);
  705. return 0;
  706. }
  707. /**
  708. * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
  709. * @pwrdm: struct powerdomain * to set
  710. * @bank: memory bank number to set (0-3)
  711. * @pwrst: one of the PWRDM_POWER_* macros
  712. *
  713. * Set the next power state that memory bank x of the powerdomain
  714. * pwrdm will enter when the powerdomain enters the RETENTION state.
  715. * Bank will be a number from 0 to 3, and represents different types
  716. * of memory, depending on the powerdomain. pwrst will be either
  717. * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain
  718. * pointer is null or the target power state is not not supported for
  719. * this memory bank, -EEXIST if the target memory bank does not exist
  720. * or is not controllable, or returns 0 upon success.
  721. */
  722. int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
  723. {
  724. u32 m;
  725. if (!pwrdm)
  726. return -EINVAL;
  727. if (pwrdm->banks < (bank + 1))
  728. return -EEXIST;
  729. if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
  730. return -EINVAL;
  731. pr_debug("powerdomain: setting next memory powerstate for domain %s "
  732. "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
  733. /*
  734. * The register bit names below may not correspond to the
  735. * actual names of the bits in each powerdomain's register,
  736. * but the type of value returned is the same for each
  737. * powerdomain.
  738. */
  739. switch (bank) {
  740. case 0:
  741. m = OMAP3430_SHAREDL1CACHEFLATRETSTATE;
  742. break;
  743. case 1:
  744. m = OMAP3430_L1FLATMEMRETSTATE;
  745. break;
  746. case 2:
  747. m = OMAP3430_SHAREDL2CACHEFLATRETSTATE;
  748. break;
  749. case 3:
  750. m = OMAP3430_L2FLATMEMRETSTATE;
  751. break;
  752. default:
  753. WARN_ON(1); /* should never happen */
  754. return -EEXIST;
  755. }
  756. prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
  757. PM_PWSTCTRL);
  758. return 0;
  759. }
  760. /**
  761. * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
  762. * @pwrdm: struct powerdomain * to get current logic retention power state
  763. *
  764. * Return the current power state that the logic portion of
  765. * powerdomain pwrdm will enter
  766. * Returns -EINVAL if the powerdomain pointer is null or returns the
  767. * current logic retention power state upon success.
  768. */
  769. int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
  770. {
  771. if (!pwrdm)
  772. return -EINVAL;
  773. return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
  774. OMAP3430_LOGICSTATEST);
  775. }
  776. /**
  777. * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
  778. * @pwrdm: struct powerdomain * to get previous logic power state
  779. *
  780. * Return the powerdomain pwrdm's logic power state. Returns -EINVAL
  781. * if the powerdomain pointer is null or returns the previous logic
  782. * power state upon success.
  783. */
  784. int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
  785. {
  786. if (!pwrdm)
  787. return -EINVAL;
  788. /*
  789. * The register bit names below may not correspond to the
  790. * actual names of the bits in each powerdomain's register,
  791. * but the type of value returned is the same for each
  792. * powerdomain.
  793. */
  794. return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
  795. OMAP3430_LASTLOGICSTATEENTERED);
  796. }
  797. /**
  798. * pwrdm_read_mem_pwrst - get current memory bank power state
  799. * @pwrdm: struct powerdomain * to get current memory bank power state
  800. * @bank: memory bank number (0-3)
  801. *
  802. * Return the powerdomain pwrdm's current memory power state for bank
  803. * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
  804. * the target memory bank does not exist or is not controllable, or
  805. * returns the current memory power state upon success.
  806. */
  807. int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
  808. {
  809. u32 m;
  810. if (!pwrdm)
  811. return -EINVAL;
  812. if (pwrdm->banks < (bank + 1))
  813. return -EEXIST;
  814. if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
  815. bank = 1;
  816. /*
  817. * The register bit names below may not correspond to the
  818. * actual names of the bits in each powerdomain's register,
  819. * but the type of value returned is the same for each
  820. * powerdomain.
  821. */
  822. switch (bank) {
  823. case 0:
  824. m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK;
  825. break;
  826. case 1:
  827. m = OMAP3430_L1FLATMEMSTATEST_MASK;
  828. break;
  829. case 2:
  830. m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK;
  831. break;
  832. case 3:
  833. m = OMAP3430_L2FLATMEMSTATEST_MASK;
  834. break;
  835. default:
  836. WARN_ON(1); /* should never happen */
  837. return -EEXIST;
  838. }
  839. return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m);
  840. }
  841. /**
  842. * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
  843. * @pwrdm: struct powerdomain * to get previous memory bank power state
  844. * @bank: memory bank number (0-3)
  845. *
  846. * Return the powerdomain pwrdm's previous memory power state for bank
  847. * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
  848. * the target memory bank does not exist or is not controllable, or
  849. * returns the previous memory power state upon success.
  850. */
  851. int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
  852. {
  853. u32 m;
  854. if (!pwrdm)
  855. return -EINVAL;
  856. if (pwrdm->banks < (bank + 1))
  857. return -EEXIST;
  858. if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
  859. bank = 1;
  860. /*
  861. * The register bit names below may not correspond to the
  862. * actual names of the bits in each powerdomain's register,
  863. * but the type of value returned is the same for each
  864. * powerdomain.
  865. */
  866. switch (bank) {
  867. case 0:
  868. m = OMAP3430_LASTMEM1STATEENTERED_MASK;
  869. break;
  870. case 1:
  871. m = OMAP3430_LASTMEM2STATEENTERED_MASK;
  872. break;
  873. case 2:
  874. m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
  875. break;
  876. case 3:
  877. m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
  878. break;
  879. default:
  880. WARN_ON(1); /* should never happen */
  881. return -EEXIST;
  882. }
  883. return prm_read_mod_bits_shift(pwrdm->prcm_offs,
  884. OMAP3430_PM_PREPWSTST, m);
  885. }
  886. /**
  887. * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
  888. * @pwrdm: struct powerdomain * to clear
  889. *
  890. * Clear the powerdomain's previous power state register. Clears the
  891. * entire register, including logic and memory bank previous power states.
  892. * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon
  893. * success.
  894. */
  895. int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
  896. {
  897. if (!pwrdm)
  898. return -EINVAL;
  899. /*
  900. * XXX should get the powerdomain's current state here;
  901. * warn & fail if it is not ON.
  902. */
  903. pr_debug("powerdomain: clearing previous power state reg for %s\n",
  904. pwrdm->name);
  905. prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
  906. return 0;
  907. }
  908. /**
  909. * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
  910. * @pwrdm: struct powerdomain *
  911. *
  912. * Enable automatic context save-and-restore upon power state change
  913. * for some devices in a powerdomain. Warning: this only affects a
  914. * subset of devices in a powerdomain; check the TRM closely. Returns
  915. * -EINVAL if the powerdomain pointer is null or if the powerdomain
  916. * does not support automatic save-and-restore, or returns 0 upon
  917. * success.
  918. */
  919. int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
  920. {
  921. if (!pwrdm)
  922. return -EINVAL;
  923. if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
  924. return -EINVAL;
  925. pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
  926. pwrdm->name);
  927. prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
  928. pwrdm->prcm_offs, PM_PWSTCTRL);
  929. return 0;
  930. }
  931. /**
  932. * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
  933. * @pwrdm: struct powerdomain *
  934. *
  935. * Disable automatic context save-and-restore upon power state change
  936. * for some devices in a powerdomain. Warning: this only affects a
  937. * subset of devices in a powerdomain; check the TRM closely. Returns
  938. * -EINVAL if the powerdomain pointer is null or if the powerdomain
  939. * does not support automatic save-and-restore, or returns 0 upon
  940. * success.
  941. */
  942. int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
  943. {
  944. if (!pwrdm)
  945. return -EINVAL;
  946. if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
  947. return -EINVAL;
  948. pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
  949. pwrdm->name);
  950. prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0,
  951. pwrdm->prcm_offs, PM_PWSTCTRL);
  952. return 0;
  953. }
  954. /**
  955. * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
  956. * @pwrdm: struct powerdomain *
  957. *
  958. * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore
  959. * for some devices, or 0 if it does not.
  960. */
  961. bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
  962. {
  963. return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
  964. }
  965. /**
  966. * pwrdm_wait_transition - wait for powerdomain power transition to finish
  967. * @pwrdm: struct powerdomain * to wait for
  968. *
  969. * If the powerdomain pwrdm is in the process of a state transition,
  970. * spin until it completes the power transition, or until an iteration
  971. * bailout value is reached. Returns -EINVAL if the powerdomain
  972. * pointer is null, -EAGAIN if the bailout value was reached, or
  973. * returns 0 upon success.
  974. */
  975. int pwrdm_wait_transition(struct powerdomain *pwrdm)
  976. {
  977. u32 c = 0;
  978. if (!pwrdm)
  979. return -EINVAL;
  980. /*
  981. * REVISIT: pwrdm_wait_transition() may be better implemented
  982. * via a callback and a periodic timer check -- how long do we expect
  983. * powerdomain transitions to take?
  984. */
  985. /* XXX Is this udelay() value meaningful? */
  986. while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) &
  987. OMAP_INTRANSITION) &&
  988. (c++ < PWRDM_TRANSITION_BAILOUT))
  989. udelay(1);
  990. if (c > PWRDM_TRANSITION_BAILOUT) {
  991. printk(KERN_ERR "powerdomain: waited too long for "
  992. "powerdomain %s to complete transition\n", pwrdm->name);
  993. return -EAGAIN;
  994. }
  995. pr_debug("powerdomain: completed transition in %d loops\n", c);
  996. return 0;
  997. }
  998. int pwrdm_state_switch(struct powerdomain *pwrdm)
  999. {
  1000. return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
  1001. }
  1002. int pwrdm_clkdm_state_switch(struct clockdomain *clkdm)
  1003. {
  1004. if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) {
  1005. pwrdm_wait_transition(clkdm->pwrdm.ptr);
  1006. return pwrdm_state_switch(clkdm->pwrdm.ptr);
  1007. }
  1008. return -EINVAL;
  1009. }
  1010. int pwrdm_clk_state_switch(struct clk *clk)
  1011. {
  1012. if (clk != NULL && clk->clkdm != NULL)
  1013. return pwrdm_clkdm_state_switch(clk->clkdm);
  1014. return -EINVAL;
  1015. }
  1016. int pwrdm_pre_transition(void)
  1017. {
  1018. pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
  1019. return 0;
  1020. }
  1021. int pwrdm_post_transition(void)
  1022. {
  1023. pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
  1024. return 0;
  1025. }