mtk-scpsys.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. /*
  2. * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/clk.h>
  14. #include <linux/init.h>
  15. #include <linux/io.h>
  16. #include <linux/mfd/syscon.h>
  17. #include <linux/of_device.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/pm_domain.h>
  20. #include <linux/regulator/consumer.h>
  21. #include <linux/soc/mediatek/infracfg.h>
  22. #include <dt-bindings/power/mt2701-power.h>
  23. #include <dt-bindings/power/mt8173-power.h>
  24. #define SPM_VDE_PWR_CON 0x0210
  25. #define SPM_MFG_PWR_CON 0x0214
  26. #define SPM_VEN_PWR_CON 0x0230
  27. #define SPM_ISP_PWR_CON 0x0238
  28. #define SPM_DIS_PWR_CON 0x023c
  29. #define SPM_CONN_PWR_CON 0x0280
  30. #define SPM_VEN2_PWR_CON 0x0298
  31. #define SPM_AUDIO_PWR_CON 0x029c /* MT8173 */
  32. #define SPM_BDP_PWR_CON 0x029c /* MT2701 */
  33. #define SPM_ETH_PWR_CON 0x02a0
  34. #define SPM_HIF_PWR_CON 0x02a4
  35. #define SPM_IFR_MSC_PWR_CON 0x02a8
  36. #define SPM_MFG_2D_PWR_CON 0x02c0
  37. #define SPM_MFG_ASYNC_PWR_CON 0x02c4
  38. #define SPM_USB_PWR_CON 0x02cc
  39. #define SPM_PWR_STATUS 0x060c
  40. #define SPM_PWR_STATUS_2ND 0x0610
  41. #define PWR_RST_B_BIT BIT(0)
  42. #define PWR_ISO_BIT BIT(1)
  43. #define PWR_ON_BIT BIT(2)
  44. #define PWR_ON_2ND_BIT BIT(3)
  45. #define PWR_CLK_DIS_BIT BIT(4)
  46. #define PWR_STATUS_CONN BIT(1)
  47. #define PWR_STATUS_DISP BIT(3)
  48. #define PWR_STATUS_MFG BIT(4)
  49. #define PWR_STATUS_ISP BIT(5)
  50. #define PWR_STATUS_VDEC BIT(7)
  51. #define PWR_STATUS_BDP BIT(14)
  52. #define PWR_STATUS_ETH BIT(15)
  53. #define PWR_STATUS_HIF BIT(16)
  54. #define PWR_STATUS_IFR_MSC BIT(17)
  55. #define PWR_STATUS_VENC_LT BIT(20)
  56. #define PWR_STATUS_VENC BIT(21)
  57. #define PWR_STATUS_MFG_2D BIT(22)
  58. #define PWR_STATUS_MFG_ASYNC BIT(23)
  59. #define PWR_STATUS_AUDIO BIT(24)
  60. #define PWR_STATUS_USB BIT(25)
  61. enum clk_id {
  62. CLK_NONE,
  63. CLK_MM,
  64. CLK_MFG,
  65. CLK_VENC,
  66. CLK_VENC_LT,
  67. CLK_ETHIF,
  68. CLK_MAX,
  69. };
  70. static const char * const clk_names[] = {
  71. NULL,
  72. "mm",
  73. "mfg",
  74. "venc",
  75. "venc_lt",
  76. "ethif",
  77. NULL,
  78. };
  79. #define MAX_CLKS 2
  80. struct scp_domain_data {
  81. const char *name;
  82. u32 sta_mask;
  83. int ctl_offs;
  84. u32 sram_pdn_bits;
  85. u32 sram_pdn_ack_bits;
  86. u32 bus_prot_mask;
  87. enum clk_id clk_id[MAX_CLKS];
  88. bool active_wakeup;
  89. };
  90. struct scp;
  91. struct scp_domain {
  92. struct generic_pm_domain genpd;
  93. struct scp *scp;
  94. struct clk *clk[MAX_CLKS];
  95. const struct scp_domain_data *data;
  96. struct regulator *supply;
  97. };
  98. struct scp {
  99. struct scp_domain *domains;
  100. struct genpd_onecell_data pd_data;
  101. struct device *dev;
  102. void __iomem *base;
  103. struct regmap *infracfg;
  104. };
  105. static int scpsys_domain_is_on(struct scp_domain *scpd)
  106. {
  107. struct scp *scp = scpd->scp;
  108. u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->data->sta_mask;
  109. u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) &
  110. scpd->data->sta_mask;
  111. /*
  112. * A domain is on when both status bits are set. If only one is set
  113. * return an error. This happens while powering up a domain
  114. */
  115. if (status && status2)
  116. return true;
  117. if (!status && !status2)
  118. return false;
  119. return -EINVAL;
  120. }
  121. static int scpsys_power_on(struct generic_pm_domain *genpd)
  122. {
  123. struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
  124. struct scp *scp = scpd->scp;
  125. unsigned long timeout;
  126. bool expired;
  127. void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
  128. u32 sram_pdn_ack = scpd->data->sram_pdn_ack_bits;
  129. u32 val;
  130. int ret;
  131. int i;
  132. if (scpd->supply) {
  133. ret = regulator_enable(scpd->supply);
  134. if (ret)
  135. return ret;
  136. }
  137. for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
  138. ret = clk_prepare_enable(scpd->clk[i]);
  139. if (ret) {
  140. for (--i; i >= 0; i--)
  141. clk_disable_unprepare(scpd->clk[i]);
  142. goto err_clk;
  143. }
  144. }
  145. val = readl(ctl_addr);
  146. val |= PWR_ON_BIT;
  147. writel(val, ctl_addr);
  148. val |= PWR_ON_2ND_BIT;
  149. writel(val, ctl_addr);
  150. /* wait until PWR_ACK = 1 */
  151. timeout = jiffies + HZ;
  152. expired = false;
  153. while (1) {
  154. ret = scpsys_domain_is_on(scpd);
  155. if (ret > 0)
  156. break;
  157. if (expired) {
  158. ret = -ETIMEDOUT;
  159. goto err_pwr_ack;
  160. }
  161. cpu_relax();
  162. if (time_after(jiffies, timeout))
  163. expired = true;
  164. }
  165. val &= ~PWR_CLK_DIS_BIT;
  166. writel(val, ctl_addr);
  167. val &= ~PWR_ISO_BIT;
  168. writel(val, ctl_addr);
  169. val |= PWR_RST_B_BIT;
  170. writel(val, ctl_addr);
  171. val &= ~scpd->data->sram_pdn_bits;
  172. writel(val, ctl_addr);
  173. /* wait until SRAM_PDN_ACK all 0 */
  174. timeout = jiffies + HZ;
  175. expired = false;
  176. while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) {
  177. if (expired) {
  178. ret = -ETIMEDOUT;
  179. goto err_pwr_ack;
  180. }
  181. cpu_relax();
  182. if (time_after(jiffies, timeout))
  183. expired = true;
  184. }
  185. if (scpd->data->bus_prot_mask) {
  186. ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
  187. scpd->data->bus_prot_mask);
  188. if (ret)
  189. goto err_pwr_ack;
  190. }
  191. return 0;
  192. err_pwr_ack:
  193. for (i = MAX_CLKS - 1; i >= 0; i--) {
  194. if (scpd->clk[i])
  195. clk_disable_unprepare(scpd->clk[i]);
  196. }
  197. err_clk:
  198. if (scpd->supply)
  199. regulator_disable(scpd->supply);
  200. dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
  201. return ret;
  202. }
  203. static int scpsys_power_off(struct generic_pm_domain *genpd)
  204. {
  205. struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
  206. struct scp *scp = scpd->scp;
  207. unsigned long timeout;
  208. bool expired;
  209. void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
  210. u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
  211. u32 val;
  212. int ret;
  213. int i;
  214. if (scpd->data->bus_prot_mask) {
  215. ret = mtk_infracfg_set_bus_protection(scp->infracfg,
  216. scpd->data->bus_prot_mask);
  217. if (ret)
  218. goto out;
  219. }
  220. val = readl(ctl_addr);
  221. val |= scpd->data->sram_pdn_bits;
  222. writel(val, ctl_addr);
  223. /* wait until SRAM_PDN_ACK all 1 */
  224. timeout = jiffies + HZ;
  225. expired = false;
  226. while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) {
  227. if (expired) {
  228. ret = -ETIMEDOUT;
  229. goto out;
  230. }
  231. cpu_relax();
  232. if (time_after(jiffies, timeout))
  233. expired = true;
  234. }
  235. val |= PWR_ISO_BIT;
  236. writel(val, ctl_addr);
  237. val &= ~PWR_RST_B_BIT;
  238. writel(val, ctl_addr);
  239. val |= PWR_CLK_DIS_BIT;
  240. writel(val, ctl_addr);
  241. val &= ~PWR_ON_BIT;
  242. writel(val, ctl_addr);
  243. val &= ~PWR_ON_2ND_BIT;
  244. writel(val, ctl_addr);
  245. /* wait until PWR_ACK = 0 */
  246. timeout = jiffies + HZ;
  247. expired = false;
  248. while (1) {
  249. ret = scpsys_domain_is_on(scpd);
  250. if (ret == 0)
  251. break;
  252. if (expired) {
  253. ret = -ETIMEDOUT;
  254. goto out;
  255. }
  256. cpu_relax();
  257. if (time_after(jiffies, timeout))
  258. expired = true;
  259. }
  260. for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
  261. clk_disable_unprepare(scpd->clk[i]);
  262. if (scpd->supply)
  263. regulator_disable(scpd->supply);
  264. return 0;
  265. out:
  266. dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
  267. return ret;
  268. }
  269. static bool scpsys_active_wakeup(struct device *dev)
  270. {
  271. struct generic_pm_domain *genpd;
  272. struct scp_domain *scpd;
  273. genpd = pd_to_genpd(dev->pm_domain);
  274. scpd = container_of(genpd, struct scp_domain, genpd);
  275. return scpd->data->active_wakeup;
  276. }
  277. static void init_clks(struct platform_device *pdev, struct clk **clk)
  278. {
  279. int i;
  280. for (i = CLK_NONE + 1; i < CLK_MAX; i++)
  281. clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
  282. }
  283. static struct scp *init_scp(struct platform_device *pdev,
  284. const struct scp_domain_data *scp_domain_data, int num)
  285. {
  286. struct genpd_onecell_data *pd_data;
  287. struct resource *res;
  288. int i, j;
  289. struct scp *scp;
  290. struct clk *clk[CLK_MAX];
  291. scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
  292. if (!scp)
  293. return ERR_PTR(-ENOMEM);
  294. scp->dev = &pdev->dev;
  295. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  296. scp->base = devm_ioremap_resource(&pdev->dev, res);
  297. if (IS_ERR(scp->base))
  298. return ERR_CAST(scp->base);
  299. scp->domains = devm_kzalloc(&pdev->dev,
  300. sizeof(*scp->domains) * num, GFP_KERNEL);
  301. if (!scp->domains)
  302. return ERR_PTR(-ENOMEM);
  303. pd_data = &scp->pd_data;
  304. pd_data->domains = devm_kzalloc(&pdev->dev,
  305. sizeof(*pd_data->domains) * num, GFP_KERNEL);
  306. if (!pd_data->domains)
  307. return ERR_PTR(-ENOMEM);
  308. scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
  309. "infracfg");
  310. if (IS_ERR(scp->infracfg)) {
  311. dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
  312. PTR_ERR(scp->infracfg));
  313. return ERR_CAST(scp->infracfg);
  314. }
  315. for (i = 0; i < num; i++) {
  316. struct scp_domain *scpd = &scp->domains[i];
  317. const struct scp_domain_data *data = &scp_domain_data[i];
  318. scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
  319. if (IS_ERR(scpd->supply)) {
  320. if (PTR_ERR(scpd->supply) == -ENODEV)
  321. scpd->supply = NULL;
  322. else
  323. return ERR_CAST(scpd->supply);
  324. }
  325. }
  326. pd_data->num_domains = num;
  327. init_clks(pdev, clk);
  328. for (i = 0; i < num; i++) {
  329. struct scp_domain *scpd = &scp->domains[i];
  330. struct generic_pm_domain *genpd = &scpd->genpd;
  331. const struct scp_domain_data *data = &scp_domain_data[i];
  332. pd_data->domains[i] = genpd;
  333. scpd->scp = scp;
  334. scpd->data = data;
  335. for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
  336. struct clk *c = clk[data->clk_id[j]];
  337. if (IS_ERR(c)) {
  338. dev_err(&pdev->dev, "%s: clk unavailable\n",
  339. data->name);
  340. return ERR_CAST(c);
  341. }
  342. scpd->clk[j] = c;
  343. }
  344. genpd->name = data->name;
  345. genpd->power_off = scpsys_power_off;
  346. genpd->power_on = scpsys_power_on;
  347. genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
  348. }
  349. return scp;
  350. }
  351. static void mtk_register_power_domains(struct platform_device *pdev,
  352. struct scp *scp, int num)
  353. {
  354. struct genpd_onecell_data *pd_data;
  355. int i, ret;
  356. for (i = 0; i < num; i++) {
  357. struct scp_domain *scpd = &scp->domains[i];
  358. struct generic_pm_domain *genpd = &scpd->genpd;
  359. /*
  360. * Initially turn on all domains to make the domains usable
  361. * with !CONFIG_PM and to get the hardware in sync with the
  362. * software. The unused domains will be switched off during
  363. * late_init time.
  364. */
  365. genpd->power_on(genpd);
  366. pm_genpd_init(genpd, NULL, false);
  367. }
  368. /*
  369. * We are not allowed to fail here since there is no way to unregister
  370. * a power domain. Once registered above we have to keep the domains
  371. * valid.
  372. */
  373. pd_data = &scp->pd_data;
  374. ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
  375. if (ret)
  376. dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
  377. }
  378. /*
  379. * MT2701 power domain support
  380. */
  381. static const struct scp_domain_data scp_domain_data_mt2701[] = {
  382. [MT2701_POWER_DOMAIN_CONN] = {
  383. .name = "conn",
  384. .sta_mask = PWR_STATUS_CONN,
  385. .ctl_offs = SPM_CONN_PWR_CON,
  386. .bus_prot_mask = 0x0104,
  387. .clk_id = {CLK_NONE},
  388. .active_wakeup = true,
  389. },
  390. [MT2701_POWER_DOMAIN_DISP] = {
  391. .name = "disp",
  392. .sta_mask = PWR_STATUS_DISP,
  393. .ctl_offs = SPM_DIS_PWR_CON,
  394. .sram_pdn_bits = GENMASK(11, 8),
  395. .clk_id = {CLK_MM},
  396. .bus_prot_mask = 0x0002,
  397. .active_wakeup = true,
  398. },
  399. [MT2701_POWER_DOMAIN_MFG] = {
  400. .name = "mfg",
  401. .sta_mask = PWR_STATUS_MFG,
  402. .ctl_offs = SPM_MFG_PWR_CON,
  403. .sram_pdn_bits = GENMASK(11, 8),
  404. .sram_pdn_ack_bits = GENMASK(12, 12),
  405. .clk_id = {CLK_MFG},
  406. .active_wakeup = true,
  407. },
  408. [MT2701_POWER_DOMAIN_VDEC] = {
  409. .name = "vdec",
  410. .sta_mask = PWR_STATUS_VDEC,
  411. .ctl_offs = SPM_VDE_PWR_CON,
  412. .sram_pdn_bits = GENMASK(11, 8),
  413. .sram_pdn_ack_bits = GENMASK(12, 12),
  414. .clk_id = {CLK_MM},
  415. .active_wakeup = true,
  416. },
  417. [MT2701_POWER_DOMAIN_ISP] = {
  418. .name = "isp",
  419. .sta_mask = PWR_STATUS_ISP,
  420. .ctl_offs = SPM_ISP_PWR_CON,
  421. .sram_pdn_bits = GENMASK(11, 8),
  422. .sram_pdn_ack_bits = GENMASK(13, 12),
  423. .clk_id = {CLK_MM},
  424. .active_wakeup = true,
  425. },
  426. [MT2701_POWER_DOMAIN_BDP] = {
  427. .name = "bdp",
  428. .sta_mask = PWR_STATUS_BDP,
  429. .ctl_offs = SPM_BDP_PWR_CON,
  430. .sram_pdn_bits = GENMASK(11, 8),
  431. .clk_id = {CLK_NONE},
  432. .active_wakeup = true,
  433. },
  434. [MT2701_POWER_DOMAIN_ETH] = {
  435. .name = "eth",
  436. .sta_mask = PWR_STATUS_ETH,
  437. .ctl_offs = SPM_ETH_PWR_CON,
  438. .sram_pdn_bits = GENMASK(11, 8),
  439. .sram_pdn_ack_bits = GENMASK(15, 12),
  440. .clk_id = {CLK_ETHIF},
  441. .active_wakeup = true,
  442. },
  443. [MT2701_POWER_DOMAIN_HIF] = {
  444. .name = "hif",
  445. .sta_mask = PWR_STATUS_HIF,
  446. .ctl_offs = SPM_HIF_PWR_CON,
  447. .sram_pdn_bits = GENMASK(11, 8),
  448. .sram_pdn_ack_bits = GENMASK(15, 12),
  449. .clk_id = {CLK_ETHIF},
  450. .active_wakeup = true,
  451. },
  452. [MT2701_POWER_DOMAIN_IFR_MSC] = {
  453. .name = "ifr_msc",
  454. .sta_mask = PWR_STATUS_IFR_MSC,
  455. .ctl_offs = SPM_IFR_MSC_PWR_CON,
  456. .clk_id = {CLK_NONE},
  457. .active_wakeup = true,
  458. },
  459. };
  460. #define NUM_DOMAINS_MT2701 ARRAY_SIZE(scp_domain_data_mt2701)
  461. static int __init scpsys_probe_mt2701(struct platform_device *pdev)
  462. {
  463. struct scp *scp;
  464. scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701);
  465. if (IS_ERR(scp))
  466. return PTR_ERR(scp);
  467. mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701);
  468. return 0;
  469. }
  470. /*
  471. * MT8173 power domain support
  472. */
  473. static const struct scp_domain_data scp_domain_data_mt8173[] = {
  474. [MT8173_POWER_DOMAIN_VDEC] = {
  475. .name = "vdec",
  476. .sta_mask = PWR_STATUS_VDEC,
  477. .ctl_offs = SPM_VDE_PWR_CON,
  478. .sram_pdn_bits = GENMASK(11, 8),
  479. .sram_pdn_ack_bits = GENMASK(12, 12),
  480. .clk_id = {CLK_MM},
  481. },
  482. [MT8173_POWER_DOMAIN_VENC] = {
  483. .name = "venc",
  484. .sta_mask = PWR_STATUS_VENC,
  485. .ctl_offs = SPM_VEN_PWR_CON,
  486. .sram_pdn_bits = GENMASK(11, 8),
  487. .sram_pdn_ack_bits = GENMASK(15, 12),
  488. .clk_id = {CLK_MM, CLK_VENC},
  489. },
  490. [MT8173_POWER_DOMAIN_ISP] = {
  491. .name = "isp",
  492. .sta_mask = PWR_STATUS_ISP,
  493. .ctl_offs = SPM_ISP_PWR_CON,
  494. .sram_pdn_bits = GENMASK(11, 8),
  495. .sram_pdn_ack_bits = GENMASK(13, 12),
  496. .clk_id = {CLK_MM},
  497. },
  498. [MT8173_POWER_DOMAIN_MM] = {
  499. .name = "mm",
  500. .sta_mask = PWR_STATUS_DISP,
  501. .ctl_offs = SPM_DIS_PWR_CON,
  502. .sram_pdn_bits = GENMASK(11, 8),
  503. .sram_pdn_ack_bits = GENMASK(12, 12),
  504. .clk_id = {CLK_MM},
  505. .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
  506. MT8173_TOP_AXI_PROT_EN_MM_M1,
  507. },
  508. [MT8173_POWER_DOMAIN_VENC_LT] = {
  509. .name = "venc_lt",
  510. .sta_mask = PWR_STATUS_VENC_LT,
  511. .ctl_offs = SPM_VEN2_PWR_CON,
  512. .sram_pdn_bits = GENMASK(11, 8),
  513. .sram_pdn_ack_bits = GENMASK(15, 12),
  514. .clk_id = {CLK_MM, CLK_VENC_LT},
  515. },
  516. [MT8173_POWER_DOMAIN_AUDIO] = {
  517. .name = "audio",
  518. .sta_mask = PWR_STATUS_AUDIO,
  519. .ctl_offs = SPM_AUDIO_PWR_CON,
  520. .sram_pdn_bits = GENMASK(11, 8),
  521. .sram_pdn_ack_bits = GENMASK(15, 12),
  522. .clk_id = {CLK_NONE},
  523. },
  524. [MT8173_POWER_DOMAIN_USB] = {
  525. .name = "usb",
  526. .sta_mask = PWR_STATUS_USB,
  527. .ctl_offs = SPM_USB_PWR_CON,
  528. .sram_pdn_bits = GENMASK(11, 8),
  529. .sram_pdn_ack_bits = GENMASK(15, 12),
  530. .clk_id = {CLK_NONE},
  531. .active_wakeup = true,
  532. },
  533. [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
  534. .name = "mfg_async",
  535. .sta_mask = PWR_STATUS_MFG_ASYNC,
  536. .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
  537. .sram_pdn_bits = GENMASK(11, 8),
  538. .sram_pdn_ack_bits = 0,
  539. .clk_id = {CLK_MFG},
  540. },
  541. [MT8173_POWER_DOMAIN_MFG_2D] = {
  542. .name = "mfg_2d",
  543. .sta_mask = PWR_STATUS_MFG_2D,
  544. .ctl_offs = SPM_MFG_2D_PWR_CON,
  545. .sram_pdn_bits = GENMASK(11, 8),
  546. .sram_pdn_ack_bits = GENMASK(13, 12),
  547. .clk_id = {CLK_NONE},
  548. },
  549. [MT8173_POWER_DOMAIN_MFG] = {
  550. .name = "mfg",
  551. .sta_mask = PWR_STATUS_MFG,
  552. .ctl_offs = SPM_MFG_PWR_CON,
  553. .sram_pdn_bits = GENMASK(13, 8),
  554. .sram_pdn_ack_bits = GENMASK(21, 16),
  555. .clk_id = {CLK_NONE},
  556. .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
  557. MT8173_TOP_AXI_PROT_EN_MFG_M0 |
  558. MT8173_TOP_AXI_PROT_EN_MFG_M1 |
  559. MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
  560. },
  561. };
  562. #define NUM_DOMAINS_MT8173 ARRAY_SIZE(scp_domain_data_mt8173)
  563. static int __init scpsys_probe_mt8173(struct platform_device *pdev)
  564. {
  565. struct scp *scp;
  566. struct genpd_onecell_data *pd_data;
  567. int ret;
  568. scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173);
  569. if (IS_ERR(scp))
  570. return PTR_ERR(scp);
  571. mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
  572. pd_data = &scp->pd_data;
  573. ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
  574. pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
  575. if (ret && IS_ENABLED(CONFIG_PM))
  576. dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
  577. ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
  578. pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
  579. if (ret && IS_ENABLED(CONFIG_PM))
  580. dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
  581. return 0;
  582. }
  583. /*
  584. * scpsys driver init
  585. */
  586. static const struct of_device_id of_scpsys_match_tbl[] = {
  587. {
  588. .compatible = "mediatek,mt2701-scpsys",
  589. .data = scpsys_probe_mt2701,
  590. }, {
  591. .compatible = "mediatek,mt8173-scpsys",
  592. .data = scpsys_probe_mt8173,
  593. }, {
  594. /* sentinel */
  595. }
  596. };
  597. static int scpsys_probe(struct platform_device *pdev)
  598. {
  599. int (*probe)(struct platform_device *);
  600. const struct of_device_id *of_id;
  601. of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node);
  602. if (!of_id || !of_id->data)
  603. return -EINVAL;
  604. probe = of_id->data;
  605. return probe(pdev);
  606. }
  607. static struct platform_driver scpsys_drv = {
  608. .probe = scpsys_probe,
  609. .driver = {
  610. .name = "mtk-scpsys",
  611. .suppress_bind_attrs = true,
  612. .owner = THIS_MODULE,
  613. .of_match_table = of_match_ptr(of_scpsys_match_tbl),
  614. },
  615. };
  616. builtin_platform_driver(scpsys_drv);