omap_prm.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * OMAP2+ PRM driver
  4. *
  5. * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
  6. * Tero Kristo <[email protected]>
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/clk.h>
  10. #include <linux/device.h>
  11. #include <linux/io.h>
  12. #include <linux/iopoll.h>
  13. #include <linux/module.h>
  14. #include <linux/of.h>
  15. #include <linux/of_device.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/pm_clock.h>
  18. #include <linux/pm_domain.h>
  19. #include <linux/reset-controller.h>
  20. #include <linux/delay.h>
  21. #include <linux/platform_data/ti-prm.h>
  22. enum omap_prm_domain_mode {
  23. OMAP_PRMD_OFF,
  24. OMAP_PRMD_RETENTION,
  25. OMAP_PRMD_ON_INACTIVE,
  26. OMAP_PRMD_ON_ACTIVE,
  27. };
  28. struct omap_prm_domain_map {
  29. unsigned int usable_modes; /* Mask of hardware supported modes */
  30. unsigned long statechange:1; /* Optional low-power state change */
  31. unsigned long logicretstate:1; /* Optional logic off mode */
  32. };
  33. struct omap_prm_domain {
  34. struct device *dev;
  35. struct omap_prm *prm;
  36. struct generic_pm_domain pd;
  37. u16 pwrstctrl;
  38. u16 pwrstst;
  39. const struct omap_prm_domain_map *cap;
  40. u32 pwrstctrl_saved;
  41. unsigned int uses_pm_clk:1;
  42. };
  43. struct omap_rst_map {
  44. s8 rst;
  45. s8 st;
  46. };
  47. struct omap_prm_data {
  48. u32 base;
  49. const char *name;
  50. const char *clkdm_name;
  51. u16 pwrstctrl;
  52. u16 pwrstst;
  53. const struct omap_prm_domain_map *dmap;
  54. u16 rstctrl;
  55. u16 rstst;
  56. const struct omap_rst_map *rstmap;
  57. u8 flags;
  58. };
  59. struct omap_prm {
  60. const struct omap_prm_data *data;
  61. void __iomem *base;
  62. struct omap_prm_domain *prmd;
  63. };
  64. struct omap_reset_data {
  65. struct reset_controller_dev rcdev;
  66. struct omap_prm *prm;
  67. u32 mask;
  68. spinlock_t lock;
  69. struct clockdomain *clkdm;
  70. struct device *dev;
  71. };
  72. #define genpd_to_prm_domain(gpd) container_of(gpd, struct omap_prm_domain, pd)
  73. #define to_omap_reset_data(p) container_of((p), struct omap_reset_data, rcdev)
  74. #define OMAP_MAX_RESETS 8
  75. #define OMAP_RESET_MAX_WAIT 10000
  76. #define OMAP_PRM_HAS_RSTCTRL BIT(0)
  77. #define OMAP_PRM_HAS_RSTST BIT(1)
  78. #define OMAP_PRM_HAS_NO_CLKDM BIT(2)
  79. #define OMAP_PRM_RET_WHEN_IDLE BIT(3)
  80. #define OMAP_PRM_HAS_RESETS (OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_RSTST)
  81. #define PRM_STATE_MAX_WAIT 10000
  82. #define PRM_LOGICRETSTATE BIT(2)
  83. #define PRM_LOWPOWERSTATECHANGE BIT(4)
  84. #define PRM_POWERSTATE_MASK OMAP_PRMD_ON_ACTIVE
  85. #define PRM_ST_INTRANSITION BIT(20)
  86. static const struct omap_prm_domain_map omap_prm_all = {
  87. .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) |
  88. BIT(OMAP_PRMD_RETENTION) | BIT(OMAP_PRMD_OFF),
  89. .statechange = 1,
  90. .logicretstate = 1,
  91. };
  92. static const struct omap_prm_domain_map omap_prm_noinact = {
  93. .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_RETENTION) |
  94. BIT(OMAP_PRMD_OFF),
  95. .statechange = 1,
  96. .logicretstate = 1,
  97. };
  98. static const struct omap_prm_domain_map omap_prm_nooff = {
  99. .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_ON_INACTIVE) |
  100. BIT(OMAP_PRMD_RETENTION),
  101. .statechange = 1,
  102. .logicretstate = 1,
  103. };
  104. static const struct omap_prm_domain_map omap_prm_onoff_noauto = {
  105. .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_OFF),
  106. .statechange = 1,
  107. };
  108. static const struct omap_prm_domain_map omap_prm_alwon = {
  109. .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE),
  110. };
  111. static const struct omap_prm_domain_map omap_prm_reton = {
  112. .usable_modes = BIT(OMAP_PRMD_ON_ACTIVE) | BIT(OMAP_PRMD_RETENTION),
  113. .statechange = 1,
  114. .logicretstate = 1,
  115. };
  116. static const struct omap_rst_map rst_map_0[] = {
  117. { .rst = 0, .st = 0 },
  118. { .rst = -1 },
  119. };
  120. static const struct omap_rst_map rst_map_01[] = {
  121. { .rst = 0, .st = 0 },
  122. { .rst = 1, .st = 1 },
  123. { .rst = -1 },
  124. };
  125. static const struct omap_rst_map rst_map_012[] = {
  126. { .rst = 0, .st = 0 },
  127. { .rst = 1, .st = 1 },
  128. { .rst = 2, .st = 2 },
  129. { .rst = -1 },
  130. };
  131. static const struct omap_prm_data omap4_prm_data[] = {
  132. {
  133. .name = "mpu", .base = 0x4a306300,
  134. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
  135. },
  136. {
  137. .name = "tesla", .base = 0x4a306400,
  138. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
  139. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01
  140. },
  141. {
  142. .name = "abe", .base = 0x4a306500,
  143. .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_all,
  144. },
  145. {
  146. .name = "always_on_core", .base = 0x4a306600,
  147. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  148. },
  149. {
  150. .name = "core", .base = 0x4a306700,
  151. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
  152. .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ducati",
  153. .rstmap = rst_map_012,
  154. .flags = OMAP_PRM_RET_WHEN_IDLE,
  155. },
  156. {
  157. .name = "ivahd", .base = 0x4a306f00,
  158. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
  159. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012
  160. },
  161. {
  162. .name = "cam", .base = 0x4a307000,
  163. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  164. },
  165. {
  166. .name = "dss", .base = 0x4a307100,
  167. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact
  168. },
  169. {
  170. .name = "gfx", .base = 0x4a307200,
  171. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto
  172. },
  173. {
  174. .name = "l3init", .base = 0x4a307300,
  175. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton
  176. },
  177. {
  178. .name = "l4per", .base = 0x4a307400,
  179. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
  180. .flags = OMAP_PRM_RET_WHEN_IDLE,
  181. },
  182. {
  183. .name = "cefuse", .base = 0x4a307600,
  184. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto
  185. },
  186. {
  187. .name = "wkup", .base = 0x4a307700,
  188. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon
  189. },
  190. {
  191. .name = "emu", .base = 0x4a307900,
  192. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto
  193. },
  194. {
  195. .name = "device", .base = 0x4a307b00,
  196. .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01,
  197. .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM
  198. },
  199. { },
  200. };
  201. static const struct omap_prm_data omap5_prm_data[] = {
  202. {
  203. .name = "mpu", .base = 0x4ae06300,
  204. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
  205. },
  206. {
  207. .name = "dsp", .base = 0x4ae06400,
  208. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
  209. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01
  210. },
  211. {
  212. .name = "abe", .base = 0x4ae06500,
  213. .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_nooff,
  214. },
  215. {
  216. .name = "coreaon", .base = 0x4ae06600,
  217. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon
  218. },
  219. {
  220. .name = "core", .base = 0x4ae06700,
  221. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
  222. .rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ipu",
  223. .rstmap = rst_map_012
  224. },
  225. {
  226. .name = "iva", .base = 0x4ae07200,
  227. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
  228. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012
  229. },
  230. {
  231. .name = "cam", .base = 0x4ae07300,
  232. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto
  233. },
  234. {
  235. .name = "dss", .base = 0x4ae07400,
  236. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact
  237. },
  238. {
  239. .name = "gpu", .base = 0x4ae07500,
  240. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto
  241. },
  242. {
  243. .name = "l3init", .base = 0x4ae07600,
  244. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton
  245. },
  246. {
  247. .name = "custefuse", .base = 0x4ae07700,
  248. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto
  249. },
  250. {
  251. .name = "wkupaon", .base = 0x4ae07800,
  252. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon
  253. },
  254. {
  255. .name = "emu", .base = 0x4ae07a00,
  256. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto
  257. },
  258. {
  259. .name = "device", .base = 0x4ae07c00,
  260. .rstctrl = 0x0, .rstst = 0x4, .rstmap = rst_map_01,
  261. .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM
  262. },
  263. { },
  264. };
  265. static const struct omap_prm_data dra7_prm_data[] = {
  266. {
  267. .name = "mpu", .base = 0x4ae06300,
  268. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
  269. },
  270. {
  271. .name = "dsp1", .base = 0x4ae06400,
  272. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  273. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01,
  274. },
  275. {
  276. .name = "ipu", .base = 0x4ae06500,
  277. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  278. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012,
  279. .clkdm_name = "ipu1"
  280. },
  281. {
  282. .name = "coreaon", .base = 0x4ae06628,
  283. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  284. },
  285. {
  286. .name = "core", .base = 0x4ae06700,
  287. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  288. .rstctrl = 0x210, .rstst = 0x214, .rstmap = rst_map_012,
  289. .clkdm_name = "ipu2"
  290. },
  291. {
  292. .name = "iva", .base = 0x4ae06f00,
  293. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  294. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012,
  295. },
  296. {
  297. .name = "cam", .base = 0x4ae07000,
  298. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  299. },
  300. {
  301. .name = "dss", .base = 0x4ae07100,
  302. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  303. },
  304. {
  305. .name = "gpu", .base = 0x4ae07200,
  306. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  307. },
  308. {
  309. .name = "l3init", .base = 0x4ae07300,
  310. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  311. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01,
  312. .clkdm_name = "pcie"
  313. },
  314. {
  315. .name = "l4per", .base = 0x4ae07400,
  316. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  317. },
  318. {
  319. .name = "custefuse", .base = 0x4ae07600,
  320. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  321. },
  322. {
  323. .name = "wkupaon", .base = 0x4ae07724,
  324. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  325. },
  326. {
  327. .name = "emu", .base = 0x4ae07900,
  328. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  329. },
  330. {
  331. .name = "dsp2", .base = 0x4ae07b00,
  332. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  333. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01
  334. },
  335. {
  336. .name = "eve1", .base = 0x4ae07b40,
  337. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  338. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01
  339. },
  340. {
  341. .name = "eve2", .base = 0x4ae07b80,
  342. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  343. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01
  344. },
  345. {
  346. .name = "eve3", .base = 0x4ae07bc0,
  347. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  348. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01
  349. },
  350. {
  351. .name = "eve4", .base = 0x4ae07c00,
  352. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  353. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01
  354. },
  355. {
  356. .name = "rtc", .base = 0x4ae07c60,
  357. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  358. },
  359. {
  360. .name = "vpe", .base = 0x4ae07c80,
  361. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  362. },
  363. { },
  364. };
  365. static const struct omap_rst_map am3_per_rst_map[] = {
  366. { .rst = 1 },
  367. { .rst = -1 },
  368. };
  369. static const struct omap_rst_map am3_wkup_rst_map[] = {
  370. { .rst = 3, .st = 5 },
  371. { .rst = -1 },
  372. };
  373. static const struct omap_prm_data am3_prm_data[] = {
  374. {
  375. .name = "per", .base = 0x44e00c00,
  376. .pwrstctrl = 0xc, .pwrstst = 0x8, .dmap = &omap_prm_noinact,
  377. .rstctrl = 0x0, .rstmap = am3_per_rst_map,
  378. .flags = OMAP_PRM_HAS_RSTCTRL, .clkdm_name = "pruss_ocp"
  379. },
  380. {
  381. .name = "wkup", .base = 0x44e00d00,
  382. .pwrstctrl = 0x4, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  383. .rstctrl = 0x0, .rstst = 0xc, .rstmap = am3_wkup_rst_map,
  384. .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM
  385. },
  386. {
  387. .name = "mpu", .base = 0x44e00e00,
  388. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
  389. },
  390. {
  391. .name = "device", .base = 0x44e00f00,
  392. .rstctrl = 0x0, .rstst = 0x8, .rstmap = rst_map_01,
  393. .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM
  394. },
  395. {
  396. .name = "rtc", .base = 0x44e01000,
  397. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  398. },
  399. {
  400. .name = "gfx", .base = 0x44e01100,
  401. .pwrstctrl = 0, .pwrstst = 0x10, .dmap = &omap_prm_noinact,
  402. .rstctrl = 0x4, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3",
  403. },
  404. {
  405. .name = "cefuse", .base = 0x44e01200,
  406. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  407. },
  408. { },
  409. };
  410. static const struct omap_rst_map am4_per_rst_map[] = {
  411. { .rst = 1, .st = 0 },
  412. { .rst = -1 },
  413. };
  414. static const struct omap_rst_map am4_device_rst_map[] = {
  415. { .rst = 0, .st = 1 },
  416. { .rst = 1, .st = 0 },
  417. { .rst = -1 },
  418. };
  419. static const struct omap_prm_data am4_prm_data[] = {
  420. {
  421. .name = "mpu", .base = 0x44df0300,
  422. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
  423. },
  424. {
  425. .name = "gfx", .base = 0x44df0400,
  426. .pwrstctrl = 0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  427. .rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3",
  428. },
  429. {
  430. .name = "rtc", .base = 0x44df0500,
  431. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  432. },
  433. {
  434. .name = "tamper", .base = 0x44df0600,
  435. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  436. },
  437. {
  438. .name = "cefuse", .base = 0x44df0700,
  439. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
  440. },
  441. {
  442. .name = "per", .base = 0x44df0800,
  443. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
  444. .rstctrl = 0x10, .rstst = 0x14, .rstmap = am4_per_rst_map,
  445. .clkdm_name = "pruss_ocp"
  446. },
  447. {
  448. .name = "wkup", .base = 0x44df2000,
  449. .pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
  450. .rstctrl = 0x10, .rstst = 0x14, .rstmap = am3_wkup_rst_map,
  451. .flags = OMAP_PRM_HAS_NO_CLKDM
  452. },
  453. {
  454. .name = "device", .base = 0x44df4000,
  455. .rstctrl = 0x0, .rstst = 0x4, .rstmap = am4_device_rst_map,
  456. .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM
  457. },
  458. { },
  459. };
  460. static const struct of_device_id omap_prm_id_table[] = {
  461. { .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data },
  462. { .compatible = "ti,omap5-prm-inst", .data = omap5_prm_data },
  463. { .compatible = "ti,dra7-prm-inst", .data = dra7_prm_data },
  464. { .compatible = "ti,am3-prm-inst", .data = am3_prm_data },
  465. { .compatible = "ti,am4-prm-inst", .data = am4_prm_data },
  466. { },
  467. };
  468. #ifdef DEBUG
  469. static void omap_prm_domain_show_state(struct omap_prm_domain *prmd,
  470. const char *desc)
  471. {
  472. dev_dbg(prmd->dev, "%s %s: %08x/%08x\n",
  473. prmd->pd.name, desc,
  474. readl_relaxed(prmd->prm->base + prmd->pwrstctrl),
  475. readl_relaxed(prmd->prm->base + prmd->pwrstst));
  476. }
  477. #else
  478. static inline void omap_prm_domain_show_state(struct omap_prm_domain *prmd,
  479. const char *desc)
  480. {
  481. }
  482. #endif
  483. static int omap_prm_domain_power_on(struct generic_pm_domain *domain)
  484. {
  485. struct omap_prm_domain *prmd;
  486. int ret;
  487. u32 v, mode;
  488. prmd = genpd_to_prm_domain(domain);
  489. if (!prmd->cap)
  490. return 0;
  491. omap_prm_domain_show_state(prmd, "on: previous state");
  492. if (prmd->pwrstctrl_saved)
  493. v = prmd->pwrstctrl_saved;
  494. else
  495. v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl);
  496. if (prmd->prm->data->flags & OMAP_PRM_RET_WHEN_IDLE)
  497. mode = OMAP_PRMD_RETENTION;
  498. else
  499. mode = OMAP_PRMD_ON_ACTIVE;
  500. writel_relaxed((v & ~PRM_POWERSTATE_MASK) | mode,
  501. prmd->prm->base + prmd->pwrstctrl);
  502. /* wait for the transition bit to get cleared */
  503. ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst,
  504. v, !(v & PRM_ST_INTRANSITION), 1,
  505. PRM_STATE_MAX_WAIT);
  506. if (ret)
  507. dev_err(prmd->dev, "%s: %s timed out\n",
  508. prmd->pd.name, __func__);
  509. omap_prm_domain_show_state(prmd, "on: new state");
  510. return ret;
  511. }
  512. /* No need to check for holes in the mask for the lowest mode */
  513. static int omap_prm_domain_find_lowest(struct omap_prm_domain *prmd)
  514. {
  515. return __ffs(prmd->cap->usable_modes);
  516. }
  517. static int omap_prm_domain_power_off(struct generic_pm_domain *domain)
  518. {
  519. struct omap_prm_domain *prmd;
  520. int ret;
  521. u32 v;
  522. prmd = genpd_to_prm_domain(domain);
  523. if (!prmd->cap)
  524. return 0;
  525. omap_prm_domain_show_state(prmd, "off: previous state");
  526. v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl);
  527. prmd->pwrstctrl_saved = v;
  528. v &= ~PRM_POWERSTATE_MASK;
  529. v |= omap_prm_domain_find_lowest(prmd);
  530. if (prmd->cap->statechange)
  531. v |= PRM_LOWPOWERSTATECHANGE;
  532. if (prmd->cap->logicretstate)
  533. v &= ~PRM_LOGICRETSTATE;
  534. else
  535. v |= PRM_LOGICRETSTATE;
  536. writel_relaxed(v, prmd->prm->base + prmd->pwrstctrl);
  537. /* wait for the transition bit to get cleared */
  538. ret = readl_relaxed_poll_timeout(prmd->prm->base + prmd->pwrstst,
  539. v, !(v & PRM_ST_INTRANSITION), 1,
  540. PRM_STATE_MAX_WAIT);
  541. if (ret)
  542. dev_warn(prmd->dev, "%s: %s timed out\n",
  543. __func__, prmd->pd.name);
  544. omap_prm_domain_show_state(prmd, "off: new state");
  545. return 0;
  546. }
  547. /*
  548. * Note that ti-sysc already manages the module clocks separately so
  549. * no need to manage those. Interconnect instances need clocks managed
  550. * for simple-pm-bus.
  551. */
  552. static int omap_prm_domain_attach_clock(struct device *dev,
  553. struct omap_prm_domain *prmd)
  554. {
  555. struct device_node *np = dev->of_node;
  556. int error;
  557. if (!of_device_is_compatible(np, "simple-pm-bus"))
  558. return 0;
  559. if (!of_property_read_bool(np, "clocks"))
  560. return 0;
  561. error = pm_clk_create(dev);
  562. if (error)
  563. return error;
  564. error = of_pm_clk_add_clks(dev);
  565. if (error < 0) {
  566. pm_clk_destroy(dev);
  567. return error;
  568. }
  569. prmd->uses_pm_clk = 1;
  570. return 0;
  571. }
  572. static int omap_prm_domain_attach_dev(struct generic_pm_domain *domain,
  573. struct device *dev)
  574. {
  575. struct generic_pm_domain_data *genpd_data;
  576. struct of_phandle_args pd_args;
  577. struct omap_prm_domain *prmd;
  578. struct device_node *np;
  579. int ret;
  580. prmd = genpd_to_prm_domain(domain);
  581. np = dev->of_node;
  582. ret = of_parse_phandle_with_args(np, "power-domains",
  583. "#power-domain-cells", 0, &pd_args);
  584. if (ret < 0)
  585. return ret;
  586. if (pd_args.args_count != 0)
  587. dev_warn(dev, "%s: unusupported #power-domain-cells: %i\n",
  588. prmd->pd.name, pd_args.args_count);
  589. genpd_data = dev_gpd_data(dev);
  590. genpd_data->data = NULL;
  591. ret = omap_prm_domain_attach_clock(dev, prmd);
  592. if (ret)
  593. return ret;
  594. return 0;
  595. }
  596. static void omap_prm_domain_detach_dev(struct generic_pm_domain *domain,
  597. struct device *dev)
  598. {
  599. struct generic_pm_domain_data *genpd_data;
  600. struct omap_prm_domain *prmd;
  601. prmd = genpd_to_prm_domain(domain);
  602. if (prmd->uses_pm_clk)
  603. pm_clk_destroy(dev);
  604. genpd_data = dev_gpd_data(dev);
  605. genpd_data->data = NULL;
  606. }
  607. static int omap_prm_domain_init(struct device *dev, struct omap_prm *prm)
  608. {
  609. struct omap_prm_domain *prmd;
  610. struct device_node *np = dev->of_node;
  611. const struct omap_prm_data *data;
  612. const char *name;
  613. int error;
  614. if (!of_find_property(dev->of_node, "#power-domain-cells", NULL))
  615. return 0;
  616. of_node_put(dev->of_node);
  617. prmd = devm_kzalloc(dev, sizeof(*prmd), GFP_KERNEL);
  618. if (!prmd)
  619. return -ENOMEM;
  620. data = prm->data;
  621. name = devm_kasprintf(dev, GFP_KERNEL, "prm_%s",
  622. data->name);
  623. prmd->dev = dev;
  624. prmd->prm = prm;
  625. prmd->cap = prmd->prm->data->dmap;
  626. prmd->pwrstctrl = prmd->prm->data->pwrstctrl;
  627. prmd->pwrstst = prmd->prm->data->pwrstst;
  628. prmd->pd.name = name;
  629. prmd->pd.power_on = omap_prm_domain_power_on;
  630. prmd->pd.power_off = omap_prm_domain_power_off;
  631. prmd->pd.attach_dev = omap_prm_domain_attach_dev;
  632. prmd->pd.detach_dev = omap_prm_domain_detach_dev;
  633. prmd->pd.flags = GENPD_FLAG_PM_CLK;
  634. pm_genpd_init(&prmd->pd, NULL, true);
  635. error = of_genpd_add_provider_simple(np, &prmd->pd);
  636. if (error)
  637. pm_genpd_remove(&prmd->pd);
  638. else
  639. prm->prmd = prmd;
  640. return error;
  641. }
  642. static bool _is_valid_reset(struct omap_reset_data *reset, unsigned long id)
  643. {
  644. if (reset->mask & BIT(id))
  645. return true;
  646. return false;
  647. }
  648. static int omap_reset_get_st_bit(struct omap_reset_data *reset,
  649. unsigned long id)
  650. {
  651. const struct omap_rst_map *map = reset->prm->data->rstmap;
  652. while (map->rst >= 0) {
  653. if (map->rst == id)
  654. return map->st;
  655. map++;
  656. }
  657. return id;
  658. }
  659. static int omap_reset_status(struct reset_controller_dev *rcdev,
  660. unsigned long id)
  661. {
  662. struct omap_reset_data *reset = to_omap_reset_data(rcdev);
  663. u32 v;
  664. int st_bit = omap_reset_get_st_bit(reset, id);
  665. bool has_rstst = reset->prm->data->rstst ||
  666. (reset->prm->data->flags & OMAP_PRM_HAS_RSTST);
  667. /* Check if we have rstst */
  668. if (!has_rstst)
  669. return -ENOTSUPP;
  670. /* Check if hw reset line is asserted */
  671. v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
  672. if (v & BIT(id))
  673. return 1;
  674. /*
  675. * Check reset status, high value means reset sequence has been
  676. * completed successfully so we can return 0 here (reset deasserted)
  677. */
  678. v = readl_relaxed(reset->prm->base + reset->prm->data->rstst);
  679. v >>= st_bit;
  680. v &= 1;
  681. return !v;
  682. }
  683. static int omap_reset_assert(struct reset_controller_dev *rcdev,
  684. unsigned long id)
  685. {
  686. struct omap_reset_data *reset = to_omap_reset_data(rcdev);
  687. u32 v;
  688. unsigned long flags;
  689. /* assert the reset control line */
  690. spin_lock_irqsave(&reset->lock, flags);
  691. v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
  692. v |= 1 << id;
  693. writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
  694. spin_unlock_irqrestore(&reset->lock, flags);
  695. return 0;
  696. }
  697. static int omap_reset_deassert(struct reset_controller_dev *rcdev,
  698. unsigned long id)
  699. {
  700. struct omap_reset_data *reset = to_omap_reset_data(rcdev);
  701. u32 v;
  702. int st_bit;
  703. bool has_rstst;
  704. unsigned long flags;
  705. struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev);
  706. int ret = 0;
  707. /* Nothing to do if the reset is already deasserted */
  708. if (!omap_reset_status(rcdev, id))
  709. return 0;
  710. has_rstst = reset->prm->data->rstst ||
  711. (reset->prm->data->flags & OMAP_PRM_HAS_RSTST);
  712. if (has_rstst) {
  713. st_bit = omap_reset_get_st_bit(reset, id);
  714. /* Clear the reset status by writing 1 to the status bit */
  715. v = 1 << st_bit;
  716. writel_relaxed(v, reset->prm->base + reset->prm->data->rstst);
  717. }
  718. if (reset->clkdm)
  719. pdata->clkdm_deny_idle(reset->clkdm);
  720. /* de-assert the reset control line */
  721. spin_lock_irqsave(&reset->lock, flags);
  722. v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
  723. v &= ~(1 << id);
  724. writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
  725. spin_unlock_irqrestore(&reset->lock, flags);
  726. /* wait for the reset bit to clear */
  727. ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
  728. reset->prm->data->rstctrl,
  729. v, !(v & BIT(id)), 1,
  730. OMAP_RESET_MAX_WAIT);
  731. if (ret)
  732. pr_err("%s: timedout waiting for %s:%lu\n", __func__,
  733. reset->prm->data->name, id);
  734. /* wait for the status to be set */
  735. if (has_rstst) {
  736. ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
  737. reset->prm->data->rstst,
  738. v, v & BIT(st_bit), 1,
  739. OMAP_RESET_MAX_WAIT);
  740. if (ret)
  741. pr_err("%s: timedout waiting for %s:%lu\n", __func__,
  742. reset->prm->data->name, id);
  743. }
  744. if (reset->clkdm)
  745. pdata->clkdm_allow_idle(reset->clkdm);
  746. return ret;
  747. }
  748. static const struct reset_control_ops omap_reset_ops = {
  749. .assert = omap_reset_assert,
  750. .deassert = omap_reset_deassert,
  751. .status = omap_reset_status,
  752. };
  753. static int omap_prm_reset_xlate(struct reset_controller_dev *rcdev,
  754. const struct of_phandle_args *reset_spec)
  755. {
  756. struct omap_reset_data *reset = to_omap_reset_data(rcdev);
  757. if (!_is_valid_reset(reset, reset_spec->args[0]))
  758. return -EINVAL;
  759. return reset_spec->args[0];
  760. }
  761. static int omap_prm_reset_init(struct platform_device *pdev,
  762. struct omap_prm *prm)
  763. {
  764. struct omap_reset_data *reset;
  765. const struct omap_rst_map *map;
  766. struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev);
  767. char buf[32];
  768. u32 v;
  769. /*
  770. * Check if we have controllable resets. If either rstctrl is non-zero
  771. * or OMAP_PRM_HAS_RSTCTRL flag is set, we have reset control register
  772. * for the domain.
  773. */
  774. if (!prm->data->rstctrl && !(prm->data->flags & OMAP_PRM_HAS_RSTCTRL))
  775. return 0;
  776. /* Check if we have the pdata callbacks in place */
  777. if (!pdata || !pdata->clkdm_lookup || !pdata->clkdm_deny_idle ||
  778. !pdata->clkdm_allow_idle)
  779. return -EINVAL;
  780. map = prm->data->rstmap;
  781. if (!map)
  782. return -EINVAL;
  783. reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
  784. if (!reset)
  785. return -ENOMEM;
  786. reset->rcdev.owner = THIS_MODULE;
  787. reset->rcdev.ops = &omap_reset_ops;
  788. reset->rcdev.of_node = pdev->dev.of_node;
  789. reset->rcdev.nr_resets = OMAP_MAX_RESETS;
  790. reset->rcdev.of_xlate = omap_prm_reset_xlate;
  791. reset->rcdev.of_reset_n_cells = 1;
  792. reset->dev = &pdev->dev;
  793. spin_lock_init(&reset->lock);
  794. reset->prm = prm;
  795. sprintf(buf, "%s_clkdm", prm->data->clkdm_name ? prm->data->clkdm_name :
  796. prm->data->name);
  797. if (!(prm->data->flags & OMAP_PRM_HAS_NO_CLKDM)) {
  798. reset->clkdm = pdata->clkdm_lookup(buf);
  799. if (!reset->clkdm)
  800. return -EINVAL;
  801. }
  802. while (map->rst >= 0) {
  803. reset->mask |= BIT(map->rst);
  804. map++;
  805. }
  806. /* Quirk handling to assert rst_map_012 bits on reset and avoid errors */
  807. if (prm->data->rstmap == rst_map_012) {
  808. v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
  809. if ((v & reset->mask) != reset->mask) {
  810. dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v);
  811. writel_relaxed(reset->mask, reset->prm->base +
  812. reset->prm->data->rstctrl);
  813. }
  814. }
  815. return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
  816. }
  817. static int omap_prm_probe(struct platform_device *pdev)
  818. {
  819. struct resource *res;
  820. const struct omap_prm_data *data;
  821. struct omap_prm *prm;
  822. int ret;
  823. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  824. if (!res)
  825. return -ENODEV;
  826. data = of_device_get_match_data(&pdev->dev);
  827. if (!data)
  828. return -ENOTSUPP;
  829. prm = devm_kzalloc(&pdev->dev, sizeof(*prm), GFP_KERNEL);
  830. if (!prm)
  831. return -ENOMEM;
  832. while (data->base != res->start) {
  833. if (!data->base)
  834. return -EINVAL;
  835. data++;
  836. }
  837. prm->data = data;
  838. prm->base = devm_ioremap_resource(&pdev->dev, res);
  839. if (IS_ERR(prm->base))
  840. return PTR_ERR(prm->base);
  841. ret = omap_prm_domain_init(&pdev->dev, prm);
  842. if (ret)
  843. return ret;
  844. ret = omap_prm_reset_init(pdev, prm);
  845. if (ret)
  846. goto err_domain;
  847. return 0;
  848. err_domain:
  849. of_genpd_del_provider(pdev->dev.of_node);
  850. pm_genpd_remove(&prm->prmd->pd);
  851. return ret;
  852. }
  853. static struct platform_driver omap_prm_driver = {
  854. .probe = omap_prm_probe,
  855. .driver = {
  856. .name = KBUILD_MODNAME,
  857. .of_match_table = omap_prm_id_table,
  858. },
  859. };
  860. builtin_platform_driver(omap_prm_driver);