aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/soc/mediatek/mtk-infracfg.c26
-rw-r--r--drivers/soc/mediatek/mtk-scpsys.c28
-rw-r--r--include/linux/soc/mediatek/infracfg.h7
3 files changed, 46 insertions, 15 deletions
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
index dba3055a9493..8c310de01e93 100644
--- a/drivers/soc/mediatek/mtk-infracfg.c
+++ b/drivers/soc/mediatek/mtk-infracfg.c
@@ -19,23 +19,33 @@
19 19
20#define INFRA_TOPAXI_PROTECTEN 0x0220 20#define INFRA_TOPAXI_PROTECTEN 0x0220
21#define INFRA_TOPAXI_PROTECTSTA1 0x0228 21#define INFRA_TOPAXI_PROTECTSTA1 0x0228
22#define INFRA_TOPAXI_PROTECTEN_SET 0x0260
23#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
22 24
23/** 25/**
24 * mtk_infracfg_set_bus_protection - enable bus protection 26 * mtk_infracfg_set_bus_protection - enable bus protection
25 * @regmap: The infracfg regmap 27 * @regmap: The infracfg regmap
26 * @mask: The mask containing the protection bits to be enabled. 28 * @mask: The mask containing the protection bits to be enabled.
29 * @reg_update: The boolean flag determines to set the protection bits
30 * by regmap_update_bits with enable register(PROTECTEN) or
31 * by regmap_write with set register(PROTECTEN_SET).
27 * 32 *
28 * This function enables the bus protection bits for disabled power 33 * This function enables the bus protection bits for disabled power
29 * domains so that the system does not hang when some unit accesses the 34 * domains so that the system does not hang when some unit accesses the
30 * bus while in power down. 35 * bus while in power down.
31 */ 36 */
32int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask) 37int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
38 bool reg_update)
33{ 39{
34 unsigned long expired; 40 unsigned long expired;
35 u32 val; 41 u32 val;
36 int ret; 42 int ret;
37 43
38 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask); 44 if (reg_update)
45 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
46 mask);
47 else
48 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
39 49
40 expired = jiffies + HZ; 50 expired = jiffies + HZ;
41 51
@@ -59,16 +69,24 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
59 * mtk_infracfg_clear_bus_protection - disable bus protection 69 * mtk_infracfg_clear_bus_protection - disable bus protection
60 * @regmap: The infracfg regmap 70 * @regmap: The infracfg regmap
61 * @mask: The mask containing the protection bits to be disabled. 71 * @mask: The mask containing the protection bits to be disabled.
72 * @reg_update: The boolean flag determines to clear the protection bits
73 * by regmap_update_bits with enable register(PROTECTEN) or
74 * by regmap_write with clear register(PROTECTEN_CLR).
62 * 75 *
63 * This function disables the bus protection bits previously enabled with 76 * This function disables the bus protection bits previously enabled with
64 * mtk_infracfg_set_bus_protection. 77 * mtk_infracfg_set_bus_protection.
65 */ 78 */
66int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask) 79
80int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
81 bool reg_update)
67{ 82{
68 unsigned long expired; 83 unsigned long expired;
69 int ret; 84 int ret;
70 85
71 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); 86 if (reg_update)
87 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
88 else
89 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
72 90
73 expired = jiffies + HZ; 91 expired = jiffies + HZ;
74 92
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index e570b6af2e6f..4c484b1d2f30 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -134,6 +134,7 @@ struct scp {
134 void __iomem *base; 134 void __iomem *base;
135 struct regmap *infracfg; 135 struct regmap *infracfg;
136 struct scp_ctrl_reg ctrl_reg; 136 struct scp_ctrl_reg ctrl_reg;
137 bool bus_prot_reg_update;
137}; 138};
138 139
139struct scp_subdomain { 140struct scp_subdomain {
@@ -147,6 +148,7 @@ struct scp_soc_data {
147 const struct scp_subdomain *subdomains; 148 const struct scp_subdomain *subdomains;
148 int num_subdomains; 149 int num_subdomains;
149 const struct scp_ctrl_reg regs; 150 const struct scp_ctrl_reg regs;
151 bool bus_prot_reg_update;
150}; 152};
151 153
152static int scpsys_domain_is_on(struct scp_domain *scpd) 154static int scpsys_domain_is_on(struct scp_domain *scpd)
@@ -254,7 +256,8 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
254 256
255 if (scpd->data->bus_prot_mask) { 257 if (scpd->data->bus_prot_mask) {
256 ret = mtk_infracfg_clear_bus_protection(scp->infracfg, 258 ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
257 scpd->data->bus_prot_mask); 259 scpd->data->bus_prot_mask,
260 scp->bus_prot_reg_update);
258 if (ret) 261 if (ret)
259 goto err_pwr_ack; 262 goto err_pwr_ack;
260 } 263 }
@@ -289,7 +292,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
289 292
290 if (scpd->data->bus_prot_mask) { 293 if (scpd->data->bus_prot_mask) {
291 ret = mtk_infracfg_set_bus_protection(scp->infracfg, 294 ret = mtk_infracfg_set_bus_protection(scp->infracfg,
292 scpd->data->bus_prot_mask); 295 scpd->data->bus_prot_mask,
296 scp->bus_prot_reg_update);
293 if (ret) 297 if (ret)
294 goto out; 298 goto out;
295 } 299 }
@@ -371,7 +375,8 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
371 375
372static struct scp *init_scp(struct platform_device *pdev, 376static struct scp *init_scp(struct platform_device *pdev,
373 const struct scp_domain_data *scp_domain_data, int num, 377 const struct scp_domain_data *scp_domain_data, int num,
374 const struct scp_ctrl_reg *scp_ctrl_reg) 378 const struct scp_ctrl_reg *scp_ctrl_reg,
379 bool bus_prot_reg_update)
375{ 380{
376 struct genpd_onecell_data *pd_data; 381 struct genpd_onecell_data *pd_data;
377 struct resource *res; 382 struct resource *res;
@@ -386,6 +391,8 @@ static struct scp *init_scp(struct platform_device *pdev,
386 scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs; 391 scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
387 scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs; 392 scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
388 393
394 scp->bus_prot_reg_update = bus_prot_reg_update;
395
389 scp->dev = &pdev->dev; 396 scp->dev = &pdev->dev;
390 397
391 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 398 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -806,7 +813,8 @@ static const struct scp_soc_data mt2701_data = {
806 .regs = { 813 .regs = {
807 .pwr_sta_offs = SPM_PWR_STATUS, 814 .pwr_sta_offs = SPM_PWR_STATUS,
808 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 815 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
809 } 816 },
817 .bus_prot_reg_update = true,
810}; 818};
811 819
812static const struct scp_soc_data mt6797_data = { 820static const struct scp_soc_data mt6797_data = {
@@ -817,7 +825,8 @@ static const struct scp_soc_data mt6797_data = {
817 .regs = { 825 .regs = {
818 .pwr_sta_offs = SPM_PWR_STATUS_MT6797, 826 .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
819 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797 827 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
820 } 828 },
829 .bus_prot_reg_update = true,
821}; 830};
822 831
823static const struct scp_soc_data mt7622_data = { 832static const struct scp_soc_data mt7622_data = {
@@ -826,7 +835,8 @@ static const struct scp_soc_data mt7622_data = {
826 .regs = { 835 .regs = {
827 .pwr_sta_offs = SPM_PWR_STATUS, 836 .pwr_sta_offs = SPM_PWR_STATUS,
828 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 837 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
829 } 838 },
839 .bus_prot_reg_update = true,
830}; 840};
831 841
832static const struct scp_soc_data mt8173_data = { 842static const struct scp_soc_data mt8173_data = {
@@ -837,7 +847,8 @@ static const struct scp_soc_data mt8173_data = {
837 .regs = { 847 .regs = {
838 .pwr_sta_offs = SPM_PWR_STATUS, 848 .pwr_sta_offs = SPM_PWR_STATUS,
839 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 849 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
840 } 850 },
851 .bus_prot_reg_update = true,
841}; 852};
842 853
843/* 854/*
@@ -874,7 +885,8 @@ static int scpsys_probe(struct platform_device *pdev)
874 match = of_match_device(of_scpsys_match_tbl, &pdev->dev); 885 match = of_match_device(of_scpsys_match_tbl, &pdev->dev);
875