aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2015-10-23 13:22:05 -0400
committerOlof Johansson <olof@lixom.net>2015-10-23 13:22:05 -0400
commit00b24d445495af5548b163fa6b525108ac713db7 (patch)
tree00886ed14b79457e5b8e73cb11a9f9e289875924 /drivers/soc
parentfc1f61f1c0b71a1c21123502c99712ad5b7d8e79 (diff)
parent0cda07001a9454f371b7a7edabad55d99ef91157 (diff)
Merge tag 'v4.3-next-soc' of https://github.com/mbgg/linux-mediatek into next/soc
Do the initial setting of the pmic wrap interrupt before requesting the interrupt. This fixes the corner-case where the pmic is initialized by the bootloader, but not the pmic watchdog. Add support for active wakeup to the scpsys. This allows to keep the power of a scpsys domain during suspend state. With version v4.3 new subsystem clocks are added to the clock dirver. In late init the kernel turns off all unused clocks. This can provoke a hang if the kernel tries to access the venc and venc_lt power domain registers. Add the necessary parent clocks for this power domains to the scpsys so that no random hang happens. The bootloader of mt6589, mt8135 and mt1827 does not turn on the arm-arch-timer. As there is no opensource bootloader in the near future for this architectures we enable the arch timer at kernel boot. We need the arch timer for SMP boot. Add support for SMP on mt6589, mt8127 and mt8135. * tag 'v4.3-next-soc' of https://github.com/mbgg/linux-mediatek: ARM: mediatek: add smp bringup code ARM: mediatek: enable gpt6 on boot up to make arch timer working soc: mediatek: Fix random hang up issue while kernel init soc: mediatek: add scpsys support active_wakeup soc: mediatek: Move the initial setting of pmic wrap interrupt before requesting irq. Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/mediatek/mtk-pmic-wrap.c10
-rw-r--r--drivers/soc/mediatek/mtk-scpsys.c83
2 files changed, 66 insertions, 27 deletions
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index 8bc7b41b09fd..105597a885cb 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -725,10 +725,6 @@ static int pwrap_init(struct pmic_wrapper *wrp)
725 pwrap_writel(wrp, 0x1, PWRAP_WACS2_EN); 725 pwrap_writel(wrp, 0x1, PWRAP_WACS2_EN);
726 pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD); 726 pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD);
727 pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN); 727 pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN);
728 pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
729 pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
730 pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
731 pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
732 728
733 if (pwrap_is_mt8135(wrp)) { 729 if (pwrap_is_mt8135(wrp)) {
734 /* enable pwrap events and pwrap bridge in AP side */ 730 /* enable pwrap events and pwrap bridge in AP side */
@@ -896,6 +892,12 @@ static int pwrap_probe(struct platform_device *pdev)
896 return -ENODEV; 892 return -ENODEV;
897 } 893 }
898 894
895 /* Initialize watchdog, may not be done by the bootloader */
896 pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
897 pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
898 pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
899 pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
900
899 irq = platform_get_irq(pdev, 0); 901 irq = platform_get_irq(pdev, 0);
900 ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH, 902 ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
901 "mt-pmic-pwrap", wrp); 903 "mt-pmic-pwrap", wrp);
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 164a7d8439b1..4d4203c896c4 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -54,12 +54,16 @@
54#define PWR_STATUS_USB BIT(25) 54#define PWR_STATUS_USB BIT(25)
55 55
56enum clk_id { 56enum clk_id {
57 MT8173_CLK_NONE,
57 MT8173_CLK_MM, 58 MT8173_CLK_MM,
58 MT8173_CLK_MFG, 59 MT8173_CLK_MFG,
59 MT8173_CLK_NONE, 60 MT8173_CLK_VENC,
60 MT8173_CLK_MAX = MT8173_CLK_NONE, 61 MT8173_CLK_VENC_LT,
62 MT8173_CLK_MAX,
61}; 63};
62 64
65#define MAX_CLKS 2
66
63struct scp_domain_data { 67struct scp_domain_data {
64 const char *name; 68 const char *name;
65 u32 sta_mask; 69 u32 sta_mask;
@@ -67,7 +71,8 @@ struct scp_domain_data {
67 u32 sram_pdn_bits; 71 u32 sram_pdn_bits;
68 u32 sram_pdn_ack_bits; 72 u32 sram_pdn_ack_bits;
69 u32 bus_prot_mask; 73 u32 bus_prot_mask;
70 enum clk_id clk_id; 74 enum clk_id clk_id[MAX_CLKS];
75 bool active_wakeup;
71}; 76};
72 77
73static const struct scp_domain_data scp_domain_data[] __initconst = { 78static const struct scp_domain_data scp_domain_data[] __initconst = {
@@ -77,7 +82,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
77 .ctl_offs = SPM_VDE_PWR_CON, 82 .ctl_offs = SPM_VDE_PWR_CON,
78 .sram_pdn_bits = GENMASK(11, 8), 83 .sram_pdn_bits = GENMASK(11, 8),
79 .sram_pdn_ack_bits = GENMASK(12, 12), 84 .sram_pdn_ack_bits = GENMASK(12, 12),
80 .clk_id = MT8173_CLK_MM, 85 .clk_id = {MT8173_CLK_MM},
81 }, 86 },
82 [MT8173_POWER_DOMAIN_VENC] = { 87 [MT8173_POWER_DOMAIN_VENC] = {
83 .name = "venc", 88 .name = "venc",
@@ -85,7 +90,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
85 .ctl_offs = SPM_VEN_PWR_CON, 90 .ctl_offs = SPM_VEN_PWR_CON,
86 .sram_pdn_bits = GENMASK(11, 8), 91 .sram_pdn_bits = GENMASK(11, 8),
87 .sram_pdn_ack_bits = GENMASK(15, 12), 92 .sram_pdn_ack_bits = GENMASK(15, 12),
88 .clk_id = MT8173_CLK_MM, 93 .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
89 }, 94 },
90 [MT8173_POWER_DOMAIN_ISP] = { 95 [MT8173_POWER_DOMAIN_ISP] = {
91 .name = "isp", 96 .name = "isp",
@@ -93,7 +98,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
93 .ctl_offs = SPM_ISP_PWR_CON, 98 .ctl_offs = SPM_ISP_PWR_CON,
94 .sram_pdn_bits = GENMASK(11, 8), 99 .sram_pdn_bits = GENMASK(11, 8),
95 .sram_pdn_ack_bits = GENMASK(13, 12), 100 .sram_pdn_ack_bits = GENMASK(13, 12),
96 .clk_id = MT8173_CLK_MM, 101 .clk_id = {MT8173_CLK_MM},
97 }, 102 },
98 [MT8173_POWER_DOMAIN_MM] = { 103 [MT8173_POWER_DOMAIN_MM] = {
99 .name = "mm", 104 .name = "mm",
@@ -101,7 +106,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
101 .ctl_offs = SPM_DIS_PWR_CON, 106 .ctl_offs = SPM_DIS_PWR_CON,
102 .sram_pdn_bits = GENMASK(11, 8), 107 .sram_pdn_bits = GENMASK(11, 8),
103 .sram_pdn_ack_bits = GENMASK(12, 12), 108 .sram_pdn_ack_bits = GENMASK(12, 12),
104 .clk_id = MT8173_CLK_MM, 109 .clk_id = {MT8173_CLK_MM},
105 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | 110 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
106 MT8173_TOP_AXI_PROT_EN_MM_M1, 111 MT8173_TOP_AXI_PROT_EN_MM_M1,
107 }, 112 },
@@ -111,7 +116,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
111 .ctl_offs = SPM_VEN2_PWR_CON, 116 .ctl_offs = SPM_VEN2_PWR_CON,
112 .sram_pdn_bits = GENMASK(11, 8), 117 .sram_pdn_bits = GENMASK(11, 8),
113 .sram_pdn_ack_bits = GENMASK(15, 12), 118 .sram_pdn_ack_bits = GENMASK(15, 12),
114 .clk_id = MT8173_CLK_MM, 119 .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
115 }, 120 },
116 [MT8173_POWER_DOMAIN_AUDIO] = { 121 [MT8173_POWER_DOMAIN_AUDIO] = {
117 .name = "audio", 122 .name = "audio",
@@ -119,7 +124,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
119 .ctl_offs = SPM_AUDIO_PWR_CON, 124 .ctl_offs = SPM_AUDIO_PWR_CON,
120 .sram_pdn_bits = GENMASK(11, 8), 125 .sram_pdn_bits = GENMASK(11, 8),
121 .sram_pdn_ack_bits = GENMASK(15, 12), 126 .sram_pdn_ack_bits = GENMASK(15, 12),
122 .clk_id = MT8173_CLK_NONE, 127 .clk_id = {MT8173_CLK_NONE},
123 }, 128 },
124 [MT8173_POWER_DOMAIN_USB] = { 129 [MT8173_POWER_DOMAIN_USB] = {
125 .name = "usb", 130 .name = "usb",
@@ -127,7 +132,8 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
127 .ctl_offs = SPM_USB_PWR_CON, 132 .ctl_offs = SPM_USB_PWR_CON,
128 .sram_pdn_bits = GENMASK(11, 8), 133 .sram_pdn_bits = GENMASK(11, 8),
129 .sram_pdn_ack_bits = GENMASK(15, 12), 134 .sram_pdn_ack_bits = GENMASK(15, 12),
130 .clk_id = MT8173_CLK_NONE, 135 .clk_id = {MT8173_CLK_NONE},
136 .active_wakeup = true,
131 }, 137 },
132 [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 138 [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
133 .name = "mfg_async", 139 .name = "mfg_async",
@@ -135,7 +141,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
135 .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 141 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
136 .sram_pdn_bits = GENMASK(11, 8), 142 .sram_pdn_bits = GENMASK(11, 8),
137 .sram_pdn_ack_bits = 0, 143 .sram_pdn_ack_bits = 0,
138 .clk_id = MT8173_CLK_MFG, 144 .clk_id = {MT8173_CLK_MFG},
139 }, 145 },
140 [MT8173_POWER_DOMAIN_MFG_2D] = { 146 [MT8173_POWER_DOMAIN_MFG_2D] = {
141 .name = "mfg_2d", 147 .name = "mfg_2d",
@@ -143,7 +149,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
143 .ctl_offs = SPM_MFG_2D_PWR_CON, 149 .ctl_offs = SPM_MFG_2D_PWR_CON,
144 .sram_pdn_bits = GENMASK(11, 8), 150 .sram_pdn_bits = GENMASK(11, 8),
145 .sram_pdn_ack_bits = GENMASK(13, 12), 151 .sram_pdn_ack_bits = GENMASK(13, 12),
146 .clk_id = MT8173_CLK_NONE, 152 .clk_id = {MT8173_CLK_NONE},
147 }, 153 },
148 [MT8173_POWER_DOMAIN_MFG] = { 154 [MT8173_POWER_DOMAIN_MFG] = {
149 .name = "mfg", 155 .name = "mfg",
@@ -151,7 +157,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
151 .ctl_offs = SPM_MFG_PWR_CON, 157 .ctl_offs = SPM_MFG_PWR_CON,
152 .sram_pdn_bits = GENMASK(13, 8), 158 .sram_pdn_bits = GENMASK(13, 8),
153 .sram_pdn_ack_bits = GENMASK(21, 16), 159 .sram_pdn_ack_bits = GENMASK(21, 16),
154 .clk_id = MT8173_CLK_NONE, 160 .clk_id = {MT8173_CLK_NONE},
155 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | 161 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
156 MT8173_TOP_AXI_PROT_EN_MFG_M0 | 162 MT8173_TOP_AXI_PROT_EN_MFG_M0 |
157 MT8173_TOP_AXI_PROT_EN_MFG_M1 | 163 MT8173_TOP_AXI_PROT_EN_MFG_M1 |
@@ -166,12 +172,13 @@ struct scp;
166struct scp_domain { 172struct scp_domain {
167 struct generic_pm_domain genpd; 173 struct generic_pm_domain genpd;
168 struct scp *scp; 174 struct scp *scp;
169 struct clk *clk; 175 struct clk *clk[MAX_CLKS];
170 u32 sta_mask; 176 u32 sta_mask;
171 void __iomem *ctl_addr; 177 void __iomem *ctl_addr;
172 u32 sram_pdn_bits; 178 u32 sram_pdn_bits;
173 u32 sram_pdn_ack_bits; 179 u32 sram_pdn_ack_bits;
174 u32 bus_prot_mask; 180 u32 bus_prot_mask;
181 bool active_wakeup;
175}; 182};
176 183
177struct scp { 184struct scp {
@@ -212,11 +219,16 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
212 u32 sram_pdn_ack = scpd->sram_pdn_ack_bits; 219 u32 sram_pdn_ack = scpd->sram_pdn_ack_bits;
213 u32 val; 220 u32 val;
214 int ret; 221 int ret;
222 int i;
223
224 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
225 ret = clk_prepare_enable(scpd->clk[i]);
226 if (ret) {
227 for (--i; i >= 0; i--)
228 clk_disable_unprepare(scpd->clk[i]);
215 229
216 if (scpd->clk) {
217 ret = clk_prepare_enable(scpd->clk);
218 if (ret)
219 goto err_clk; 230 goto err_clk;
231 }
220 } 232 }
221 233
222 val = readl(ctl_addr); 234 val = readl(ctl_addr);
@@ -282,7 +294,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
282 return 0; 294 return 0;
283 295
284err_pwr_ack: 296err_pwr_ack:
285 clk_disable_unprepare(scpd->clk); 297 for (i = MAX_CLKS - 1; i >= 0; i--) {
298 if (scpd->clk[i])
299 clk_disable_unprepare(scpd->clk[i]);
300 }
286err_clk: 301err_clk:
287 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name); 302 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
288 303
@@ -299,6 +314,7 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
299 u32 pdn_ack = scpd->sram_pdn_ack_bits; 314 u32 pdn_ack = scpd->sram_pdn_ack_bits;
300 u32 val; 315 u32 val;
301 int ret; 316 int ret;
317 int i;
302 318
303 if (scpd->bus_prot_mask) { 319 if (scpd->bus_prot_mask) {
304 ret = mtk_infracfg_set_bus_protection(scp->infracfg, 320 ret = mtk_infracfg_set_bus_protection(scp->infracfg,
@@ -360,8 +376,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
360 expired = true; 376 expired = true;
361 } 377 }
362 378
363 if (scpd->clk) 379 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
364 clk_disable_unprepare(scpd->clk); 380 clk_disable_unprepare(scpd->clk[i]);
365 381
366 return 0; 382 return 0;
367 383
@@ -371,11 +387,22 @@ out:
371 return ret; 387 return ret;
372} 388}
373 389
390static bool scpsys_active_wakeup(struct device *dev)
391{
392 struct generic_pm_domain *genpd;
393 struct scp_domain *scpd;
394
395 genpd = pd_to_genpd(dev->pm_domain);
396 scpd = container_of(genpd, struct scp_domain, genpd);
397
398 return scpd->active_wakeup;
399}
400
374static int __init scpsys_probe(struct platform_device *pdev) 401static int __init scpsys_probe(struct platform_device *pdev)
375{ 402{
376 struct genpd_onecell_data *pd_data; 403 struct genpd_onecell_data *pd_data;
377 struct resource *res; 404 struct resource *res;
378 int i, ret; 405 int i, j, ret;
379 struct scp *scp; 406 struct scp *scp;
380 struct clk *clk[MT8173_CLK_MAX]; 407 struct clk *clk[MT8173_CLK_MAX];
381 408
@@ -405,6 +432,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
405 if (IS_ERR(clk[MT8173_CLK_MFG])) 432 if (IS_ERR(clk[MT8173_CLK_MFG]))
406 return PTR_ERR(clk[MT8173_CLK_MFG]); 433 return PTR_ERR(clk[MT8173_CLK_MFG]);
407 434
435 clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
436 if (IS_ERR(clk[MT8173_CLK_VENC]))
437 return PTR_ERR(clk[MT8173_CLK_VENC]);
438
439 clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
440 if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
441 return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
442
408 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 443 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
409 "infracfg"); 444 "infracfg");
410 if (IS_ERR(scp->infracfg)) { 445 if (IS_ERR(scp->infracfg)) {
@@ -428,12 +463,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
428 scpd->sram_pdn_bits = data->sram_pdn_bits; 463 scpd->sram_pdn_bits = data->sram_pdn_bits;
429 scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits; 464 scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
430 scpd->bus_prot_mask = data->bus_prot_mask; 465 scpd->bus_prot_mask = data->bus_prot_mask;
431 if (data->clk_id != MT8173_CLK_NONE) 466 scpd->active_wakeup = data->active_wakeup;
432 scpd->clk = clk[data->clk_id]; 467 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
468 scpd->clk[j] = clk[data->clk_id[j]];
433 469
434 genpd->name = data->name; 470 genpd->name = data->name;
435 genpd->power_off = scpsys_power_off; 471 genpd->power_off = scpsys_power_off;
436 genpd->power_on = scpsys_power_on; 472 genpd->power_on = scpsys_power_on;
473 genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
437 474
438 /* 475 /*
439 * Initially turn on all domains to make the domains usable 476 * Initially turn on all domains to make the domains usable