powerdomains3xxx_data.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * OMAP3 powerdomain definitions
  4. *
  5. * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
  6. * Copyright (C) 2007-2011 Nokia Corporation
  7. *
  8. * Paul Walmsley, Jouni Högander
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/bug.h>
  13. #include "soc.h"
  14. #include "powerdomain.h"
  15. #include "powerdomains2xxx_3xxx_data.h"
  16. #include "prcm-common.h"
  17. #include "prm2xxx_3xxx.h"
  18. #include "prm-regbits-34xx.h"
  19. #include "cm2xxx_3xxx.h"
  20. #include "cm-regbits-34xx.h"
  21. /*
  22. * 34XX-specific powerdomains, dependencies
  23. */
  24. /*
  25. * Powerdomains
  26. */
  27. static struct powerdomain iva2_pwrdm = {
  28. .name = "iva2_pwrdm",
  29. .prcm_offs = OMAP3430_IVA2_MOD,
  30. .pwrsts = PWRSTS_OFF_RET_ON,
  31. .pwrsts_logic_ret = PWRSTS_OFF_RET,
  32. .banks = 4,
  33. .pwrsts_mem_ret = {
  34. [0] = PWRSTS_OFF_RET,
  35. [1] = PWRSTS_OFF_RET,
  36. [2] = PWRSTS_OFF_RET,
  37. [3] = PWRSTS_OFF_RET,
  38. },
  39. .pwrsts_mem_on = {
  40. [0] = PWRSTS_ON,
  41. [1] = PWRSTS_ON,
  42. [2] = PWRSTS_OFF_ON,
  43. [3] = PWRSTS_ON,
  44. },
  45. .voltdm = { .name = "mpu_iva" },
  46. };
  47. static struct powerdomain mpu_3xxx_pwrdm = {
  48. .name = "mpu_pwrdm",
  49. .prcm_offs = MPU_MOD,
  50. .pwrsts = PWRSTS_OFF_RET_ON,
  51. .pwrsts_logic_ret = PWRSTS_OFF_RET,
  52. .flags = PWRDM_HAS_MPU_QUIRK,
  53. .banks = 1,
  54. .pwrsts_mem_ret = {
  55. [0] = PWRSTS_OFF_RET,
  56. },
  57. .pwrsts_mem_on = {
  58. [0] = PWRSTS_OFF_ON,
  59. },
  60. .voltdm = { .name = "mpu_iva" },
  61. };
  62. static struct powerdomain mpu_am35x_pwrdm = {
  63. .name = "mpu_pwrdm",
  64. .prcm_offs = MPU_MOD,
  65. .pwrsts = PWRSTS_ON,
  66. .pwrsts_logic_ret = PWRSTS_ON,
  67. .flags = PWRDM_HAS_MPU_QUIRK,
  68. .banks = 1,
  69. .pwrsts_mem_ret = {
  70. [0] = PWRSTS_ON,
  71. },
  72. .pwrsts_mem_on = {
  73. [0] = PWRSTS_ON,
  74. },
  75. .voltdm = { .name = "mpu_iva" },
  76. };
  77. /*
  78. * The USBTLL Save-and-Restore mechanism is broken on
  79. * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
  80. * needs to be disabled on these chips.
  81. * Refer: 3430 errata ID i459 and 3630 errata ID i579
  82. *
  83. * Note: setting the SAR flag could help for errata ID i478
  84. * which applies to 3430 <= ES3.1, but since the SAR feature
  85. * is broken, do not use it.
  86. */
  87. static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
  88. .name = "core_pwrdm",
  89. .prcm_offs = CORE_MOD,
  90. .pwrsts = PWRSTS_OFF_RET_ON,
  91. .pwrsts_logic_ret = PWRSTS_OFF_RET,
  92. .banks = 2,
  93. .pwrsts_mem_ret = {
  94. [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
  95. [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
  96. },
  97. .pwrsts_mem_on = {
  98. [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
  99. [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
  100. },
  101. .voltdm = { .name = "core" },
  102. };
  103. static struct powerdomain core_3xxx_es3_1_pwrdm = {
  104. .name = "core_pwrdm",
  105. .prcm_offs = CORE_MOD,
  106. .pwrsts = PWRSTS_OFF_RET_ON,
  107. .pwrsts_logic_ret = PWRSTS_OFF_RET,
  108. /*
  109. * Setting the SAR flag for errata ID i478 which applies
  110. * to 3430 <= ES3.1
  111. */
  112. .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
  113. .banks = 2,
  114. .pwrsts_mem_ret = {
  115. [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
  116. [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
  117. },
  118. .pwrsts_mem_on = {
  119. [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
  120. [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
  121. },
  122. .voltdm = { .name = "core" },
  123. };
  124. static struct powerdomain core_am35x_pwrdm = {
  125. .name = "core_pwrdm",
  126. .prcm_offs = CORE_MOD,
  127. .pwrsts = PWRSTS_ON,
  128. .pwrsts_logic_ret = PWRSTS_ON,
  129. .banks = 2,
  130. .pwrsts_mem_ret = {
  131. [0] = PWRSTS_ON, /* MEM1RETSTATE */
  132. [1] = PWRSTS_ON, /* MEM2RETSTATE */
  133. },
  134. .pwrsts_mem_on = {
  135. [0] = PWRSTS_ON, /* MEM1ONSTATE */
  136. [1] = PWRSTS_ON, /* MEM2ONSTATE */
  137. },
  138. .voltdm = { .name = "core" },
  139. };
  140. static struct powerdomain dss_pwrdm = {
  141. .name = "dss_pwrdm",
  142. .prcm_offs = OMAP3430_DSS_MOD,
  143. .pwrsts = PWRSTS_OFF_RET_ON,
  144. .pwrsts_logic_ret = PWRSTS_RET,
  145. .banks = 1,
  146. .pwrsts_mem_ret = {
  147. [0] = PWRSTS_RET, /* MEMRETSTATE */
  148. },
  149. .pwrsts_mem_on = {
  150. [0] = PWRSTS_ON, /* MEMONSTATE */
  151. },
  152. .voltdm = { .name = "core" },
  153. };
  154. static struct powerdomain dss_am35x_pwrdm = {
  155. .name = "dss_pwrdm",
  156. .prcm_offs = OMAP3430_DSS_MOD,
  157. .pwrsts = PWRSTS_ON,
  158. .pwrsts_logic_ret = PWRSTS_ON,
  159. .banks = 1,
  160. .pwrsts_mem_ret = {
  161. [0] = PWRSTS_ON, /* MEMRETSTATE */
  162. },
  163. .pwrsts_mem_on = {
  164. [0] = PWRSTS_ON, /* MEMONSTATE */
  165. },
  166. .voltdm = { .name = "core" },
  167. };
  168. /*
  169. * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
  170. * possible SGX powerstate, the SGX device itself does not support
  171. * retention.
  172. */
  173. static struct powerdomain sgx_pwrdm = {
  174. .name = "sgx_pwrdm",
  175. .prcm_offs = OMAP3430ES2_SGX_MOD,
  176. /* XXX This is accurate for 3430 SGX, but what about GFX? */
  177. .pwrsts = PWRSTS_OFF_ON,
  178. .pwrsts_logic_ret = PWRSTS_RET,
  179. .banks = 1,
  180. .pwrsts_mem_ret = {
  181. [0] = PWRSTS_RET, /* MEMRETSTATE */
  182. },
  183. .pwrsts_mem_on = {
  184. [0] = PWRSTS_ON, /* MEMONSTATE */
  185. },
  186. .voltdm = { .name = "core" },
  187. };
  188. static struct powerdomain sgx_am35x_pwrdm = {
  189. .name = "sgx_pwrdm",
  190. .prcm_offs = OMAP3430ES2_SGX_MOD,
  191. .pwrsts = PWRSTS_ON,
  192. .pwrsts_logic_ret = PWRSTS_ON,
  193. .banks = 1,
  194. .pwrsts_mem_ret = {
  195. [0] = PWRSTS_ON, /* MEMRETSTATE */
  196. },
  197. .pwrsts_mem_on = {
  198. [0] = PWRSTS_ON, /* MEMONSTATE */
  199. },
  200. .voltdm = { .name = "core" },
  201. };
  202. static struct powerdomain cam_pwrdm = {
  203. .name = "cam_pwrdm",
  204. .prcm_offs = OMAP3430_CAM_MOD,
  205. .pwrsts = PWRSTS_OFF_RET_ON,
  206. .pwrsts_logic_ret = PWRSTS_RET,
  207. .banks = 1,
  208. .pwrsts_mem_ret = {
  209. [0] = PWRSTS_RET, /* MEMRETSTATE */
  210. },
  211. .pwrsts_mem_on = {
  212. [0] = PWRSTS_ON, /* MEMONSTATE */
  213. },
  214. .voltdm = { .name = "core" },
  215. };
  216. static struct powerdomain per_pwrdm = {
  217. .name = "per_pwrdm",
  218. .prcm_offs = OMAP3430_PER_MOD,
  219. .pwrsts = PWRSTS_OFF_RET_ON,
  220. .pwrsts_logic_ret = PWRSTS_OFF_RET,
  221. .banks = 1,
  222. .pwrsts_mem_ret = {
  223. [0] = PWRSTS_RET, /* MEMRETSTATE */
  224. },
  225. .pwrsts_mem_on = {
  226. [0] = PWRSTS_ON, /* MEMONSTATE */
  227. },
  228. .voltdm = { .name = "core" },
  229. };
  230. static struct powerdomain per_am35x_pwrdm = {
  231. .name = "per_pwrdm",
  232. .prcm_offs = OMAP3430_PER_MOD,
  233. .pwrsts = PWRSTS_ON,
  234. .pwrsts_logic_ret = PWRSTS_ON,
  235. .banks = 1,
  236. .pwrsts_mem_ret = {
  237. [0] = PWRSTS_ON, /* MEMRETSTATE */
  238. },
  239. .pwrsts_mem_on = {
  240. [0] = PWRSTS_ON, /* MEMONSTATE */
  241. },
  242. .voltdm = { .name = "core" },
  243. };
  244. static struct powerdomain emu_pwrdm = {
  245. .name = "emu_pwrdm",
  246. .prcm_offs = OMAP3430_EMU_MOD,
  247. .voltdm = { .name = "core" },
  248. };
  249. static struct powerdomain neon_pwrdm = {
  250. .name = "neon_pwrdm",
  251. .prcm_offs = OMAP3430_NEON_MOD,
  252. .pwrsts = PWRSTS_OFF_RET_ON,
  253. .pwrsts_logic_ret = PWRSTS_RET,
  254. .voltdm = { .name = "mpu_iva" },
  255. };
  256. static struct powerdomain neon_am35x_pwrdm = {
  257. .name = "neon_pwrdm",
  258. .prcm_offs = OMAP3430_NEON_MOD,
  259. .pwrsts = PWRSTS_ON,
  260. .pwrsts_logic_ret = PWRSTS_ON,
  261. .voltdm = { .name = "mpu_iva" },
  262. };
  263. static struct powerdomain usbhost_pwrdm = {
  264. .name = "usbhost_pwrdm",
  265. .prcm_offs = OMAP3430ES2_USBHOST_MOD,
  266. .pwrsts = PWRSTS_OFF_RET_ON,
  267. .pwrsts_logic_ret = PWRSTS_RET,
  268. /*
  269. * REVISIT: Enabling usb host save and restore mechanism seems to
  270. * leave the usb host domain permanently in ACTIVE mode after
  271. * changing the usb host power domain state from OFF to active once.
  272. * Disabling for now.
  273. */
  274. /*.flags = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
  275. .banks = 1,
  276. .pwrsts_mem_ret = {
  277. [0] = PWRSTS_RET, /* MEMRETSTATE */
  278. },
  279. .pwrsts_mem_on = {
  280. [0] = PWRSTS_ON, /* MEMONSTATE */
  281. },
  282. .voltdm = { .name = "core" },
  283. };
  284. static struct powerdomain dpll1_pwrdm = {
  285. .name = "dpll1_pwrdm",
  286. .prcm_offs = MPU_MOD,
  287. .voltdm = { .name = "mpu_iva" },
  288. };
  289. static struct powerdomain dpll2_pwrdm = {
  290. .name = "dpll2_pwrdm",
  291. .prcm_offs = OMAP3430_IVA2_MOD,
  292. .voltdm = { .name = "mpu_iva" },
  293. };
  294. static struct powerdomain dpll3_pwrdm = {
  295. .name = "dpll3_pwrdm",
  296. .prcm_offs = PLL_MOD,
  297. .voltdm = { .name = "core" },
  298. };
  299. static struct powerdomain dpll4_pwrdm = {
  300. .name = "dpll4_pwrdm",
  301. .prcm_offs = PLL_MOD,
  302. .voltdm = { .name = "core" },
  303. };
  304. static struct powerdomain dpll5_pwrdm = {
  305. .name = "dpll5_pwrdm",
  306. .prcm_offs = PLL_MOD,
  307. .voltdm = { .name = "core" },
  308. };
  309. static struct powerdomain alwon_81xx_pwrdm = {
  310. .name = "alwon_pwrdm",
  311. .prcm_offs = TI81XX_PRM_ALWON_MOD,
  312. .pwrsts = PWRSTS_OFF_ON,
  313. .voltdm = { .name = "core" },
  314. };
  315. static struct powerdomain device_81xx_pwrdm = {
  316. .name = "device_pwrdm",
  317. .prcm_offs = TI81XX_PRM_DEVICE_MOD,
  318. .voltdm = { .name = "core" },
  319. };
  320. static struct powerdomain gem_814x_pwrdm = {
  321. .name = "gem_pwrdm",
  322. .prcm_offs = TI814X_PRM_DSP_MOD,
  323. .pwrsts = PWRSTS_OFF_ON,
  324. .voltdm = { .name = "dsp" },
  325. };
  326. static struct powerdomain ivahd_814x_pwrdm = {
  327. .name = "ivahd_pwrdm",
  328. .prcm_offs = TI814X_PRM_HDVICP_MOD,
  329. .pwrsts = PWRSTS_OFF_ON,
  330. .voltdm = { .name = "iva" },
  331. };
  332. static struct powerdomain hdvpss_814x_pwrdm = {
  333. .name = "hdvpss_pwrdm",
  334. .prcm_offs = TI814X_PRM_HDVPSS_MOD,
  335. .pwrsts = PWRSTS_OFF_ON,
  336. .voltdm = { .name = "dsp" },
  337. };
  338. static struct powerdomain sgx_814x_pwrdm = {
  339. .name = "sgx_pwrdm",
  340. .prcm_offs = TI814X_PRM_GFX_MOD,
  341. .pwrsts = PWRSTS_OFF_ON,
  342. .voltdm = { .name = "core" },
  343. };
  344. static struct powerdomain isp_814x_pwrdm = {
  345. .name = "isp_pwrdm",
  346. .prcm_offs = TI814X_PRM_ISP_MOD,
  347. .pwrsts = PWRSTS_OFF_ON,
  348. .voltdm = { .name = "core" },
  349. };
  350. static struct powerdomain active_81xx_pwrdm = {
  351. .name = "active_pwrdm",
  352. .prcm_offs = TI816X_PRM_ACTIVE_MOD,
  353. .pwrsts = PWRSTS_OFF_ON,
  354. .voltdm = { .name = "core" },
  355. };
  356. static struct powerdomain default_81xx_pwrdm = {
  357. .name = "default_pwrdm",
  358. .prcm_offs = TI81XX_PRM_DEFAULT_MOD,
  359. .pwrsts = PWRSTS_OFF_ON,
  360. .voltdm = { .name = "core" },
  361. };
  362. static struct powerdomain ivahd0_816x_pwrdm = {
  363. .name = "ivahd0_pwrdm",
  364. .prcm_offs = TI816X_PRM_IVAHD0_MOD,
  365. .pwrsts = PWRSTS_OFF_ON,
  366. .voltdm = { .name = "mpu_iva" },
  367. };
  368. static struct powerdomain ivahd1_816x_pwrdm = {
  369. .name = "ivahd1_pwrdm",
  370. .prcm_offs = TI816X_PRM_IVAHD1_MOD,
  371. .pwrsts = PWRSTS_OFF_ON,
  372. .voltdm = { .name = "mpu_iva" },
  373. };
  374. static struct powerdomain ivahd2_816x_pwrdm = {
  375. .name = "ivahd2_pwrdm",
  376. .prcm_offs = TI816X_PRM_IVAHD2_MOD,
  377. .pwrsts = PWRSTS_OFF_ON,
  378. .voltdm = { .name = "mpu_iva" },
  379. };
  380. static struct powerdomain sgx_816x_pwrdm = {
  381. .name = "sgx_pwrdm",
  382. .prcm_offs = TI816X_PRM_SGX_MOD,
  383. .pwrsts = PWRSTS_OFF_ON,
  384. .voltdm = { .name = "core" },
  385. };
  386. /* As powerdomains are added or removed above, this list must also be changed */
  387. static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
  388. &wkup_omap2_pwrdm,
  389. &iva2_pwrdm,
  390. &mpu_3xxx_pwrdm,
  391. &neon_pwrdm,
  392. &cam_pwrdm,
  393. &dss_pwrdm,
  394. &per_pwrdm,
  395. &emu_pwrdm,
  396. &dpll1_pwrdm,
  397. &dpll2_pwrdm,
  398. &dpll3_pwrdm,
  399. &dpll4_pwrdm,
  400. NULL
  401. };
  402. static struct powerdomain *powerdomains_omap3430es1[] __initdata = {
  403. &gfx_omap2_pwrdm,
  404. &core_3xxx_pre_es3_1_pwrdm,
  405. NULL
  406. };
  407. /* also includes 3630ES1.0 */
  408. static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = {
  409. &core_3xxx_pre_es3_1_pwrdm,
  410. &sgx_pwrdm,
  411. &usbhost_pwrdm,
  412. &dpll5_pwrdm,
  413. NULL
  414. };
  415. /* also includes 3630ES1.1+ */
  416. static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
  417. &core_3xxx_es3_1_pwrdm,
  418. &sgx_pwrdm,
  419. &usbhost_pwrdm,
  420. &dpll5_pwrdm,
  421. NULL
  422. };
  423. static struct powerdomain *powerdomains_am35x[] __initdata = {
  424. &wkup_omap2_pwrdm,
  425. &mpu_am35x_pwrdm,
  426. &neon_am35x_pwrdm,
  427. &core_am35x_pwrdm,
  428. &sgx_am35x_pwrdm,
  429. &dss_am35x_pwrdm,
  430. &per_am35x_pwrdm,
  431. &emu_pwrdm,
  432. &dpll1_pwrdm,
  433. &dpll3_pwrdm,
  434. &dpll4_pwrdm,
  435. &dpll5_pwrdm,
  436. NULL
  437. };
  438. static struct powerdomain *powerdomains_ti814x[] __initdata = {
  439. &alwon_81xx_pwrdm,
  440. &device_81xx_pwrdm,
  441. &active_81xx_pwrdm,
  442. &default_81xx_pwrdm,
  443. &gem_814x_pwrdm,
  444. &ivahd_814x_pwrdm,
  445. &hdvpss_814x_pwrdm,
  446. &sgx_814x_pwrdm,
  447. &isp_814x_pwrdm,
  448. NULL
  449. };
  450. static struct powerdomain *powerdomains_ti816x[] __initdata = {
  451. &alwon_81xx_pwrdm,
  452. &device_81xx_pwrdm,
  453. &active_81xx_pwrdm,
  454. &default_81xx_pwrdm,
  455. &ivahd0_816x_pwrdm,
  456. &ivahd1_816x_pwrdm,
  457. &ivahd2_816x_pwrdm,
  458. &sgx_816x_pwrdm,
  459. NULL
  460. };
  461. /* TI81XX specific ops */
  462. #define TI81XX_PM_PWSTCTRL 0x0000
  463. #define TI81XX_RM_RSTCTRL 0x0010
  464. #define TI81XX_PM_PWSTST 0x0004
  465. static int ti81xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
  466. {
  467. omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
  468. (pwrst << OMAP_POWERSTATE_SHIFT),
  469. pwrdm->prcm_offs, TI81XX_PM_PWSTCTRL);
  470. return 0;
  471. }
  472. static int ti81xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  473. {
  474. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  475. TI81XX_PM_PWSTCTRL,
  476. OMAP_POWERSTATE_MASK);
  477. }
  478. static int ti81xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
  479. {
  480. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  481. (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
  482. TI81XX_PM_PWSTST,
  483. OMAP_POWERSTATEST_MASK);
  484. }
  485. static int ti81xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
  486. {
  487. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  488. (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
  489. TI81XX_PM_PWSTST,
  490. OMAP3430_LOGICSTATEST_MASK);
  491. }
  492. static int ti81xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
  493. {
  494. u32 c = 0;
  495. while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs,
  496. (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
  497. TI81XX_PM_PWSTST) &
  498. OMAP_INTRANSITION_MASK) &&
  499. (c++ < PWRDM_TRANSITION_BAILOUT))
  500. udelay(1);
  501. if (c > PWRDM_TRANSITION_BAILOUT) {
  502. pr_err("powerdomain: %s timeout waiting for transition\n",
  503. pwrdm->name);
  504. return -EAGAIN;
  505. }
  506. pr_debug("powerdomain: completed transition in %d loops\n", c);
  507. return 0;
  508. }
  509. /* For dm814x we need to fix up fix GFX pwstst and rstctrl reg offsets */
  510. static struct pwrdm_ops ti81xx_pwrdm_operations = {
  511. .pwrdm_set_next_pwrst = ti81xx_pwrdm_set_next_pwrst,
  512. .pwrdm_read_next_pwrst = ti81xx_pwrdm_read_next_pwrst,
  513. .pwrdm_read_pwrst = ti81xx_pwrdm_read_pwrst,
  514. .pwrdm_read_logic_pwrst = ti81xx_pwrdm_read_logic_pwrst,
  515. .pwrdm_wait_transition = ti81xx_pwrdm_wait_transition,
  516. };
  517. void __init omap3xxx_powerdomains_init(void)
  518. {
  519. unsigned int rev;
  520. if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
  521. return;
  522. /* Only 81xx needs custom pwrdm_operations */
  523. if (!cpu_is_ti81xx())
  524. pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
  525. rev = omap_rev();
  526. if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
  527. pwrdm_register_pwrdms(powerdomains_am35x);
  528. } else if (rev == TI8148_REV_ES1_0 || rev == TI8148_REV_ES2_0 ||
  529. rev == TI8148_REV_ES2_1) {
  530. pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
  531. pwrdm_register_pwrdms(powerdomains_ti814x);
  532. } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1
  533. || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) {
  534. pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
  535. pwrdm_register_pwrdms(powerdomains_ti816x);
  536. } else {
  537. pwrdm_register_pwrdms(powerdomains_omap3430_common);
  538. switch (rev) {
  539. case OMAP3430_REV_ES1_0:
  540. pwrdm_register_pwrdms(powerdomains_omap3430es1);
  541. break;
  542. case OMAP3430_REV_ES2_0:
  543. case OMAP3430_REV_ES2_1:
  544. case OMAP3430_REV_ES3_0:
  545. case OMAP3630_REV_ES1_0:
  546. pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
  547. break;
  548. case OMAP3430_REV_ES3_1:
  549. case OMAP3430_REV_ES3_1_2:
  550. case OMAP3630_REV_ES1_1:
  551. case OMAP3630_REV_ES1_2:
  552. pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
  553. break;
  554. default:
  555. WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
  556. }
  557. }
  558. pwrdm_complete_init();
  559. }