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

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