0002-soc-mediatek-Separate-scpsys-driver-common-code.patch 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. From 1892fcf687116720d07135c83d489a23ec56a166 Mon Sep 17 00:00:00 2001
  2. From: James Liao <[email protected]>
  3. Date: Wed, 30 Dec 2015 14:41:43 +0800
  4. Subject: [PATCH 002/102] soc: mediatek: Separate scpsys driver common code
  5. Separate scpsys driver common code to mtk-scpsys.c, and move MT8173
  6. platform code to mtk-scpsys-mt8173.c.
  7. Signed-off-by: James Liao <[email protected]>
  8. ---
  9. drivers/soc/mediatek/Kconfig | 13 +-
  10. drivers/soc/mediatek/Makefile | 1 +
  11. drivers/soc/mediatek/mtk-scpsys-mt8173.c | 179 ++++++++++++++++++
  12. drivers/soc/mediatek/mtk-scpsys.c | 301 ++++++++----------------------
  13. drivers/soc/mediatek/mtk-scpsys.h | 54 ++++++
  14. 5 files changed, 320 insertions(+), 228 deletions(-)
  15. create mode 100644 drivers/soc/mediatek/mtk-scpsys-mt8173.c
  16. create mode 100644 drivers/soc/mediatek/mtk-scpsys.h
  17. diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
  18. index 0a4ea80..eca6fb7 100644
  19. --- a/drivers/soc/mediatek/Kconfig
  20. +++ b/drivers/soc/mediatek/Kconfig
  21. @@ -22,11 +22,20 @@ config MTK_PMIC_WRAP
  22. config MTK_SCPSYS
  23. bool "MediaTek SCPSYS Support"
  24. - depends on ARCH_MEDIATEK || COMPILE_TEST
  25. - default ARM64 && ARCH_MEDIATEK
  26. select REGMAP
  27. select MTK_INFRACFG
  28. select PM_GENERIC_DOMAINS if PM
  29. help
  30. Say yes here to add support for the MediaTek SCPSYS power domain
  31. driver.
  32. +
  33. +config MTK_SCPSYS_MT8173
  34. + bool "MediaTek MT8173 SCPSYS Support"
  35. + depends on ARCH_MEDIATEK || COMPILE_TEST
  36. + select MTK_SCPSYS
  37. + default ARCH_MEDIATEK
  38. + help
  39. + Say yes here to add support for the MT8173 SCPSYS power domain
  40. + driver.
  41. + The System Control Processor System (SCPSYS) has several power
  42. + management related tasks in the system.
  43. diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
  44. index 12998b0..3b22baa 100644
  45. --- a/drivers/soc/mediatek/Makefile
  46. +++ b/drivers/soc/mediatek/Makefile
  47. @@ -1,3 +1,4 @@
  48. obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
  49. obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
  50. obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
  51. +obj-$(CONFIG_MTK_SCPSYS_MT8173) += mtk-scpsys-mt8173.o
  52. diff --git a/drivers/soc/mediatek/mtk-scpsys-mt8173.c b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
  53. new file mode 100644
  54. index 0000000..3c7b569
  55. --- /dev/null
  56. +++ b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
  57. @@ -0,0 +1,179 @@
  58. +/*
  59. + * Copyright (c) 2015 Pengutronix, Sascha Hauer <[email protected]>
  60. + *
  61. + * This program is free software; you can redistribute it and/or modify
  62. + * it under the terms of the GNU General Public License version 2 as
  63. + * published by the Free Software Foundation.
  64. + *
  65. + * This program is distributed in the hope that it will be useful,
  66. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  67. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  68. + * GNU General Public License for more details.
  69. + */
  70. +#include <linux/mfd/syscon.h>
  71. +#include <linux/module.h>
  72. +#include <linux/of_device.h>
  73. +#include <linux/pm_domain.h>
  74. +#include <linux/soc/mediatek/infracfg.h>
  75. +#include <dt-bindings/power/mt8173-power.h>
  76. +
  77. +#include "mtk-scpsys.h"
  78. +
  79. +#define SPM_VDE_PWR_CON 0x0210
  80. +#define SPM_MFG_PWR_CON 0x0214
  81. +#define SPM_VEN_PWR_CON 0x0230
  82. +#define SPM_ISP_PWR_CON 0x0238
  83. +#define SPM_DIS_PWR_CON 0x023c
  84. +#define SPM_VEN2_PWR_CON 0x0298
  85. +#define SPM_AUDIO_PWR_CON 0x029c
  86. +#define SPM_MFG_2D_PWR_CON 0x02c0
  87. +#define SPM_MFG_ASYNC_PWR_CON 0x02c4
  88. +#define SPM_USB_PWR_CON 0x02cc
  89. +
  90. +#define PWR_STATUS_DISP BIT(3)
  91. +#define PWR_STATUS_MFG BIT(4)
  92. +#define PWR_STATUS_ISP BIT(5)
  93. +#define PWR_STATUS_VDEC BIT(7)
  94. +#define PWR_STATUS_VENC_LT BIT(20)
  95. +#define PWR_STATUS_VENC BIT(21)
  96. +#define PWR_STATUS_MFG_2D BIT(22)
  97. +#define PWR_STATUS_MFG_ASYNC BIT(23)
  98. +#define PWR_STATUS_AUDIO BIT(24)
  99. +#define PWR_STATUS_USB BIT(25)
  100. +
  101. +static const struct scp_domain_data scp_domain_data[] __initconst = {
  102. + [MT8173_POWER_DOMAIN_VDEC] = {
  103. + .name = "vdec",
  104. + .sta_mask = PWR_STATUS_VDEC,
  105. + .ctl_offs = SPM_VDE_PWR_CON,
  106. + .sram_pdn_bits = GENMASK(11, 8),
  107. + .sram_pdn_ack_bits = GENMASK(12, 12),
  108. + .clk_id = {CLK_MM},
  109. + },
  110. + [MT8173_POWER_DOMAIN_VENC] = {
  111. + .name = "venc",
  112. + .sta_mask = PWR_STATUS_VENC,
  113. + .ctl_offs = SPM_VEN_PWR_CON,
  114. + .sram_pdn_bits = GENMASK(11, 8),
  115. + .sram_pdn_ack_bits = GENMASK(15, 12),
  116. + .clk_id = {CLK_MM, CLK_VENC},
  117. + },
  118. + [MT8173_POWER_DOMAIN_ISP] = {
  119. + .name = "isp",
  120. + .sta_mask = PWR_STATUS_ISP,
  121. + .ctl_offs = SPM_ISP_PWR_CON,
  122. + .sram_pdn_bits = GENMASK(11, 8),
  123. + .sram_pdn_ack_bits = GENMASK(13, 12),
  124. + .clk_id = {CLK_MM},
  125. + },
  126. + [MT8173_POWER_DOMAIN_MM] = {
  127. + .name = "mm",
  128. + .sta_mask = PWR_STATUS_DISP,
  129. + .ctl_offs = SPM_DIS_PWR_CON,
  130. + .sram_pdn_bits = GENMASK(11, 8),
  131. + .sram_pdn_ack_bits = GENMASK(12, 12),
  132. + .clk_id = {CLK_MM},
  133. + .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
  134. + MT8173_TOP_AXI_PROT_EN_MM_M1,
  135. + },
  136. + [MT8173_POWER_DOMAIN_VENC_LT] = {
  137. + .name = "venc_lt",
  138. + .sta_mask = PWR_STATUS_VENC_LT,
  139. + .ctl_offs = SPM_VEN2_PWR_CON,
  140. + .sram_pdn_bits = GENMASK(11, 8),
  141. + .sram_pdn_ack_bits = GENMASK(15, 12),
  142. + .clk_id = {CLK_MM, CLK_VENC_LT},
  143. + },
  144. + [MT8173_POWER_DOMAIN_AUDIO] = {
  145. + .name = "audio",
  146. + .sta_mask = PWR_STATUS_AUDIO,
  147. + .ctl_offs = SPM_AUDIO_PWR_CON,
  148. + .sram_pdn_bits = GENMASK(11, 8),
  149. + .sram_pdn_ack_bits = GENMASK(15, 12),
  150. + .clk_id = {CLK_NONE},
  151. + },
  152. + [MT8173_POWER_DOMAIN_USB] = {
  153. + .name = "usb",
  154. + .sta_mask = PWR_STATUS_USB,
  155. + .ctl_offs = SPM_USB_PWR_CON,
  156. + .sram_pdn_bits = GENMASK(11, 8),
  157. + .sram_pdn_ack_bits = GENMASK(15, 12),
  158. + .clk_id = {CLK_NONE},
  159. + .active_wakeup = true,
  160. + },
  161. + [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
  162. + .name = "mfg_async",
  163. + .sta_mask = PWR_STATUS_MFG_ASYNC,
  164. + .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
  165. + .sram_pdn_bits = GENMASK(11, 8),
  166. + .sram_pdn_ack_bits = 0,
  167. + .clk_id = {CLK_MFG},
  168. + },
  169. + [MT8173_POWER_DOMAIN_MFG_2D] = {
  170. + .name = "mfg_2d",
  171. + .sta_mask = PWR_STATUS_MFG_2D,
  172. + .ctl_offs = SPM_MFG_2D_PWR_CON,
  173. + .sram_pdn_bits = GENMASK(11, 8),
  174. + .sram_pdn_ack_bits = GENMASK(13, 12),
  175. + .clk_id = {CLK_NONE},
  176. + },
  177. + [MT8173_POWER_DOMAIN_MFG] = {
  178. + .name = "mfg",
  179. + .sta_mask = PWR_STATUS_MFG,
  180. + .ctl_offs = SPM_MFG_PWR_CON,
  181. + .sram_pdn_bits = GENMASK(13, 8),
  182. + .sram_pdn_ack_bits = GENMASK(21, 16),
  183. + .clk_id = {CLK_NONE},
  184. + .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
  185. + MT8173_TOP_AXI_PROT_EN_MFG_M0 |
  186. + MT8173_TOP_AXI_PROT_EN_MFG_M1 |
  187. + MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
  188. + },
  189. +};
  190. +
  191. +#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
  192. +
  193. +static int __init scpsys_probe(struct platform_device *pdev)
  194. +{
  195. + struct scp *scp;
  196. + struct genpd_onecell_data *pd_data;
  197. + int ret;
  198. +
  199. + scp = init_scp(pdev, scp_domain_data, NUM_DOMAINS);
  200. + if (IS_ERR(scp))
  201. + return PTR_ERR(scp);
  202. +
  203. + mtk_register_power_domains(pdev, scp, NUM_DOMAINS);
  204. +
  205. + pd_data = &scp->pd_data;
  206. +
  207. + ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
  208. + pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
  209. + if (ret && IS_ENABLED(CONFIG_PM))
  210. + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
  211. +
  212. + ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
  213. + pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
  214. + if (ret && IS_ENABLED(CONFIG_PM))
  215. + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
  216. +
  217. + return 0;
  218. +}
  219. +
  220. +static const struct of_device_id of_scpsys_match_tbl[] = {
  221. + {
  222. + .compatible = "mediatek,mt8173-scpsys",
  223. + }, {
  224. + /* sentinel */
  225. + }
  226. +};
  227. +
  228. +static struct platform_driver scpsys_drv = {
  229. + .driver = {
  230. + .name = "mtk-scpsys-mt8173",
  231. + .owner = THIS_MODULE,
  232. + .of_match_table = of_match_ptr(of_scpsys_match_tbl),
  233. + },
  234. +};
  235. +
  236. +module_platform_driver_probe(scpsys_drv, scpsys_probe);
  237. diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
  238. index 4d4203c..a0943c5 100644
  239. --- a/drivers/soc/mediatek/mtk-scpsys.c
  240. +++ b/drivers/soc/mediatek/mtk-scpsys.c
  241. @@ -11,28 +11,14 @@
  242. * GNU General Public License for more details.
  243. */
  244. #include <linux/clk.h>
  245. -#include <linux/delay.h>
  246. #include <linux/io.h>
  247. -#include <linux/kernel.h>
  248. #include <linux/mfd/syscon.h>
  249. -#include <linux/module.h>
  250. -#include <linux/of_device.h>
  251. #include <linux/platform_device.h>
  252. #include <linux/pm_domain.h>
  253. -#include <linux/regmap.h>
  254. #include <linux/soc/mediatek/infracfg.h>
  255. -#include <dt-bindings/power/mt8173-power.h>
  256. -
  257. -#define SPM_VDE_PWR_CON 0x0210
  258. -#define SPM_MFG_PWR_CON 0x0214
  259. -#define SPM_VEN_PWR_CON 0x0230
  260. -#define SPM_ISP_PWR_CON 0x0238
  261. -#define SPM_DIS_PWR_CON 0x023c
  262. -#define SPM_VEN2_PWR_CON 0x0298
  263. -#define SPM_AUDIO_PWR_CON 0x029c
  264. -#define SPM_MFG_2D_PWR_CON 0x02c0
  265. -#define SPM_MFG_ASYNC_PWR_CON 0x02c4
  266. -#define SPM_USB_PWR_CON 0x02cc
  267. +
  268. +#include "mtk-scpsys.h"
  269. +
  270. #define SPM_PWR_STATUS 0x060c
  271. #define SPM_PWR_STATUS_2ND 0x0610
  272. @@ -42,153 +28,6 @@
  273. #define PWR_ON_2ND_BIT BIT(3)
  274. #define PWR_CLK_DIS_BIT BIT(4)
  275. -#define PWR_STATUS_DISP BIT(3)
  276. -#define PWR_STATUS_MFG BIT(4)
  277. -#define PWR_STATUS_ISP BIT(5)
  278. -#define PWR_STATUS_VDEC BIT(7)
  279. -#define PWR_STATUS_VENC_LT BIT(20)
  280. -#define PWR_STATUS_VENC BIT(21)
  281. -#define PWR_STATUS_MFG_2D BIT(22)
  282. -#define PWR_STATUS_MFG_ASYNC BIT(23)
  283. -#define PWR_STATUS_AUDIO BIT(24)
  284. -#define PWR_STATUS_USB BIT(25)
  285. -
  286. -enum clk_id {
  287. - MT8173_CLK_NONE,
  288. - MT8173_CLK_MM,
  289. - MT8173_CLK_MFG,
  290. - MT8173_CLK_VENC,
  291. - MT8173_CLK_VENC_LT,
  292. - MT8173_CLK_MAX,
  293. -};
  294. -
  295. -#define MAX_CLKS 2
  296. -
  297. -struct scp_domain_data {
  298. - const char *name;
  299. - u32 sta_mask;
  300. - int ctl_offs;
  301. - u32 sram_pdn_bits;
  302. - u32 sram_pdn_ack_bits;
  303. - u32 bus_prot_mask;
  304. - enum clk_id clk_id[MAX_CLKS];
  305. - bool active_wakeup;
  306. -};
  307. -
  308. -static const struct scp_domain_data scp_domain_data[] __initconst = {
  309. - [MT8173_POWER_DOMAIN_VDEC] = {
  310. - .name = "vdec",
  311. - .sta_mask = PWR_STATUS_VDEC,
  312. - .ctl_offs = SPM_VDE_PWR_CON,
  313. - .sram_pdn_bits = GENMASK(11, 8),
  314. - .sram_pdn_ack_bits = GENMASK(12, 12),
  315. - .clk_id = {MT8173_CLK_MM},
  316. - },
  317. - [MT8173_POWER_DOMAIN_VENC] = {
  318. - .name = "venc",
  319. - .sta_mask = PWR_STATUS_VENC,
  320. - .ctl_offs = SPM_VEN_PWR_CON,
  321. - .sram_pdn_bits = GENMASK(11, 8),
  322. - .sram_pdn_ack_bits = GENMASK(15, 12),
  323. - .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
  324. - },
  325. - [MT8173_POWER_DOMAIN_ISP] = {
  326. - .name = "isp",
  327. - .sta_mask = PWR_STATUS_ISP,
  328. - .ctl_offs = SPM_ISP_PWR_CON,
  329. - .sram_pdn_bits = GENMASK(11, 8),
  330. - .sram_pdn_ack_bits = GENMASK(13, 12),
  331. - .clk_id = {MT8173_CLK_MM},
  332. - },
  333. - [MT8173_POWER_DOMAIN_MM] = {
  334. - .name = "mm",
  335. - .sta_mask = PWR_STATUS_DISP,
  336. - .ctl_offs = SPM_DIS_PWR_CON,
  337. - .sram_pdn_bits = GENMASK(11, 8),
  338. - .sram_pdn_ack_bits = GENMASK(12, 12),
  339. - .clk_id = {MT8173_CLK_MM},
  340. - .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
  341. - MT8173_TOP_AXI_PROT_EN_MM_M1,
  342. - },
  343. - [MT8173_POWER_DOMAIN_VENC_LT] = {
  344. - .name = "venc_lt",
  345. - .sta_mask = PWR_STATUS_VENC_LT,
  346. - .ctl_offs = SPM_VEN2_PWR_CON,
  347. - .sram_pdn_bits = GENMASK(11, 8),
  348. - .sram_pdn_ack_bits = GENMASK(15, 12),
  349. - .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
  350. - },
  351. - [MT8173_POWER_DOMAIN_AUDIO] = {
  352. - .name = "audio",
  353. - .sta_mask = PWR_STATUS_AUDIO,
  354. - .ctl_offs = SPM_AUDIO_PWR_CON,
  355. - .sram_pdn_bits = GENMASK(11, 8),
  356. - .sram_pdn_ack_bits = GENMASK(15, 12),
  357. - .clk_id = {MT8173_CLK_NONE},
  358. - },
  359. - [MT8173_POWER_DOMAIN_USB] = {
  360. - .name = "usb",
  361. - .sta_mask = PWR_STATUS_USB,
  362. - .ctl_offs = SPM_USB_PWR_CON,
  363. - .sram_pdn_bits = GENMASK(11, 8),
  364. - .sram_pdn_ack_bits = GENMASK(15, 12),
  365. - .clk_id = {MT8173_CLK_NONE},
  366. - .active_wakeup = true,
  367. - },
  368. - [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
  369. - .name = "mfg_async",
  370. - .sta_mask = PWR_STATUS_MFG_ASYNC,
  371. - .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
  372. - .sram_pdn_bits = GENMASK(11, 8),
  373. - .sram_pdn_ack_bits = 0,
  374. - .clk_id = {MT8173_CLK_MFG},
  375. - },
  376. - [MT8173_POWER_DOMAIN_MFG_2D] = {
  377. - .name = "mfg_2d",
  378. - .sta_mask = PWR_STATUS_MFG_2D,
  379. - .ctl_offs = SPM_MFG_2D_PWR_CON,
  380. - .sram_pdn_bits = GENMASK(11, 8),
  381. - .sram_pdn_ack_bits = GENMASK(13, 12),
  382. - .clk_id = {MT8173_CLK_NONE},
  383. - },
  384. - [MT8173_POWER_DOMAIN_MFG] = {
  385. - .name = "mfg",
  386. - .sta_mask = PWR_STATUS_MFG,
  387. - .ctl_offs = SPM_MFG_PWR_CON,
  388. - .sram_pdn_bits = GENMASK(13, 8),
  389. - .sram_pdn_ack_bits = GENMASK(21, 16),
  390. - .clk_id = {MT8173_CLK_NONE},
  391. - .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
  392. - MT8173_TOP_AXI_PROT_EN_MFG_M0 |
  393. - MT8173_TOP_AXI_PROT_EN_MFG_M1 |
  394. - MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
  395. - },
  396. -};
  397. -
  398. -#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
  399. -
  400. -struct scp;
  401. -
  402. -struct scp_domain {
  403. - struct generic_pm_domain genpd;
  404. - struct scp *scp;
  405. - struct clk *clk[MAX_CLKS];
  406. - u32 sta_mask;
  407. - void __iomem *ctl_addr;
  408. - u32 sram_pdn_bits;
  409. - u32 sram_pdn_ack_bits;
  410. - u32 bus_prot_mask;
  411. - bool active_wakeup;
  412. -};
  413. -
  414. -struct scp {
  415. - struct scp_domain domains[NUM_DOMAINS];
  416. - struct genpd_onecell_data pd_data;
  417. - struct device *dev;
  418. - void __iomem *base;
  419. - struct regmap *infracfg;
  420. -};
  421. -
  422. static int scpsys_domain_is_on(struct scp_domain *scpd)
  423. {
  424. struct scp *scp = scpd->scp;
  425. @@ -398,63 +237,89 @@ static bool scpsys_active_wakeup(struct device *dev)
  426. return scpd->active_wakeup;
  427. }
  428. -static int __init scpsys_probe(struct platform_device *pdev)
  429. +static void init_clks(struct platform_device *pdev, struct clk *clk[CLK_MAX])
  430. +{
  431. + enum clk_id clk_ids[] = {
  432. + CLK_MM,
  433. + CLK_MFG,
  434. + CLK_VENC,
  435. + CLK_VENC_LT
  436. + };
  437. +
  438. + static const char * const clk_names[] = {
  439. + "mm",
  440. + "mfg",
  441. + "venc",
  442. + "venc_lt",
  443. + };
  444. +
  445. + int i;
  446. +
  447. + for (i = 0; i < ARRAY_SIZE(clk_ids); i++)
  448. + clk[clk_ids[i]] = devm_clk_get(&pdev->dev, clk_names[i]);
  449. +}
  450. +
  451. +struct scp *init_scp(struct platform_device *pdev,
  452. + const struct scp_domain_data *scp_domain_data, int num)
  453. {
  454. struct genpd_onecell_data *pd_data;
  455. struct resource *res;
  456. - int i, j, ret;
  457. + int i, j;
  458. struct scp *scp;
  459. - struct clk *clk[MT8173_CLK_MAX];
  460. + struct clk *clk[CLK_MAX];
  461. scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
  462. if (!scp)
  463. - return -ENOMEM;
  464. + return ERR_PTR(-ENOMEM);
  465. scp->dev = &pdev->dev;
  466. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  467. scp->base = devm_ioremap_resource(&pdev->dev, res);
  468. if (IS_ERR(scp->base))
  469. - return PTR_ERR(scp->base);
  470. -
  471. - pd_data = &scp->pd_data;
  472. -
  473. - pd_data->domains = devm_kzalloc(&pdev->dev,
  474. - sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
  475. - if (!pd_data->domains)
  476. - return -ENOMEM;
  477. -
  478. - clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
  479. - if (IS_ERR(clk[MT8173_CLK_MM]))
  480. - return PTR_ERR(clk[MT8173_CLK_MM]);
  481. -
  482. - clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
  483. - if (IS_ERR(clk[MT8173_CLK_MFG]))
  484. - return PTR_ERR(clk[MT8173_CLK_MFG]);
  485. -
  486. - clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
  487. - if (IS_ERR(clk[MT8173_CLK_VENC]))
  488. - return PTR_ERR(clk[MT8173_CLK_VENC]);
  489. -
  490. - clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
  491. - if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
  492. - return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
  493. + return ERR_CAST(scp->base);
  494. scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
  495. "infracfg");
  496. if (IS_ERR(scp->infracfg)) {
  497. dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
  498. PTR_ERR(scp->infracfg));
  499. - return PTR_ERR(scp->infracfg);
  500. + return ERR_CAST(scp->infracfg);
  501. }
  502. - pd_data->num_domains = NUM_DOMAINS;
  503. + scp->domains = devm_kzalloc(&pdev->dev,
  504. + sizeof(*scp->domains) * num, GFP_KERNEL);
  505. + if (!scp->domains)
  506. + return ERR_PTR(-ENOMEM);
  507. +
  508. + pd_data = &scp->pd_data;
  509. +
  510. + pd_data->domains = devm_kzalloc(&pdev->dev,
  511. + sizeof(*pd_data->domains) * num, GFP_KERNEL);
  512. + if (!pd_data->domains)
  513. + return ERR_PTR(-ENOMEM);
  514. - for (i = 0; i < NUM_DOMAINS; i++) {
  515. + pd_data->num_domains = num;
  516. +
  517. + init_clks(pdev, clk);
  518. +
  519. + for (i = 0; i < num; i++) {
  520. struct scp_domain *scpd = &scp->domains[i];
  521. struct generic_pm_domain *genpd = &scpd->genpd;
  522. const struct scp_domain_data *data = &scp_domain_data[i];
  523. + for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
  524. + struct clk *c = clk[data->clk_id[j]];
  525. +
  526. + if (IS_ERR(c)) {
  527. + dev_err(&pdev->dev, "%s: clk unavailable\n",
  528. + data->name);
  529. + return ERR_CAST(c);
  530. + }
  531. +
  532. + scpd->clk[j] = c;
  533. + }
  534. +
  535. pd_data->domains[i] = genpd;
  536. scpd->scp = scp;
  537. @@ -464,13 +329,25 @@ static int __init scpsys_probe(struct platform_device *pdev)
  538. scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
  539. scpd->bus_prot_mask = data->bus_prot_mask;
  540. scpd->active_wakeup = data->active_wakeup;
  541. - for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
  542. - scpd->clk[j] = clk[data->clk_id[j]];
  543. genpd->name = data->name;
  544. genpd->power_off = scpsys_power_off;
  545. genpd->power_on = scpsys_power_on;
  546. genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
  547. + }
  548. +
  549. + return scp;
  550. +}
  551. +
  552. +void mtk_register_power_domains(struct platform_device *pdev,
  553. + struct scp *scp, int num)
  554. +{
  555. + struct genpd_onecell_data *pd_data;
  556. + int i, ret;
  557. +
  558. + for (i = 0; i < num; i++) {
  559. + struct scp_domain *scpd = &scp->domains[i];
  560. + struct generic_pm_domain *genpd = &scpd->genpd;
  561. /*
  562. * Initially turn on all domains to make the domains usable
  563. @@ -489,37 +366,9 @@ static int __init scpsys_probe(struct platform_device *pdev)
  564. * valid.
  565. */
  566. - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
  567. - pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
  568. - if (ret && IS_ENABLED(CONFIG_PM))
  569. - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
  570. -
  571. - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
  572. - pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
  573. - if (ret && IS_ENABLED(CONFIG_PM))
  574. - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
  575. + pd_data = &scp->pd_data;
  576. ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
  577. if (ret)
  578. dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
  579. -
  580. - return 0;
  581. }
  582. -
  583. -static const struct of_device_id of_scpsys_match_tbl[] = {
  584. - {
  585. - .compatible = "mediatek,mt8173-scpsys",
  586. - }, {
  587. - /* sentinel */
  588. - }
  589. -};
  590. -
  591. -static struct platform_driver scpsys_drv = {
  592. - .driver = {
  593. - .name = "mtk-scpsys",
  594. - .owner = THIS_MODULE,
  595. - .of_match_table = of_match_ptr(of_scpsys_match_tbl),
  596. - },
  597. -};
  598. -
  599. -module_platform_driver_probe(scpsys_drv, scpsys_probe);
  600. diff --git a/drivers/soc/mediatek/mtk-scpsys.h b/drivers/soc/mediatek/mtk-scpsys.h
  601. new file mode 100644
  602. index 0000000..466728d
  603. --- /dev/null
  604. +++ b/drivers/soc/mediatek/mtk-scpsys.h
  605. @@ -0,0 +1,54 @@
  606. +#ifndef __DRV_SOC_MTK_H
  607. +#define __DRV_SOC_MTK_H
  608. +
  609. +enum clk_id {
  610. + CLK_NONE,
  611. + CLK_MM,
  612. + CLK_MFG,
  613. + CLK_VENC,
  614. + CLK_VENC_LT,
  615. + CLK_MAX,
  616. +};
  617. +
  618. +#define MAX_CLKS 2
  619. +
  620. +struct scp_domain_data {
  621. + const char *name;
  622. + u32 sta_mask;
  623. + int ctl_offs;
  624. + u32 sram_pdn_bits;
  625. + u32 sram_pdn_ack_bits;
  626. + u32 bus_prot_mask;
  627. + enum clk_id clk_id[MAX_CLKS];
  628. + bool active_wakeup;
  629. +};
  630. +
  631. +struct scp;
  632. +
  633. +struct scp_domain {
  634. + struct generic_pm_domain genpd;
  635. + struct scp *scp;
  636. + struct clk *clk[MAX_CLKS];
  637. + u32 sta_mask;
  638. + void __iomem *ctl_addr;
  639. + u32 sram_pdn_bits;
  640. + u32 sram_pdn_ack_bits;
  641. + u32 bus_prot_mask;
  642. + bool active_wakeup;
  643. +};
  644. +
  645. +struct scp {
  646. + struct scp_domain *domains;
  647. + struct genpd_onecell_data pd_data;
  648. + struct device *dev;
  649. + void __iomem *base;
  650. + struct regmap *infracfg;
  651. +};
  652. +
  653. +struct scp *init_scp(struct platform_device *pdev,
  654. + const struct scp_domain_data *scp_domain_data, int num);
  655. +
  656. +void mtk_register_power_domains(struct platform_device *pdev,
  657. + struct scp *scp, int num);
  658. +
  659. +#endif /* __DRV_SOC_MTK_H */
  660. --
  661. 1.7.10.4