gpcv2.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2017 Impinj, Inc
  4. * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
  5. *
  6. * Based on the code of analogus driver:
  7. *
  8. * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
  9. */
  10. #include <linux/clk.h>
  11. #include <linux/of.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/pm_domain.h>
  14. #include <linux/pm_runtime.h>
  15. #include <linux/regmap.h>
  16. #include <linux/regulator/consumer.h>
  17. #include <linux/reset.h>
  18. #include <linux/sizes.h>
  19. #include <dt-bindings/power/imx7-power.h>
  20. #include <dt-bindings/power/imx8mq-power.h>
  21. #include <dt-bindings/power/imx8mm-power.h>
  22. #include <dt-bindings/power/imx8mn-power.h>
  23. #include <dt-bindings/power/imx8mp-power.h>
  24. #define GPC_LPCR_A_CORE_BSC 0x000
  25. #define GPC_PGC_CPU_MAPPING 0x0ec
  26. #define IMX8MP_GPC_PGC_CPU_MAPPING 0x1cc
  27. #define IMX7_USB_HSIC_PHY_A_CORE_DOMAIN BIT(6)
  28. #define IMX7_USB_OTG2_PHY_A_CORE_DOMAIN BIT(5)
  29. #define IMX7_USB_OTG1_PHY_A_CORE_DOMAIN BIT(4)
  30. #define IMX7_PCIE_PHY_A_CORE_DOMAIN BIT(3)
  31. #define IMX7_MIPI_PHY_A_CORE_DOMAIN BIT(2)
  32. #define IMX8M_PCIE2_A53_DOMAIN BIT(15)
  33. #define IMX8M_MIPI_CSI2_A53_DOMAIN BIT(14)
  34. #define IMX8M_MIPI_CSI1_A53_DOMAIN BIT(13)
  35. #define IMX8M_DISP_A53_DOMAIN BIT(12)
  36. #define IMX8M_HDMI_A53_DOMAIN BIT(11)
  37. #define IMX8M_VPU_A53_DOMAIN BIT(10)
  38. #define IMX8M_GPU_A53_DOMAIN BIT(9)
  39. #define IMX8M_DDR2_A53_DOMAIN BIT(8)
  40. #define IMX8M_DDR1_A53_DOMAIN BIT(7)
  41. #define IMX8M_OTG2_A53_DOMAIN BIT(5)
  42. #define IMX8M_OTG1_A53_DOMAIN BIT(4)
  43. #define IMX8M_PCIE1_A53_DOMAIN BIT(3)
  44. #define IMX8M_MIPI_A53_DOMAIN BIT(2)
  45. #define IMX8MM_VPUH1_A53_DOMAIN BIT(15)
  46. #define IMX8MM_VPUG2_A53_DOMAIN BIT(14)
  47. #define IMX8MM_VPUG1_A53_DOMAIN BIT(13)
  48. #define IMX8MM_DISPMIX_A53_DOMAIN BIT(12)
  49. #define IMX8MM_VPUMIX_A53_DOMAIN BIT(10)
  50. #define IMX8MM_GPUMIX_A53_DOMAIN BIT(9)
  51. #define IMX8MM_GPU_A53_DOMAIN (BIT(8) | BIT(11))
  52. #define IMX8MM_DDR1_A53_DOMAIN BIT(7)
  53. #define IMX8MM_OTG2_A53_DOMAIN BIT(5)
  54. #define IMX8MM_OTG1_A53_DOMAIN BIT(4)
  55. #define IMX8MM_PCIE_A53_DOMAIN BIT(3)
  56. #define IMX8MM_MIPI_A53_DOMAIN BIT(2)
  57. #define IMX8MN_DISPMIX_A53_DOMAIN BIT(12)
  58. #define IMX8MN_GPUMIX_A53_DOMAIN BIT(9)
  59. #define IMX8MN_DDR1_A53_DOMAIN BIT(7)
  60. #define IMX8MN_OTG1_A53_DOMAIN BIT(4)
  61. #define IMX8MN_MIPI_A53_DOMAIN BIT(2)
  62. #define IMX8MP_MEDIA_ISPDWP_A53_DOMAIN BIT(20)
  63. #define IMX8MP_HSIOMIX_A53_DOMAIN BIT(19)
  64. #define IMX8MP_MIPI_PHY2_A53_DOMAIN BIT(18)
  65. #define IMX8MP_HDMI_PHY_A53_DOMAIN BIT(17)
  66. #define IMX8MP_HDMIMIX_A53_DOMAIN BIT(16)
  67. #define IMX8MP_VPU_VC8000E_A53_DOMAIN BIT(15)
  68. #define IMX8MP_VPU_G2_A53_DOMAIN BIT(14)
  69. #define IMX8MP_VPU_G1_A53_DOMAIN BIT(13)
  70. #define IMX8MP_MEDIAMIX_A53_DOMAIN BIT(12)
  71. #define IMX8MP_GPU3D_A53_DOMAIN BIT(11)
  72. #define IMX8MP_VPUMIX_A53_DOMAIN BIT(10)
  73. #define IMX8MP_GPUMIX_A53_DOMAIN BIT(9)
  74. #define IMX8MP_GPU2D_A53_DOMAIN BIT(8)
  75. #define IMX8MP_AUDIOMIX_A53_DOMAIN BIT(7)
  76. #define IMX8MP_MLMIX_A53_DOMAIN BIT(6)
  77. #define IMX8MP_USB2_PHY_A53_DOMAIN BIT(5)
  78. #define IMX8MP_USB1_PHY_A53_DOMAIN BIT(4)
  79. #define IMX8MP_PCIE_PHY_A53_DOMAIN BIT(3)
  80. #define IMX8MP_MIPI_PHY1_A53_DOMAIN BIT(2)
  81. #define IMX8MP_GPC_PU_PGC_SW_PUP_REQ 0x0d8
  82. #define IMX8MP_GPC_PU_PGC_SW_PDN_REQ 0x0e4
  83. #define GPC_PU_PGC_SW_PUP_REQ 0x0f8
  84. #define GPC_PU_PGC_SW_PDN_REQ 0x104
  85. #define IMX7_USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
  86. #define IMX7_USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
  87. #define IMX7_USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
  88. #define IMX7_PCIE_PHY_SW_Pxx_REQ BIT(1)
  89. #define IMX7_MIPI_PHY_SW_Pxx_REQ BIT(0)
  90. #define IMX8M_PCIE2_SW_Pxx_REQ BIT(13)
  91. #define IMX8M_MIPI_CSI2_SW_Pxx_REQ BIT(12)
  92. #define IMX8M_MIPI_CSI1_SW_Pxx_REQ BIT(11)
  93. #define IMX8M_DISP_SW_Pxx_REQ BIT(10)
  94. #define IMX8M_HDMI_SW_Pxx_REQ BIT(9)
  95. #define IMX8M_VPU_SW_Pxx_REQ BIT(8)
  96. #define IMX8M_GPU_SW_Pxx_REQ BIT(7)
  97. #define IMX8M_DDR2_SW_Pxx_REQ BIT(6)
  98. #define IMX8M_DDR1_SW_Pxx_REQ BIT(5)
  99. #define IMX8M_OTG2_SW_Pxx_REQ BIT(3)
  100. #define IMX8M_OTG1_SW_Pxx_REQ BIT(2)
  101. #define IMX8M_PCIE1_SW_Pxx_REQ BIT(1)
  102. #define IMX8M_MIPI_SW_Pxx_REQ BIT(0)
  103. #define IMX8MM_VPUH1_SW_Pxx_REQ BIT(13)
  104. #define IMX8MM_VPUG2_SW_Pxx_REQ BIT(12)
  105. #define IMX8MM_VPUG1_SW_Pxx_REQ BIT(11)
  106. #define IMX8MM_DISPMIX_SW_Pxx_REQ BIT(10)
  107. #define IMX8MM_VPUMIX_SW_Pxx_REQ BIT(8)
  108. #define IMX8MM_GPUMIX_SW_Pxx_REQ BIT(7)
  109. #define IMX8MM_GPU_SW_Pxx_REQ (BIT(6) | BIT(9))
  110. #define IMX8MM_DDR1_SW_Pxx_REQ BIT(5)
  111. #define IMX8MM_OTG2_SW_Pxx_REQ BIT(3)
  112. #define IMX8MM_OTG1_SW_Pxx_REQ BIT(2)
  113. #define IMX8MM_PCIE_SW_Pxx_REQ BIT(1)
  114. #define IMX8MM_MIPI_SW_Pxx_REQ BIT(0)
  115. #define IMX8MN_DISPMIX_SW_Pxx_REQ BIT(10)
  116. #define IMX8MN_GPUMIX_SW_Pxx_REQ BIT(7)
  117. #define IMX8MN_DDR1_SW_Pxx_REQ BIT(5)
  118. #define IMX8MN_OTG1_SW_Pxx_REQ BIT(2)
  119. #define IMX8MN_MIPI_SW_Pxx_REQ BIT(0)
  120. #define IMX8MP_DDRMIX_Pxx_REQ BIT(19)
  121. #define IMX8MP_MEDIA_ISP_DWP_Pxx_REQ BIT(18)
  122. #define IMX8MP_HSIOMIX_Pxx_REQ BIT(17)
  123. #define IMX8MP_MIPI_PHY2_Pxx_REQ BIT(16)
  124. #define IMX8MP_HDMI_PHY_Pxx_REQ BIT(15)
  125. #define IMX8MP_HDMIMIX_Pxx_REQ BIT(14)
  126. #define IMX8MP_VPU_VC8K_Pxx_REQ BIT(13)
  127. #define IMX8MP_VPU_G2_Pxx_REQ BIT(12)
  128. #define IMX8MP_VPU_G1_Pxx_REQ BIT(11)
  129. #define IMX8MP_MEDIMIX_Pxx_REQ BIT(10)
  130. #define IMX8MP_GPU_3D_Pxx_REQ BIT(9)
  131. #define IMX8MP_VPU_MIX_SHARE_LOGIC_Pxx_REQ BIT(8)
  132. #define IMX8MP_GPU_SHARE_LOGIC_Pxx_REQ BIT(7)
  133. #define IMX8MP_GPU_2D_Pxx_REQ BIT(6)
  134. #define IMX8MP_AUDIOMIX_Pxx_REQ BIT(5)
  135. #define IMX8MP_MLMIX_Pxx_REQ BIT(4)
  136. #define IMX8MP_USB2_PHY_Pxx_REQ BIT(3)
  137. #define IMX8MP_USB1_PHY_Pxx_REQ BIT(2)
  138. #define IMX8MP_PCIE_PHY_SW_Pxx_REQ BIT(1)
  139. #define IMX8MP_MIPI_PHY1_SW_Pxx_REQ BIT(0)
  140. #define GPC_M4_PU_PDN_FLG 0x1bc
  141. #define IMX8MP_GPC_PU_PWRHSK 0x190
  142. #define GPC_PU_PWRHSK 0x1fc
  143. #define IMX8M_GPU_HSK_PWRDNACKN BIT(26)
  144. #define IMX8M_VPU_HSK_PWRDNACKN BIT(25)
  145. #define IMX8M_DISP_HSK_PWRDNACKN BIT(24)
  146. #define IMX8M_GPU_HSK_PWRDNREQN BIT(6)
  147. #define IMX8M_VPU_HSK_PWRDNREQN BIT(5)
  148. #define IMX8M_DISP_HSK_PWRDNREQN BIT(4)
  149. #define IMX8MM_GPUMIX_HSK_PWRDNACKN BIT(29)
  150. #define IMX8MM_GPU_HSK_PWRDNACKN (BIT(27) | BIT(28))
  151. #define IMX8MM_VPUMIX_HSK_PWRDNACKN BIT(26)
  152. #define IMX8MM_DISPMIX_HSK_PWRDNACKN BIT(25)
  153. #define IMX8MM_HSIO_HSK_PWRDNACKN (BIT(23) | BIT(24))
  154. #define IMX8MM_GPUMIX_HSK_PWRDNREQN BIT(11)
  155. #define IMX8MM_GPU_HSK_PWRDNREQN (BIT(9) | BIT(10))
  156. #define IMX8MM_VPUMIX_HSK_PWRDNREQN BIT(8)
  157. #define IMX8MM_DISPMIX_HSK_PWRDNREQN BIT(7)
  158. #define IMX8MM_HSIO_HSK_PWRDNREQN (BIT(5) | BIT(6))
  159. #define IMX8MN_GPUMIX_HSK_PWRDNACKN (BIT(29) | BIT(27))
  160. #define IMX8MN_DISPMIX_HSK_PWRDNACKN BIT(25)
  161. #define IMX8MN_HSIO_HSK_PWRDNACKN BIT(23)
  162. #define IMX8MN_GPUMIX_HSK_PWRDNREQN (BIT(11) | BIT(9))
  163. #define IMX8MN_DISPMIX_HSK_PWRDNREQN BIT(7)
  164. #define IMX8MN_HSIO_HSK_PWRDNREQN BIT(5)
  165. #define IMX8MP_MEDIAMIX_PWRDNACKN BIT(30)
  166. #define IMX8MP_HDMIMIX_PWRDNACKN BIT(29)
  167. #define IMX8MP_HSIOMIX_PWRDNACKN BIT(28)
  168. #define IMX8MP_VPUMIX_PWRDNACKN BIT(26)
  169. #define IMX8MP_GPUMIX_PWRDNACKN BIT(25)
  170. #define IMX8MP_MLMIX_PWRDNACKN (BIT(23) | BIT(24))
  171. #define IMX8MP_AUDIOMIX_PWRDNACKN (BIT(20) | BIT(31))
  172. #define IMX8MP_MEDIAMIX_PWRDNREQN BIT(14)
  173. #define IMX8MP_HDMIMIX_PWRDNREQN BIT(13)
  174. #define IMX8MP_HSIOMIX_PWRDNREQN BIT(12)
  175. #define IMX8MP_VPUMIX_PWRDNREQN BIT(10)
  176. #define IMX8MP_GPUMIX_PWRDNREQN BIT(9)
  177. #define IMX8MP_MLMIX_PWRDNREQN (BIT(7) | BIT(8))
  178. #define IMX8MP_AUDIOMIX_PWRDNREQN (BIT(4) | BIT(15))
  179. /*
  180. * The PGC offset values in Reference Manual
  181. * (Rev. 1, 01/2018 and the older ones) GPC chapter's
  182. * GPC_PGC memory map are incorrect, below offset
  183. * values are from design RTL.
  184. */
  185. #define IMX7_PGC_MIPI 16
  186. #define IMX7_PGC_PCIE 17
  187. #define IMX7_PGC_USB_HSIC 20
  188. #define IMX8M_PGC_MIPI 16
  189. #define IMX8M_PGC_PCIE1 17
  190. #define IMX8M_PGC_OTG1 18
  191. #define IMX8M_PGC_OTG2 19
  192. #define IMX8M_PGC_DDR1 21
  193. #define IMX8M_PGC_GPU 23
  194. #define IMX8M_PGC_VPU 24
  195. #define IMX8M_PGC_DISP 26
  196. #define IMX8M_PGC_MIPI_CSI1 27
  197. #define IMX8M_PGC_MIPI_CSI2 28
  198. #define IMX8M_PGC_PCIE2 29
  199. #define IMX8MM_PGC_MIPI 16
  200. #define IMX8MM_PGC_PCIE 17
  201. #define IMX8MM_PGC_OTG1 18
  202. #define IMX8MM_PGC_OTG2 19
  203. #define IMX8MM_PGC_DDR1 21
  204. #define IMX8MM_PGC_GPU2D 22
  205. #define IMX8MM_PGC_GPUMIX 23
  206. #define IMX8MM_PGC_VPUMIX 24
  207. #define IMX8MM_PGC_GPU3D 25
  208. #define IMX8MM_PGC_DISPMIX 26
  209. #define IMX8MM_PGC_VPUG1 27
  210. #define IMX8MM_PGC_VPUG2 28
  211. #define IMX8MM_PGC_VPUH1 29
  212. #define IMX8MN_PGC_MIPI 16
  213. #define IMX8MN_PGC_OTG1 18
  214. #define IMX8MN_PGC_DDR1 21
  215. #define IMX8MN_PGC_GPUMIX 23
  216. #define IMX8MN_PGC_DISPMIX 26
  217. #define IMX8MP_PGC_NOC 9
  218. #define IMX8MP_PGC_MIPI1 12
  219. #define IMX8MP_PGC_PCIE 13
  220. #define IMX8MP_PGC_USB1 14
  221. #define IMX8MP_PGC_USB2 15
  222. #define IMX8MP_PGC_MLMIX 16
  223. #define IMX8MP_PGC_AUDIOMIX 17
  224. #define IMX8MP_PGC_GPU2D 18
  225. #define IMX8MP_PGC_GPUMIX 19
  226. #define IMX8MP_PGC_VPUMIX 20
  227. #define IMX8MP_PGC_GPU3D 21
  228. #define IMX8MP_PGC_MEDIAMIX 22
  229. #define IMX8MP_PGC_VPU_G1 23
  230. #define IMX8MP_PGC_VPU_G2 24
  231. #define IMX8MP_PGC_VPU_VC8000E 25
  232. #define IMX8MP_PGC_HDMIMIX 26
  233. #define IMX8MP_PGC_HDMI 27
  234. #define IMX8MP_PGC_MIPI2 28
  235. #define IMX8MP_PGC_HSIOMIX 29
  236. #define IMX8MP_PGC_MEDIA_ISP_DWP 30
  237. #define IMX8MP_PGC_DDRMIX 31
  238. #define GPC_PGC_CTRL(n) (0x800 + (n) * 0x40)
  239. #define GPC_PGC_SR(n) (GPC_PGC_CTRL(n) + 0xc)
  240. #define GPC_PGC_CTRL_PCR BIT(0)
  241. struct imx_pgc_regs {
  242. u16 map;
  243. u16 pup;
  244. u16 pdn;
  245. u16 hsk;
  246. };
  247. struct imx_pgc_domain {
  248. struct generic_pm_domain genpd;
  249. struct regmap *regmap;
  250. const struct imx_pgc_regs *regs;
  251. struct regulator *regulator;
  252. struct reset_control *reset;
  253. struct clk_bulk_data *clks;
  254. int num_clks;
  255. unsigned long pgc;
  256. const struct {
  257. u32 pxx;
  258. u32 map;
  259. u32 hskreq;
  260. u32 hskack;
  261. } bits;
  262. const int voltage;
  263. const bool keep_clocks;
  264. struct device *dev;
  265. unsigned int pgc_sw_pup_reg;
  266. unsigned int pgc_sw_pdn_reg;
  267. };
  268. struct imx_pgc_domain_data {
  269. const struct imx_pgc_domain *domains;
  270. size_t domains_num;
  271. const struct regmap_access_table *reg_access_table;
  272. const struct imx_pgc_regs *pgc_regs;
  273. };
  274. static inline struct imx_pgc_domain *
  275. to_imx_pgc_domain(struct generic_pm_domain *genpd)
  276. {
  277. return container_of(genpd, struct imx_pgc_domain, genpd);
  278. }
  279. static int imx_pgc_power_up(struct generic_pm_domain *genpd)
  280. {
  281. struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd);
  282. u32 reg_val, pgc;
  283. int ret;
  284. ret = pm_runtime_get_sync(domain->dev);
  285. if (ret < 0) {
  286. pm_runtime_put_noidle(domain->dev);
  287. return ret;
  288. }
  289. if (!IS_ERR(domain->regulator)) {
  290. ret = regulator_enable(domain->regulator);
  291. if (ret) {
  292. dev_err(domain->dev,
  293. "failed to enable regulator: %pe\n",
  294. ERR_PTR(ret));
  295. goto out_put_pm;
  296. }
  297. }
  298. reset_control_assert(domain->reset);
  299. /* Enable reset clocks for all devices in the domain */
  300. ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
  301. if (ret) {
  302. dev_err(domain->dev, "failed to enable reset clocks\n");
  303. goto out_regulator_disable;
  304. }
  305. /* delays for reset to propagate */
  306. udelay(5);
  307. if (domain->bits.pxx) {
  308. /* request the domain to power up */
  309. regmap_update_bits(domain->regmap, domain->regs->pup,
  310. domain->bits.pxx, domain->bits.pxx);
  311. /*
  312. * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
  313. * for PUP_REQ/PDN_REQ bit to be cleared
  314. */
  315. ret = regmap_read_poll_timeout(domain->regmap,
  316. domain->regs->pup, reg_val,
  317. !(reg_val & domain->bits.pxx),
  318. 0, USEC_PER_MSEC);
  319. if (ret) {
  320. dev_err(domain->dev, "failed to command PGC\n");
  321. goto out_clk_disable;
  322. }
  323. /* disable power control */
  324. for_each_set_bit(pgc, &domain->pgc, 32) {
  325. regmap_clear_bits(domain->regmap, GPC_PGC_CTRL(pgc),
  326. GPC_PGC_CTRL_PCR);
  327. }
  328. }
  329. /* delay for reset to propagate */
  330. udelay(5);
  331. reset_control_deassert(domain->reset);
  332. /* request the ADB400 to power up */
  333. if (domain->bits.hskreq) {
  334. regmap_update_bits(domain->regmap, domain->regs->hsk,
  335. domain->bits.hskreq, domain->bits.hskreq);
  336. /*
  337. * ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk, reg_val,
  338. * (reg_val & domain->bits.hskack), 0,
  339. * USEC_PER_MSEC);
  340. * Technically we need the commented code to wait handshake. But that needs
  341. * the BLK-CTL module BUS clk-en bit being set.
  342. *
  343. * There is a separate BLK-CTL module and we will have such a driver for it,
  344. * that driver will set the BUS clk-en bit and handshake will be triggered
  345. * automatically there. Just add a delay and suppose the handshake finish
  346. * after that.
  347. */
  348. /*
  349. * For some BLK-CTL module (eg. AudioMix on i.MX8MP) doesn't have BUS
  350. * clk-en bit, it is better to add delay here, as the BLK-CTL module
  351. * doesn't need to care about how it is powered up.
  352. *
  353. * regmap_read_bypassed() is to make sure the above write IO transaction
  354. * already reaches target before udelay()
  355. */
  356. regmap_read_bypassed(domain->regmap, domain->regs->hsk, &reg_val);
  357. udelay(10);
  358. }
  359. /* Disable reset clocks for all devices in the domain */
  360. if (!domain->keep_clocks)
  361. clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
  362. return 0;
  363. out_clk_disable:
  364. clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
  365. out_regulator_disable:
  366. if (!IS_ERR(domain->regulator))
  367. regulator_disable(domain->regulator);
  368. out_put_pm:
  369. pm_runtime_put(domain->dev);
  370. return ret;
  371. }
  372. static int imx_pgc_power_down(struct generic_pm_domain *genpd)
  373. {
  374. struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd);
  375. u32 reg_val, pgc;
  376. int ret;
  377. /* Enable reset clocks for all devices in the domain */
  378. if (!domain->keep_clocks) {
  379. ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
  380. if (ret) {
  381. dev_err(domain->dev, "failed to enable reset clocks\n");
  382. return ret;
  383. }
  384. }
  385. /* request the ADB400 to power down */
  386. if (domain->bits.hskreq) {
  387. regmap_clear_bits(domain->regmap, domain->regs->hsk,
  388. domain->bits.hskreq);
  389. ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk,
  390. reg_val,
  391. !(reg_val & domain->bits.hskack),
  392. 0, USEC_PER_MSEC);
  393. if (ret) {
  394. dev_err(domain->dev, "failed to power down ADB400\n");
  395. goto out_clk_disable;
  396. }
  397. }
  398. if (domain->bits.pxx) {
  399. /* enable power control */
  400. for_each_set_bit(pgc, &domain->pgc, 32) {
  401. regmap_update_bits(domain->regmap, GPC_PGC_CTRL(pgc),
  402. GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
  403. }
  404. /* request the domain to power down */
  405. regmap_update_bits(domain->regmap, domain->regs->pdn,
  406. domain->bits.pxx, domain->bits.pxx);
  407. /*
  408. * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
  409. * for PUP_REQ/PDN_REQ bit to be cleared
  410. */
  411. ret = regmap_read_poll_timeout(domain->regmap,
  412. domain->regs->pdn, reg_val,
  413. !(reg_val & domain->bits.pxx),
  414. 0, USEC_PER_MSEC);
  415. if (ret) {
  416. dev_err(domain->dev, "failed to command PGC\n");
  417. goto out_clk_disable;
  418. }
  419. }
  420. /* Disable reset clocks for all devices in the domain */
  421. clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
  422. if (!IS_ERR(domain->regulator)) {
  423. ret = regulator_disable(domain->regulator);
  424. if (ret) {
  425. dev_err(domain->dev,
  426. "failed to disable regulator: %pe\n",
  427. ERR_PTR(ret));
  428. return ret;
  429. }
  430. }
  431. pm_runtime_put_sync_suspend(domain->dev);
  432. return 0;
  433. out_clk_disable:
  434. if (!domain->keep_clocks)
  435. clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
  436. return ret;
  437. }
  438. static const struct imx_pgc_domain imx7_pgc_domains[] = {
  439. [IMX7_POWER_DOMAIN_MIPI_PHY] = {
  440. .genpd = {
  441. .name = "mipi-phy",
  442. },
  443. .bits = {
  444. .pxx = IMX7_MIPI_PHY_SW_Pxx_REQ,
  445. .map = IMX7_MIPI_PHY_A_CORE_DOMAIN,
  446. },
  447. .voltage = 1000000,
  448. .pgc = BIT(IMX7_PGC_MIPI),
  449. },
  450. [IMX7_POWER_DOMAIN_PCIE_PHY] = {
  451. .genpd = {
  452. .name = "pcie-phy",
  453. },
  454. .bits = {
  455. .pxx = IMX7_PCIE_PHY_SW_Pxx_REQ,
  456. .map = IMX7_PCIE_PHY_A_CORE_DOMAIN,
  457. },
  458. .voltage = 1000000,
  459. .pgc = BIT(IMX7_PGC_PCIE),
  460. },
  461. [IMX7_POWER_DOMAIN_USB_HSIC_PHY] = {
  462. .genpd = {
  463. .name = "usb-hsic-phy",
  464. },
  465. .bits = {
  466. .pxx = IMX7_USB_HSIC_PHY_SW_Pxx_REQ,
  467. .map = IMX7_USB_HSIC_PHY_A_CORE_DOMAIN,
  468. },
  469. .voltage = 1200000,
  470. .pgc = BIT(IMX7_PGC_USB_HSIC),
  471. },
  472. };
  473. static const struct regmap_range imx7_yes_ranges[] = {
  474. regmap_reg_range(GPC_LPCR_A_CORE_BSC,
  475. GPC_M4_PU_PDN_FLG),
  476. regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_MIPI),
  477. GPC_PGC_SR(IMX7_PGC_MIPI)),
  478. regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_PCIE),
  479. GPC_PGC_SR(IMX7_PGC_PCIE)),
  480. regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_USB_HSIC),
  481. GPC_PGC_SR(IMX7_PGC_USB_HSIC)),
  482. };
  483. static const struct regmap_access_table imx7_access_table = {
  484. .yes_ranges = imx7_yes_ranges,
  485. .n_yes_ranges = ARRAY_SIZE(imx7_yes_ranges),
  486. };
  487. static const struct imx_pgc_regs imx7_pgc_regs = {
  488. .map = GPC_PGC_CPU_MAPPING,
  489. .pup = GPC_PU_PGC_SW_PUP_REQ,
  490. .pdn = GPC_PU_PGC_SW_PDN_REQ,
  491. .hsk = GPC_PU_PWRHSK,
  492. };
  493. static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
  494. .domains = imx7_pgc_domains,
  495. .domains_num = ARRAY_SIZE(imx7_pgc_domains),
  496. .reg_access_table = &imx7_access_table,
  497. .pgc_regs = &imx7_pgc_regs,
  498. };
  499. static const struct imx_pgc_domain imx8m_pgc_domains[] = {
  500. [IMX8M_POWER_DOMAIN_MIPI] = {
  501. .genpd = {
  502. .name = "mipi",
  503. },
  504. .bits = {
  505. .pxx = IMX8M_MIPI_SW_Pxx_REQ,
  506. .map = IMX8M_MIPI_A53_DOMAIN,
  507. },
  508. .pgc = BIT(IMX8M_PGC_MIPI),
  509. },
  510. [IMX8M_POWER_DOMAIN_PCIE1] = {
  511. .genpd = {
  512. .name = "pcie1",
  513. },
  514. .bits = {
  515. .pxx = IMX8M_PCIE1_SW_Pxx_REQ,
  516. .map = IMX8M_PCIE1_A53_DOMAIN,
  517. },
  518. .pgc = BIT(IMX8M_PGC_PCIE1),
  519. },
  520. [IMX8M_POWER_DOMAIN_USB_OTG1] = {
  521. .genpd = {
  522. .name = "usb-otg1",
  523. },
  524. .bits = {
  525. .pxx = IMX8M_OTG1_SW_Pxx_REQ,
  526. .map = IMX8M_OTG1_A53_DOMAIN,
  527. },
  528. .pgc = BIT(IMX8M_PGC_OTG1),
  529. },
  530. [IMX8M_POWER_DOMAIN_USB_OTG2] = {
  531. .genpd = {
  532. .name = "usb-otg2",
  533. },
  534. .bits = {
  535. .pxx = IMX8M_OTG2_SW_Pxx_REQ,
  536. .map = IMX8M_OTG2_A53_DOMAIN,
  537. },
  538. .pgc = BIT(IMX8M_PGC_OTG2),
  539. },
  540. [IMX8M_POWER_DOMAIN_DDR1] = {
  541. .genpd = {
  542. .name = "ddr1",
  543. },
  544. .bits = {
  545. .pxx = IMX8M_DDR1_SW_Pxx_REQ,
  546. .map = IMX8M_DDR2_A53_DOMAIN,
  547. },
  548. .pgc = BIT(IMX8M_PGC_DDR1),
  549. },
  550. [IMX8M_POWER_DOMAIN_GPU] = {
  551. .genpd = {
  552. .name = "gpu",
  553. },
  554. .bits = {
  555. .pxx = IMX8M_GPU_SW_Pxx_REQ,
  556. .map = IMX8M_GPU_A53_DOMAIN,
  557. .hskreq = IMX8M_GPU_HSK_PWRDNREQN,
  558. .hskack = IMX8M_GPU_HSK_PWRDNACKN,
  559. },
  560. .pgc = BIT(IMX8M_PGC_GPU),
  561. },
  562. [IMX8M_POWER_DOMAIN_VPU] = {
  563. .genpd = {
  564. .name = "vpu",
  565. },
  566. .bits = {
  567. .pxx = IMX8M_VPU_SW_Pxx_REQ,
  568. .map = IMX8M_VPU_A53_DOMAIN,
  569. .hskreq = IMX8M_VPU_HSK_PWRDNREQN,
  570. .hskack = IMX8M_VPU_HSK_PWRDNACKN,
  571. },
  572. .pgc = BIT(IMX8M_PGC_VPU),
  573. .keep_clocks = true,
  574. },
  575. [IMX8M_POWER_DOMAIN_DISP] = {
  576. .genpd = {
  577. .name = "disp",
  578. },
  579. .bits = {
  580. .pxx = IMX8M_DISP_SW_Pxx_REQ,
  581. .map = IMX8M_DISP_A53_DOMAIN,
  582. .hskreq = IMX8M_DISP_HSK_PWRDNREQN,
  583. .hskack = IMX8M_DISP_HSK_PWRDNACKN,
  584. },
  585. .pgc = BIT(IMX8M_PGC_DISP),
  586. },
  587. [IMX8M_POWER_DOMAIN_MIPI_CSI1] = {
  588. .genpd = {
  589. .name = "mipi-csi1",
  590. },
  591. .bits = {
  592. .pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ,
  593. .map = IMX8M_MIPI_CSI1_A53_DOMAIN,
  594. },
  595. .pgc = BIT(IMX8M_PGC_MIPI_CSI1),
  596. },
  597. [IMX8M_POWER_DOMAIN_MIPI_CSI2] = {
  598. .genpd = {
  599. .name = "mipi-csi2",
  600. },
  601. .bits = {
  602. .pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ,
  603. .map = IMX8M_MIPI_CSI2_A53_DOMAIN,
  604. },
  605. .pgc = BIT(IMX8M_PGC_MIPI_CSI2),
  606. },
  607. [IMX8M_POWER_DOMAIN_PCIE2] = {
  608. .genpd = {
  609. .name = "pcie2",
  610. },
  611. .bits = {
  612. .pxx = IMX8M_PCIE2_SW_Pxx_REQ,
  613. .map = IMX8M_PCIE2_A53_DOMAIN,
  614. },
  615. .pgc = BIT(IMX8M_PGC_PCIE2),
  616. },
  617. };
  618. static const struct regmap_range imx8m_yes_ranges[] = {
  619. regmap_reg_range(GPC_LPCR_A_CORE_BSC,
  620. GPC_PU_PWRHSK),
  621. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI),
  622. GPC_PGC_SR(IMX8M_PGC_MIPI)),
  623. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE1),
  624. GPC_PGC_SR(IMX8M_PGC_PCIE1)),
  625. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG1),
  626. GPC_PGC_SR(IMX8M_PGC_OTG1)),
  627. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG2),
  628. GPC_PGC_SR(IMX8M_PGC_OTG2)),
  629. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DDR1),
  630. GPC_PGC_SR(IMX8M_PGC_DDR1)),
  631. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_GPU),
  632. GPC_PGC_SR(IMX8M_PGC_GPU)),
  633. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_VPU),
  634. GPC_PGC_SR(IMX8M_PGC_VPU)),
  635. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DISP),
  636. GPC_PGC_SR(IMX8M_PGC_DISP)),
  637. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI1),
  638. GPC_PGC_SR(IMX8M_PGC_MIPI_CSI1)),
  639. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI2),
  640. GPC_PGC_SR(IMX8M_PGC_MIPI_CSI2)),
  641. regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE2),
  642. GPC_PGC_SR(IMX8M_PGC_PCIE2)),
  643. };
  644. static const struct regmap_access_table imx8m_access_table = {
  645. .yes_ranges = imx8m_yes_ranges,
  646. .n_yes_ranges = ARRAY_SIZE(imx8m_yes_ranges),
  647. };
  648. static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
  649. .domains = imx8m_pgc_domains,
  650. .domains_num = ARRAY_SIZE(imx8m_pgc_domains),
  651. .reg_access_table = &imx8m_access_table,
  652. .pgc_regs = &imx7_pgc_regs,
  653. };
  654. static const struct imx_pgc_domain imx8mm_pgc_domains[] = {
  655. [IMX8MM_POWER_DOMAIN_HSIOMIX] = {
  656. .genpd = {
  657. .name = "hsiomix",
  658. },
  659. .bits = {
  660. .pxx = 0, /* no power sequence control */
  661. .map = 0, /* no power sequence control */
  662. .hskreq = IMX8MM_HSIO_HSK_PWRDNREQN,
  663. .hskack = IMX8MM_HSIO_HSK_PWRDNACKN,
  664. },
  665. .keep_clocks = true,
  666. },
  667. [IMX8MM_POWER_DOMAIN_PCIE] = {
  668. .genpd = {
  669. .name = "pcie",
  670. },
  671. .bits = {
  672. .pxx = IMX8MM_PCIE_SW_Pxx_REQ,
  673. .map = IMX8MM_PCIE_A53_DOMAIN,
  674. },
  675. .pgc = BIT(IMX8MM_PGC_PCIE),
  676. },
  677. [IMX8MM_POWER_DOMAIN_OTG1] = {
  678. .genpd = {
  679. .name = "usb-otg1",
  680. .flags = GENPD_FLAG_ACTIVE_WAKEUP,
  681. },
  682. .bits = {
  683. .pxx = IMX8MM_OTG1_SW_Pxx_REQ,
  684. .map = IMX8MM_OTG1_A53_DOMAIN,
  685. },
  686. .pgc = BIT(IMX8MM_PGC_OTG1),
  687. },
  688. [IMX8MM_POWER_DOMAIN_OTG2] = {
  689. .genpd = {
  690. .name = "usb-otg2",
  691. .flags = GENPD_FLAG_ACTIVE_WAKEUP,
  692. },
  693. .bits = {
  694. .pxx = IMX8MM_OTG2_SW_Pxx_REQ,
  695. .map = IMX8MM_OTG2_A53_DOMAIN,
  696. },
  697. .pgc = BIT(IMX8MM_PGC_OTG2),
  698. },
  699. [IMX8MM_POWER_DOMAIN_GPUMIX] = {
  700. .genpd = {
  701. .name = "gpumix",
  702. },
  703. .bits = {
  704. .pxx = IMX8MM_GPUMIX_SW_Pxx_REQ,
  705. .map = IMX8MM_GPUMIX_A53_DOMAIN,
  706. .hskreq = IMX8MM_GPUMIX_HSK_PWRDNREQN,
  707. .hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN,
  708. },
  709. .pgc = BIT(IMX8MM_PGC_GPUMIX),
  710. .keep_clocks = true,
  711. },
  712. [IMX8MM_POWER_DOMAIN_GPU] = {
  713. .genpd = {
  714. .name = "gpu",
  715. },
  716. .bits = {
  717. .pxx = IMX8MM_GPU_SW_Pxx_REQ,
  718. .map = IMX8MM_GPU_A53_DOMAIN,
  719. .hskreq = IMX8MM_GPU_HSK_PWRDNREQN,
  720. .hskack = IMX8MM_GPU_HSK_PWRDNACKN,
  721. },
  722. .pgc = BIT(IMX8MM_PGC_GPU2D) | BIT(IMX8MM_PGC_GPU3D),
  723. },
  724. [IMX8MM_POWER_DOMAIN_VPUMIX] = {
  725. .genpd = {
  726. .name = "vpumix",
  727. },
  728. .bits = {
  729. .pxx = IMX8MM_VPUMIX_SW_Pxx_REQ,
  730. .map = IMX8MM_VPUMIX_A53_DOMAIN,
  731. .hskreq = IMX8MM_VPUMIX_HSK_PWRDNREQN,
  732. .hskack = IMX8MM_VPUMIX_HSK_PWRDNACKN,
  733. },
  734. .pgc = BIT(IMX8MM_PGC_VPUMIX),
  735. .keep_clocks = true,
  736. },
  737. [IMX8MM_POWER_DOMAIN_VPUG1] = {
  738. .genpd = {
  739. .name = "vpu-g1",
  740. },
  741. .bits = {
  742. .pxx = IMX8MM_VPUG1_SW_Pxx_REQ,
  743. .map = IMX8MM_VPUG1_A53_DOMAIN,
  744. },
  745. .pgc = BIT(IMX8MM_PGC_VPUG1),
  746. },
  747. [IMX8MM_POWER_DOMAIN_VPUG2] = {
  748. .genpd = {
  749. .name = "vpu-g2",
  750. },
  751. .bits = {
  752. .pxx = IMX8MM_VPUG2_SW_Pxx_REQ,
  753. .map = IMX8MM_VPUG2_A53_DOMAIN,
  754. },
  755. .pgc = BIT(IMX8MM_PGC_VPUG2),
  756. },
  757. [IMX8MM_POWER_DOMAIN_VPUH1] = {
  758. .genpd = {
  759. .name = "vpu-h1",
  760. },
  761. .bits = {
  762. .pxx = IMX8MM_VPUH1_SW_Pxx_REQ,
  763. .map = IMX8MM_VPUH1_A53_DOMAIN,
  764. },
  765. .pgc = BIT(IMX8MM_PGC_VPUH1),
  766. .keep_clocks = true,
  767. },
  768. [IMX8MM_POWER_DOMAIN_DISPMIX] = {
  769. .genpd = {
  770. .name = "dispmix",
  771. },
  772. .bits = {
  773. .pxx = IMX8MM_DISPMIX_SW_Pxx_REQ,
  774. .map = IMX8MM_DISPMIX_A53_DOMAIN,
  775. .hskreq = IMX8MM_DISPMIX_HSK_PWRDNREQN,
  776. .hskack = IMX8MM_DISPMIX_HSK_PWRDNACKN,
  777. },
  778. .pgc = BIT(IMX8MM_PGC_DISPMIX),
  779. .keep_clocks = true,
  780. },
  781. [IMX8MM_POWER_DOMAIN_MIPI] = {
  782. .genpd = {
  783. .name = "mipi",
  784. },
  785. .bits = {
  786. .pxx = IMX8MM_MIPI_SW_Pxx_REQ,
  787. .map = IMX8MM_MIPI_A53_DOMAIN,
  788. },
  789. .pgc = BIT(IMX8MM_PGC_MIPI),
  790. },
  791. };
  792. static const struct regmap_range imx8mm_yes_ranges[] = {
  793. regmap_reg_range(GPC_LPCR_A_CORE_BSC,
  794. GPC_PU_PWRHSK),
  795. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_MIPI),
  796. GPC_PGC_SR(IMX8MM_PGC_MIPI)),
  797. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_PCIE),
  798. GPC_PGC_SR(IMX8MM_PGC_PCIE)),
  799. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG1),
  800. GPC_PGC_SR(IMX8MM_PGC_OTG1)),
  801. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG2),
  802. GPC_PGC_SR(IMX8MM_PGC_OTG2)),
  803. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DDR1),
  804. GPC_PGC_SR(IMX8MM_PGC_DDR1)),
  805. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU2D),
  806. GPC_PGC_SR(IMX8MM_PGC_GPU2D)),
  807. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPUMIX),
  808. GPC_PGC_SR(IMX8MM_PGC_GPUMIX)),
  809. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUMIX),
  810. GPC_PGC_SR(IMX8MM_PGC_VPUMIX)),
  811. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU3D),
  812. GPC_PGC_SR(IMX8MM_PGC_GPU3D)),
  813. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DISPMIX),
  814. GPC_PGC_SR(IMX8MM_PGC_DISPMIX)),
  815. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG1),
  816. GPC_PGC_SR(IMX8MM_PGC_VPUG1)),
  817. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG2),
  818. GPC_PGC_SR(IMX8MM_PGC_VPUG2)),
  819. regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUH1),
  820. GPC_PGC_SR(IMX8MM_PGC_VPUH1)),
  821. };
  822. static const struct regmap_access_table imx8mm_access_table = {
  823. .yes_ranges = imx8mm_yes_ranges,
  824. .n_yes_ranges = ARRAY_SIZE(imx8mm_yes_ranges),
  825. };
  826. static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = {
  827. .domains = imx8mm_pgc_domains,
  828. .domains_num = ARRAY_SIZE(imx8mm_pgc_domains),
  829. .reg_access_table = &imx8mm_access_table,
  830. .pgc_regs = &imx7_pgc_regs,
  831. };
  832. static const struct imx_pgc_domain imx8mp_pgc_domains[] = {
  833. [IMX8MP_POWER_DOMAIN_MIPI_PHY1] = {
  834. .genpd = {
  835. .name = "mipi-phy1",
  836. },
  837. .bits = {
  838. .pxx = IMX8MP_MIPI_PHY1_SW_Pxx_REQ,
  839. .map = IMX8MP_MIPI_PHY1_A53_DOMAIN,
  840. },
  841. .pgc = BIT(IMX8MP_PGC_MIPI1),
  842. },
  843. [IMX8MP_POWER_DOMAIN_PCIE_PHY] = {
  844. .genpd = {
  845. .name = "pcie-phy1",
  846. },
  847. .bits = {
  848. .pxx = IMX8MP_PCIE_PHY_SW_Pxx_REQ,
  849. .map = IMX8MP_PCIE_PHY_A53_DOMAIN,
  850. },
  851. .pgc = BIT(IMX8MP_PGC_PCIE),
  852. },
  853. [IMX8MP_POWER_DOMAIN_USB1_PHY] = {
  854. .genpd = {
  855. .name = "usb-otg1",
  856. },
  857. .bits = {
  858. .pxx = IMX8MP_USB1_PHY_Pxx_REQ,
  859. .map = IMX8MP_USB1_PHY_A53_DOMAIN,
  860. },
  861. .pgc = BIT(IMX8MP_PGC_USB1),
  862. },
  863. [IMX8MP_POWER_DOMAIN_USB2_PHY] = {
  864. .genpd = {
  865. .name = "usb-otg2",
  866. },
  867. .bits = {
  868. .pxx = IMX8MP_USB2_PHY_Pxx_REQ,
  869. .map = IMX8MP_USB2_PHY_A53_DOMAIN,
  870. },
  871. .pgc = BIT(IMX8MP_PGC_USB2),
  872. },
  873. [IMX8MP_POWER_DOMAIN_MLMIX] = {
  874. .genpd = {
  875. .name = "mlmix",
  876. },
  877. .bits = {
  878. .pxx = IMX8MP_MLMIX_Pxx_REQ,
  879. .map = IMX8MP_MLMIX_A53_DOMAIN,
  880. .hskreq = IMX8MP_MLMIX_PWRDNREQN,
  881. .hskack = IMX8MP_MLMIX_PWRDNACKN,
  882. },
  883. .pgc = BIT(IMX8MP_PGC_MLMIX),
  884. .keep_clocks = true,
  885. },
  886. [IMX8MP_POWER_DOMAIN_AUDIOMIX] = {
  887. .genpd = {
  888. .name = "audiomix",
  889. },
  890. .bits = {
  891. .pxx = IMX8MP_AUDIOMIX_Pxx_REQ,
  892. .map = IMX8MP_AUDIOMIX_A53_DOMAIN,
  893. .hskreq = IMX8MP_AUDIOMIX_PWRDNREQN,
  894. .hskack = IMX8MP_AUDIOMIX_PWRDNACKN,
  895. },
  896. .pgc = BIT(IMX8MP_PGC_AUDIOMIX),
  897. .keep_clocks = true,
  898. },
  899. [IMX8MP_POWER_DOMAIN_GPU2D] = {
  900. .genpd = {
  901. .name = "gpu2d",
  902. },
  903. .bits = {
  904. .pxx = IMX8MP_GPU_2D_Pxx_REQ,
  905. .map = IMX8MP_GPU2D_A53_DOMAIN,
  906. },
  907. .pgc = BIT(IMX8MP_PGC_GPU2D),
  908. },
  909. [IMX8MP_POWER_DOMAIN_GPUMIX] = {
  910. .genpd = {
  911. .name = "gpumix",
  912. },
  913. .bits = {
  914. .pxx = IMX8MP_GPU_SHARE_LOGIC_Pxx_REQ,
  915. .map = IMX8MP_GPUMIX_A53_DOMAIN,
  916. .hskreq = IMX8MP_GPUMIX_PWRDNREQN,
  917. .hskack = IMX8MP_GPUMIX_PWRDNACKN,
  918. },
  919. .pgc = BIT(IMX8MP_PGC_GPUMIX),
  920. .keep_clocks = true,
  921. },
  922. [IMX8MP_POWER_DOMAIN_VPUMIX] = {
  923. .genpd = {
  924. .name = "vpumix",
  925. },
  926. .bits = {
  927. .pxx = IMX8MP_VPU_MIX_SHARE_LOGIC_Pxx_REQ,
  928. .map = IMX8MP_VPUMIX_A53_DOMAIN,
  929. .hskreq = IMX8MP_VPUMIX_PWRDNREQN,
  930. .hskack = IMX8MP_VPUMIX_PWRDNACKN,
  931. },
  932. .pgc = BIT(IMX8MP_PGC_VPUMIX),
  933. .keep_clocks = true,
  934. },
  935. [IMX8MP_POWER_DOMAIN_GPU3D] = {
  936. .genpd = {
  937. .name = "gpu3d",
  938. },
  939. .bits = {
  940. .pxx = IMX8MP_GPU_3D_Pxx_REQ,
  941. .map = IMX8MP_GPU3D_A53_DOMAIN,
  942. },
  943. .pgc = BIT(IMX8MP_PGC_GPU3D),
  944. },
  945. [IMX8MP_POWER_DOMAIN_MEDIAMIX] = {
  946. .genpd = {
  947. .name = "mediamix",
  948. },
  949. .bits = {
  950. .pxx = IMX8MP_MEDIMIX_Pxx_REQ,
  951. .map = IMX8MP_MEDIAMIX_A53_DOMAIN,
  952. .hskreq = IMX8MP_MEDIAMIX_PWRDNREQN,
  953. .hskack = IMX8MP_MEDIAMIX_PWRDNACKN,
  954. },
  955. .pgc = BIT(IMX8MP_PGC_MEDIAMIX),
  956. .keep_clocks = true,
  957. },
  958. [IMX8MP_POWER_DOMAIN_VPU_G1] = {
  959. .genpd = {
  960. .name = "vpu-g1",
  961. },
  962. .bits = {
  963. .pxx = IMX8MP_VPU_G1_Pxx_REQ,
  964. .map = IMX8MP_VPU_G1_A53_DOMAIN,
  965. },
  966. .pgc = BIT(IMX8MP_PGC_VPU_G1),
  967. },
  968. [IMX8MP_POWER_DOMAIN_VPU_G2] = {
  969. .genpd = {
  970. .name = "vpu-g2",
  971. },
  972. .bits = {
  973. .pxx = IMX8MP_VPU_G2_Pxx_REQ,
  974. .map = IMX8MP_VPU_G2_A53_DOMAIN
  975. },
  976. .pgc = BIT(IMX8MP_PGC_VPU_G2),
  977. },
  978. [IMX8MP_POWER_DOMAIN_VPU_VC8000E] = {
  979. .genpd = {
  980. .name = "vpu-h1",
  981. },
  982. .bits = {
  983. .pxx = IMX8MP_VPU_VC8K_Pxx_REQ,
  984. .map = IMX8MP_VPU_VC8000E_A53_DOMAIN,
  985. },
  986. .pgc = BIT(IMX8MP_PGC_VPU_VC8000E),
  987. },
  988. [IMX8MP_POWER_DOMAIN_HDMIMIX] = {
  989. .genpd = {
  990. .name = "hdmimix",
  991. },
  992. .bits = {
  993. .pxx = IMX8MP_HDMIMIX_Pxx_REQ,
  994. .map = IMX8MP_HDMIMIX_A53_DOMAIN,
  995. .hskreq = IMX8MP_HDMIMIX_PWRDNREQN,
  996. .hskack = IMX8MP_HDMIMIX_PWRDNACKN,
  997. },
  998. .pgc = BIT(IMX8MP_PGC_HDMIMIX),
  999. .keep_clocks = true,
  1000. },
  1001. [IMX8MP_POWER_DOMAIN_HDMI_PHY] = {
  1002. .genpd = {
  1003. .name = "hdmi-phy",
  1004. },
  1005. .bits = {
  1006. .pxx = IMX8MP_HDMI_PHY_Pxx_REQ,
  1007. .map = IMX8MP_HDMI_PHY_A53_DOMAIN,
  1008. },
  1009. .pgc = BIT(IMX8MP_PGC_HDMI),
  1010. },
  1011. [IMX8MP_POWER_DOMAIN_MIPI_PHY2] = {
  1012. .genpd = {
  1013. .name = "mipi-phy2",
  1014. },
  1015. .bits = {
  1016. .pxx = IMX8MP_MIPI_PHY2_Pxx_REQ,
  1017. .map = IMX8MP_MIPI_PHY2_A53_DOMAIN,
  1018. },
  1019. .pgc = BIT(IMX8MP_PGC_MIPI2),
  1020. },
  1021. [IMX8MP_POWER_DOMAIN_HSIOMIX] = {
  1022. .genpd = {
  1023. .name = "hsiomix",
  1024. },
  1025. .bits = {
  1026. .pxx = IMX8MP_HSIOMIX_Pxx_REQ,
  1027. .map = IMX8MP_HSIOMIX_A53_DOMAIN,
  1028. .hskreq = IMX8MP_HSIOMIX_PWRDNREQN,
  1029. .hskack = IMX8MP_HSIOMIX_PWRDNACKN,
  1030. },
  1031. .pgc = BIT(IMX8MP_PGC_HSIOMIX),
  1032. .keep_clocks = true,
  1033. },
  1034. [IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP] = {
  1035. .genpd = {
  1036. .name = "mediamix-isp-dwp",
  1037. },
  1038. .bits = {
  1039. .pxx = IMX8MP_MEDIA_ISP_DWP_Pxx_REQ,
  1040. .map = IMX8MP_MEDIA_ISPDWP_A53_DOMAIN,
  1041. },
  1042. .pgc = BIT(IMX8MP_PGC_MEDIA_ISP_DWP),
  1043. },
  1044. };
  1045. static const struct regmap_range imx8mp_yes_ranges[] = {
  1046. regmap_reg_range(GPC_LPCR_A_CORE_BSC,
  1047. IMX8MP_GPC_PGC_CPU_MAPPING),
  1048. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_NOC),
  1049. GPC_PGC_SR(IMX8MP_PGC_NOC)),
  1050. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MIPI1),
  1051. GPC_PGC_SR(IMX8MP_PGC_MIPI1)),
  1052. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_PCIE),
  1053. GPC_PGC_SR(IMX8MP_PGC_PCIE)),
  1054. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_USB1),
  1055. GPC_PGC_SR(IMX8MP_PGC_USB1)),
  1056. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_USB2),
  1057. GPC_PGC_SR(IMX8MP_PGC_USB2)),
  1058. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MLMIX),
  1059. GPC_PGC_SR(IMX8MP_PGC_MLMIX)),
  1060. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_AUDIOMIX),
  1061. GPC_PGC_SR(IMX8MP_PGC_AUDIOMIX)),
  1062. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPU2D),
  1063. GPC_PGC_SR(IMX8MP_PGC_GPU2D)),
  1064. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPUMIX),
  1065. GPC_PGC_SR(IMX8MP_PGC_GPUMIX)),
  1066. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPUMIX),
  1067. GPC_PGC_SR(IMX8MP_PGC_VPUMIX)),
  1068. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPU3D),
  1069. GPC_PGC_SR(IMX8MP_PGC_GPU3D)),
  1070. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MEDIAMIX),
  1071. GPC_PGC_SR(IMX8MP_PGC_MEDIAMIX)),
  1072. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_G1),
  1073. GPC_PGC_SR(IMX8MP_PGC_VPU_G1)),
  1074. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_G2),
  1075. GPC_PGC_SR(IMX8MP_PGC_VPU_G2)),
  1076. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_VC8000E),
  1077. GPC_PGC_SR(IMX8MP_PGC_VPU_VC8000E)),
  1078. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HDMIMIX),
  1079. GPC_PGC_SR(IMX8MP_PGC_HDMIMIX)),
  1080. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HDMI),
  1081. GPC_PGC_SR(IMX8MP_PGC_HDMI)),
  1082. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MIPI2),
  1083. GPC_PGC_SR(IMX8MP_PGC_MIPI2)),
  1084. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HSIOMIX),
  1085. GPC_PGC_SR(IMX8MP_PGC_HSIOMIX)),
  1086. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MEDIA_ISP_DWP),
  1087. GPC_PGC_SR(IMX8MP_PGC_MEDIA_ISP_DWP)),
  1088. regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_DDRMIX),
  1089. GPC_PGC_SR(IMX8MP_PGC_DDRMIX)),
  1090. };
  1091. static const struct regmap_access_table imx8mp_access_table = {
  1092. .yes_ranges = imx8mp_yes_ranges,
  1093. .n_yes_ranges = ARRAY_SIZE(imx8mp_yes_ranges),
  1094. };
  1095. static const struct imx_pgc_regs imx8mp_pgc_regs = {
  1096. .map = IMX8MP_GPC_PGC_CPU_MAPPING,
  1097. .pup = IMX8MP_GPC_PU_PGC_SW_PUP_REQ,
  1098. .pdn = IMX8MP_GPC_PU_PGC_SW_PDN_REQ,
  1099. .hsk = IMX8MP_GPC_PU_PWRHSK,
  1100. };
  1101. static const struct imx_pgc_domain_data imx8mp_pgc_domain_data = {
  1102. .domains = imx8mp_pgc_domains,
  1103. .domains_num = ARRAY_SIZE(imx8mp_pgc_domains),
  1104. .reg_access_table = &imx8mp_access_table,
  1105. .pgc_regs = &imx8mp_pgc_regs,
  1106. };
  1107. static const struct imx_pgc_domain imx8mn_pgc_domains[] = {
  1108. [IMX8MN_POWER_DOMAIN_HSIOMIX] = {
  1109. .genpd = {
  1110. .name = "hsiomix",
  1111. },
  1112. .bits = {
  1113. .pxx = 0, /* no power sequence control */
  1114. .map = 0, /* no power sequence control */
  1115. .hskreq = IMX8MN_HSIO_HSK_PWRDNREQN,
  1116. .hskack = IMX8MN_HSIO_HSK_PWRDNACKN,
  1117. },
  1118. .keep_clocks = true,
  1119. },
  1120. [IMX8MN_POWER_DOMAIN_OTG1] = {
  1121. .genpd = {
  1122. .name = "usb-otg1",
  1123. .flags = GENPD_FLAG_ACTIVE_WAKEUP,
  1124. },
  1125. .bits = {
  1126. .pxx = IMX8MN_OTG1_SW_Pxx_REQ,
  1127. .map = IMX8MN_OTG1_A53_DOMAIN,
  1128. },
  1129. .pgc = BIT(IMX8MN_PGC_OTG1),
  1130. },
  1131. [IMX8MN_POWER_DOMAIN_GPUMIX] = {
  1132. .genpd = {
  1133. .name = "gpumix",
  1134. },
  1135. .bits = {
  1136. .pxx = IMX8MN_GPUMIX_SW_Pxx_REQ,
  1137. .map = IMX8MN_GPUMIX_A53_DOMAIN,
  1138. .hskreq = IMX8MN_GPUMIX_HSK_PWRDNREQN,
  1139. .hskack = IMX8MN_GPUMIX_HSK_PWRDNACKN,
  1140. },
  1141. .pgc = BIT(IMX8MN_PGC_GPUMIX),
  1142. .keep_clocks = true,
  1143. },
  1144. [IMX8MN_POWER_DOMAIN_DISPMIX] = {
  1145. .genpd = {
  1146. .name = "dispmix",
  1147. },
  1148. .bits = {
  1149. .pxx = IMX8MN_DISPMIX_SW_Pxx_REQ,
  1150. .map = IMX8MN_DISPMIX_A53_DOMAIN,
  1151. .hskreq = IMX8MN_DISPMIX_HSK_PWRDNREQN,
  1152. .hskack = IMX8MN_DISPMIX_HSK_PWRDNACKN,
  1153. },
  1154. .pgc = BIT(IMX8MN_PGC_DISPMIX),
  1155. .keep_clocks = true,
  1156. },
  1157. [IMX8MN_POWER_DOMAIN_MIPI] = {
  1158. .genpd = {
  1159. .name = "mipi",
  1160. },
  1161. .bits = {
  1162. .pxx = IMX8MN_MIPI_SW_Pxx_REQ,
  1163. .map = IMX8MN_MIPI_A53_DOMAIN,
  1164. },
  1165. .pgc = BIT(IMX8MN_PGC_MIPI),
  1166. },
  1167. };
  1168. static const struct regmap_range imx8mn_yes_ranges[] = {
  1169. regmap_reg_range(GPC_LPCR_A_CORE_BSC,
  1170. GPC_PU_PWRHSK),
  1171. regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_MIPI),
  1172. GPC_PGC_SR(IMX8MN_PGC_MIPI)),
  1173. regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_OTG1),
  1174. GPC_PGC_SR(IMX8MN_PGC_OTG1)),
  1175. regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_DDR1),
  1176. GPC_PGC_SR(IMX8MN_PGC_DDR1)),
  1177. regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_GPUMIX),
  1178. GPC_PGC_SR(IMX8MN_PGC_GPUMIX)),
  1179. regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_DISPMIX),
  1180. GPC_PGC_SR(IMX8MN_PGC_DISPMIX)),
  1181. };
  1182. static const struct regmap_access_table imx8mn_access_table = {
  1183. .yes_ranges = imx8mn_yes_ranges,
  1184. .n_yes_ranges = ARRAY_SIZE(imx8mn_yes_ranges),
  1185. };
  1186. static const struct imx_pgc_domain_data imx8mn_pgc_domain_data = {
  1187. .domains = imx8mn_pgc_domains,
  1188. .domains_num = ARRAY_SIZE(imx8mn_pgc_domains),
  1189. .reg_access_table = &imx8mn_access_table,
  1190. .pgc_regs = &imx7_pgc_regs,
  1191. };
  1192. static int imx_pgc_domain_probe(struct platform_device *pdev)
  1193. {
  1194. struct imx_pgc_domain *domain = pdev->dev.platform_data;
  1195. int ret;
  1196. domain->dev = &pdev->dev;
  1197. domain->regulator = devm_regulator_get_optional(domain->dev, "power");
  1198. if (IS_ERR(domain->regulator)) {
  1199. if (PTR_ERR(domain->regulator) != -ENODEV)
  1200. return dev_err_probe(domain->dev, PTR_ERR(domain->regulator),
  1201. "Failed to get domain's regulator\n");
  1202. } else if (domain->voltage) {
  1203. regulator_set_voltage(domain->regulator,
  1204. domain->voltage, domain->voltage);
  1205. }
  1206. domain->num_clks = devm_clk_bulk_get_all(domain->dev, &domain->clks);
  1207. if (domain->num_clks < 0)
  1208. return dev_err_probe(domain->dev, domain->num_clks,
  1209. "Failed to get domain's clocks\n");
  1210. domain->reset = devm_reset_control_array_get_optional_exclusive(domain->dev);
  1211. if (IS_ERR(domain->reset))
  1212. return dev_err_probe(domain->dev, PTR_ERR(domain->reset),
  1213. "Failed to get domain's resets\n");
  1214. pm_runtime_enable(domain->dev);
  1215. if (domain->bits.map)
  1216. regmap_update_bits(domain->regmap, domain->regs->map,
  1217. domain->bits.map, domain->bits.map);
  1218. ret = pm_genpd_init(&domain->genpd, NULL, true);
  1219. if (ret) {
  1220. dev_err(domain->dev, "Failed to init power domain\n");
  1221. goto out_domain_unmap;
  1222. }
  1223. if (IS_ENABLED(CONFIG_LOCKDEP) &&
  1224. of_property_present(domain->dev->of_node, "power-domains"))
  1225. lockdep_set_subclass(&domain->genpd.mlock, 1);
  1226. ret = of_genpd_add_provider_simple(domain->dev->of_node,
  1227. &domain->genpd);
  1228. if (ret) {
  1229. dev_err(domain->dev, "Failed to add genpd provider\n");
  1230. goto out_genpd_remove;
  1231. }
  1232. return 0;
  1233. out_genpd_remove:
  1234. pm_genpd_remove(&domain->genpd);
  1235. out_domain_unmap:
  1236. if (domain->bits.map)
  1237. regmap_update_bits(domain->regmap, domain->regs->map,
  1238. domain->bits.map, 0);
  1239. pm_runtime_disable(domain->dev);
  1240. return ret;
  1241. }
  1242. static void imx_pgc_domain_remove(struct platform_device *pdev)
  1243. {
  1244. struct imx_pgc_domain *domain = pdev->dev.platform_data;
  1245. of_genpd_del_provider(domain->dev->of_node);
  1246. pm_genpd_remove(&domain->genpd);
  1247. if (domain->bits.map)
  1248. regmap_update_bits(domain->regmap, domain->regs->map,
  1249. domain->bits.map, 0);
  1250. pm_runtime_disable(domain->dev);
  1251. }
  1252. #ifdef CONFIG_PM_SLEEP
  1253. static int imx_pgc_domain_suspend(struct device *dev)
  1254. {
  1255. int ret;
  1256. /*
  1257. * This may look strange, but is done so the generic PM_SLEEP code
  1258. * can power down our domain and more importantly power it up again
  1259. * after resume, without tripping over our usage of runtime PM to
  1260. * power up/down the nested domains.
  1261. */
  1262. ret = pm_runtime_get_sync(dev);
  1263. if (ret < 0) {
  1264. pm_runtime_put_noidle(dev);
  1265. return ret;
  1266. }
  1267. return 0;
  1268. }
  1269. static int imx_pgc_domain_resume(struct device *dev)
  1270. {
  1271. return pm_runtime_put(dev);
  1272. }
  1273. #endif
  1274. static const struct dev_pm_ops imx_pgc_domain_pm_ops = {
  1275. SET_SYSTEM_SLEEP_PM_OPS(imx_pgc_domain_suspend, imx_pgc_domain_resume)
  1276. };
  1277. static const struct platform_device_id imx_pgc_domain_id[] = {
  1278. { "imx-pgc-domain", },
  1279. { },
  1280. };
  1281. static struct platform_driver imx_pgc_domain_driver = {
  1282. .driver = {
  1283. .name = "imx-pgc",
  1284. .pm = &imx_pgc_domain_pm_ops,
  1285. },
  1286. .probe = imx_pgc_domain_probe,
  1287. .remove_new = imx_pgc_domain_remove,
  1288. .id_table = imx_pgc_domain_id,
  1289. };
  1290. builtin_platform_driver(imx_pgc_domain_driver)
  1291. static int imx_gpcv2_probe(struct platform_device *pdev)
  1292. {
  1293. const struct imx_pgc_domain_data *domain_data =
  1294. of_device_get_match_data(&pdev->dev);
  1295. struct regmap_config regmap_config = {
  1296. .reg_bits = 32,
  1297. .val_bits = 32,
  1298. .reg_stride = 4,
  1299. .rd_table = domain_data->reg_access_table,
  1300. .wr_table = domain_data->reg_access_table,
  1301. .max_register = SZ_4K,
  1302. };
  1303. struct device *dev = &pdev->dev;
  1304. struct device_node *pgc_np __free(device_node) =
  1305. of_get_child_by_name(dev->of_node, "pgc");
  1306. struct regmap *regmap;
  1307. void __iomem *base;
  1308. int ret;
  1309. if (!pgc_np) {
  1310. dev_err(dev, "No power domains specified in DT\n");
  1311. return -EINVAL;
  1312. }
  1313. base = devm_platform_ioremap_resource(pdev, 0);
  1314. if (IS_ERR(base))
  1315. return PTR_ERR(base);
  1316. regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
  1317. if (IS_ERR(regmap)) {
  1318. ret = PTR_ERR(regmap);
  1319. dev_err(dev, "failed to init regmap (%d)\n", ret);
  1320. return ret;
  1321. }
  1322. for_each_child_of_node_scoped(pgc_np, np) {
  1323. struct platform_device *pd_pdev;
  1324. struct imx_pgc_domain *domain;
  1325. u32 domain_index;
  1326. if (!of_device_is_available(np))
  1327. continue;
  1328. ret = of_property_read_u32(np, "reg", &domain_index);
  1329. if (ret) {
  1330. dev_err(dev, "Failed to read 'reg' property\n");
  1331. return ret;
  1332. }
  1333. if (domain_index >= domain_data->domains_num) {
  1334. dev_warn(dev,
  1335. "Domain index %d is out of bounds\n",
  1336. domain_index);
  1337. continue;
  1338. }
  1339. pd_pdev = platform_device_alloc("imx-pgc-domain",
  1340. domain_index);
  1341. if (!pd_pdev) {
  1342. dev_err(dev, "Failed to allocate platform device\n");
  1343. return -ENOMEM;
  1344. }
  1345. ret = platform_device_add_data(pd_pdev,
  1346. &domain_data->domains[domain_index],
  1347. sizeof(domain_data->domains[domain_index]));
  1348. if (ret) {
  1349. platform_device_put(pd_pdev);
  1350. return ret;
  1351. }
  1352. domain = pd_pdev->dev.platform_data;
  1353. domain->regmap = regmap;
  1354. domain->regs = domain_data->pgc_regs;
  1355. domain->genpd.power_on = imx_pgc_power_up;
  1356. domain->genpd.power_off = imx_pgc_power_down;
  1357. pd_pdev->dev.parent = dev;
  1358. device_set_node(&pd_pdev->dev, of_fwnode_handle(np));
  1359. ret = platform_device_add(pd_pdev);
  1360. if (ret) {
  1361. platform_device_put(pd_pdev);
  1362. return ret;
  1363. }
  1364. }
  1365. return 0;
  1366. }
  1367. static const struct of_device_id imx_gpcv2_dt_ids[] = {
  1368. { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
  1369. { .compatible = "fsl,imx8mm-gpc", .data = &imx8mm_pgc_domain_data, },
  1370. { .compatible = "fsl,imx8mn-gpc", .data = &imx8mn_pgc_domain_data, },
  1371. { .compatible = "fsl,imx8mp-gpc", .data = &imx8mp_pgc_domain_data, },
  1372. { .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
  1373. { }
  1374. };
  1375. static struct platform_driver imx_gpc_driver = {
  1376. .driver = {
  1377. .name = "imx-gpcv2",
  1378. .of_match_table = imx_gpcv2_dt_ids,
  1379. },
  1380. .probe = imx_gpcv2_probe,
  1381. };
  1382. builtin_platform_driver(imx_gpc_driver)