pmdomain core:
- Don't clear suspended_count at genpd_prepare() - Update the rejected/usage counters at system suspend too pmdomain providers: - ti-sci: Fix duplicate PD referrals - mediatek: Add MT8188 buck isolation setting - renesas: Add R-Car M3-W power-off delay quirk - renesas: Split R-Car M3-W and M3-W+ sub-drivers cpuidle-psci: - Update MAINTAINERS to set a git for DT IDLE PM DOMAIN/ARM PSCI PM DOMAIN - Update init level to core_initcall() - Drop superfluous wrappers psci_dt_attach|detach_cpu() -----BEGIN PGP SIGNATURE----- iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmZF99kXHHVsZi5oYW5z c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCnEQxAAsh+sLW0icCOMUcnhX9OtFh5r XbL96l0SHZgCj+1hQS36nfnXO1GYdrlctlQ/9ikcKzuXSxscG0l7fwLE30If29w0 KejTM6sieu+Yr8Jt5NRDwLZWIOVujP1hlnvNJPa/fLJmQm2KjORKWPPMQOm8tYdk reav6OkE7KKZseihVaGEoNzq2vjeQLGvcJaXjmSFeBZfpBo3BYnBvwMDDLdO9NGB +zDiAwREUYBTbjEB7djSVCQhTe5sseg57Iy58g57jupbBYbGz1sctf0JBFq56foV pArUMqkJx1TVUo8JGHp7OqddpwpndmrdH0JoGa3/Ow+3iJSgQsDwD/vSS1HZ3jCR evVWfZdkZ9PK0tK5WYWTljOdEaCqLlHco8Uce0q2lyd5P5AA200Ihw3W2a8tEmQQ gzZRZWhRCRXKE66OrBKz17ji+0ORS8Fcz69lAcAg0ZMdsFpoAlPU8becd/Q4kQDI KytDofCTS+3J1Dr4YoHUxkRAua5fzVgNGZGj4NdVgu1/43tLQ3ZxEbzGa3V4YIX8 Fc4ay79B7/ufn9xu7BCVPClt9L0P6qgpe/oUtKmB5XGN3MJaMQuekjttwOu9qCAU Ayvo5uuGGIeYx/LtX5oNYA3nl9PYIOYoGZOwY/hd9uTLyekkoyXEs/AEuSFM/Rbd m9bCFGceporKjZb8tw8= =dS2r -----END PGP SIGNATURE----- Merge tag 'pmdomain-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm Pull pmdomain updates from Ulf Hansson: "pmdomain core: - Don't clear suspended_count at genpd_prepare() - Update the rejected/usage counters at system suspend too pmdomain providers: - ti-sci: Fix duplicate PD referrals - mediatek: Add MT8188 buck isolation setting - renesas: Add R-Car M3-W power-off delay quirk - renesas: Split R-Car M3-W and M3-W+ sub-drivers cpuidle-psci: - Update MAINTAINERS to set a git for DT IDLE PM DOMAIN/ARM PSCI PM DOMAIN - Update init level to core_initcall() - Drop superfluous wrappers psci_dt_attach|detach_cpu()" * tag 'pmdomain-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: pmdomain: ti-sci: Fix duplicate PD referrals pmdomain: core: Don't clear suspended_count at genpd_prepare() pmdomain: core: Update the rejected/usage counters at system suspend too pmdomain: renesas: rcar-sysc: Add R-Car M3-W power-off delay quirk pmdomain: renesas: rcar-sysc: Remove rcar_sysc_nullify() helper pmdomain: renesas: rcar-sysc: Split R-Car M3-W and M3-W+ sub-drivers pmdomain: renesas: rcar-sysc: Absorb rcar_sysc_ch into rcar_sysc_pd MAINTAINERS: Add a git for the DT IDLE PM DOMAIN MAINTAINERS: Add a git for the ARM PSCI PM DOMAIN cpuidle: psci: Update init level to core_initcall() cpuidle: psci: Drop superfluous wrappers psci_dt_attach|detach_cpu() pmdomain: mediatek: Add MT8188 buck isolation setting pmdomain: mediatek: scpsys: drop driver owner assignment
This commit is contained in:
commit
8b35a3bb33
@ -5658,6 +5658,7 @@ M: Ulf Hansson <ulf.hansson@linaro.org>
|
|||||||
L: linux-pm@vger.kernel.org
|
L: linux-pm@vger.kernel.org
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Supported
|
S: Supported
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git
|
||||||
F: drivers/cpuidle/cpuidle-psci-domain.c
|
F: drivers/cpuidle/cpuidle-psci-domain.c
|
||||||
F: drivers/cpuidle/cpuidle-psci.h
|
F: drivers/cpuidle/cpuidle-psci.h
|
||||||
|
|
||||||
@ -5665,6 +5666,7 @@ CPUIDLE DRIVER - DT IDLE PM DOMAIN
|
|||||||
M: Ulf Hansson <ulf.hansson@linaro.org>
|
M: Ulf Hansson <ulf.hansson@linaro.org>
|
||||||
L: linux-pm@vger.kernel.org
|
L: linux-pm@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git
|
||||||
F: drivers/cpuidle/dt_idle_genpd.c
|
F: drivers/cpuidle/dt_idle_genpd.c
|
||||||
F: drivers/cpuidle/dt_idle_genpd.h
|
F: drivers/cpuidle/dt_idle_genpd.h
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include "cpuidle-psci.h"
|
#include "cpuidle-psci.h"
|
||||||
|
#include "dt_idle_genpd.h"
|
||||||
|
|
||||||
struct psci_pd_provider {
|
struct psci_pd_provider {
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
@ -200,4 +201,4 @@ static int __init psci_idle_init_domains(void)
|
|||||||
{
|
{
|
||||||
return platform_driver_register(&psci_cpuidle_domain_driver);
|
return platform_driver_register(&psci_cpuidle_domain_driver);
|
||||||
}
|
}
|
||||||
subsys_initcall(psci_idle_init_domains);
|
core_initcall(psci_idle_init_domains);
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "cpuidle-psci.h"
|
#include "cpuidle-psci.h"
|
||||||
#include "dt_idle_states.h"
|
#include "dt_idle_states.h"
|
||||||
|
#include "dt_idle_genpd.h"
|
||||||
|
|
||||||
struct psci_cpuidle_data {
|
struct psci_cpuidle_data {
|
||||||
u32 *psci_states;
|
u32 *psci_states;
|
||||||
@ -224,7 +225,7 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
|
|||||||
if (IS_ENABLED(CONFIG_PREEMPT_RT))
|
if (IS_ENABLED(CONFIG_PREEMPT_RT))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
data->dev = psci_dt_attach_cpu(cpu);
|
data->dev = dt_idle_attach_cpu(cpu, "psci");
|
||||||
if (IS_ERR_OR_NULL(data->dev))
|
if (IS_ERR_OR_NULL(data->dev))
|
||||||
return PTR_ERR_OR_ZERO(data->dev);
|
return PTR_ERR_OR_ZERO(data->dev);
|
||||||
|
|
||||||
@ -311,7 +312,7 @@ static void psci_cpu_deinit_idle(int cpu)
|
|||||||
{
|
{
|
||||||
struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
|
struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
|
||||||
|
|
||||||
psci_dt_detach_cpu(data->dev);
|
dt_idle_detach_cpu(data->dev);
|
||||||
psci_cpuidle_use_cpuhp = false;
|
psci_cpuidle_use_cpuhp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,29 +3,9 @@
|
|||||||
#ifndef __CPUIDLE_PSCI_H
|
#ifndef __CPUIDLE_PSCI_H
|
||||||
#define __CPUIDLE_PSCI_H
|
#define __CPUIDLE_PSCI_H
|
||||||
|
|
||||||
struct device;
|
|
||||||
struct device_node;
|
struct device_node;
|
||||||
|
|
||||||
void psci_set_domain_state(u32 state);
|
void psci_set_domain_state(u32 state);
|
||||||
int psci_dt_parse_state_node(struct device_node *np, u32 *state);
|
int psci_dt_parse_state_node(struct device_node *np, u32 *state);
|
||||||
|
|
||||||
#ifdef CONFIG_ARM_PSCI_CPUIDLE_DOMAIN
|
|
||||||
|
|
||||||
#include "dt_idle_genpd.h"
|
|
||||||
|
|
||||||
static inline struct device *psci_dt_attach_cpu(int cpu)
|
|
||||||
{
|
|
||||||
return dt_idle_attach_cpu(cpu, "psci");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void psci_dt_detach_cpu(struct device *dev)
|
|
||||||
{
|
|
||||||
dt_idle_detach_cpu(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
static inline struct device *psci_dt_attach_cpu(int cpu) { return NULL; }
|
|
||||||
static inline void psci_dt_detach_cpu(struct device *dev) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __CPUIDLE_PSCI_H */
|
#endif /* __CPUIDLE_PSCI_H */
|
||||||
|
@ -1178,8 +1178,12 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
|
|||||||
|
|
||||||
/* Choose the deepest state when suspending */
|
/* Choose the deepest state when suspending */
|
||||||
genpd->state_idx = genpd->state_count - 1;
|
genpd->state_idx = genpd->state_count - 1;
|
||||||
if (_genpd_power_off(genpd, false))
|
if (_genpd_power_off(genpd, false)) {
|
||||||
|
genpd->states[genpd->state_idx].rejected++;
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
genpd->states[genpd->state_idx].usage++;
|
||||||
|
}
|
||||||
|
|
||||||
genpd->status = GENPD_STATE_OFF;
|
genpd->status = GENPD_STATE_OFF;
|
||||||
|
|
||||||
@ -1251,10 +1255,7 @@ static int genpd_prepare(struct device *dev)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
genpd_lock(genpd);
|
genpd_lock(genpd);
|
||||||
|
genpd->prepared_count++;
|
||||||
if (genpd->prepared_count++ == 0)
|
|
||||||
genpd->suspended_count = 0;
|
|
||||||
|
|
||||||
genpd_unlock(genpd);
|
genpd_unlock(genpd);
|
||||||
|
|
||||||
ret = pm_generic_prepare(dev);
|
ret = pm_generic_prepare(dev);
|
||||||
|
@ -175,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
|
|||||||
.ctl_offs = 0x35C,
|
.ctl_offs = 0x35C,
|
||||||
.pwr_sta_offs = 0x16C,
|
.pwr_sta_offs = 0x16C,
|
||||||
.pwr_sta2nd_offs = 0x170,
|
.pwr_sta2nd_offs = 0x170,
|
||||||
|
.ext_buck_iso_offs = 0x3EC,
|
||||||
|
.ext_buck_iso_mask = BIT(10),
|
||||||
.bp_cfg = {
|
.bp_cfg = {
|
||||||
BUS_PROT_WR(INFRA,
|
BUS_PROT_WR(INFRA,
|
||||||
MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1,
|
MT8188_TOP_AXI_PROT_EN_2_ADSP_AO_STEP1,
|
||||||
@ -187,7 +189,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
|
|||||||
MT8188_TOP_AXI_PROT_EN_2_CLR,
|
MT8188_TOP_AXI_PROT_EN_2_CLR,
|
||||||
MT8188_TOP_AXI_PROT_EN_2_STA),
|
MT8188_TOP_AXI_PROT_EN_2_STA),
|
||||||
},
|
},
|
||||||
.caps = MTK_SCPD_ALWAYS_ON,
|
.caps = MTK_SCPD_ALWAYS_ON | MTK_SCPD_EXT_BUCK_ISO,
|
||||||
},
|
},
|
||||||
[MT8188_POWER_DOMAIN_ADSP_INFRA] = {
|
[MT8188_POWER_DOMAIN_ADSP_INFRA] = {
|
||||||
.name = "adsp_infra",
|
.name = "adsp_infra",
|
||||||
@ -524,6 +526,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
|
|||||||
.ctl_offs = 0x3A4,
|
.ctl_offs = 0x3A4,
|
||||||
.pwr_sta_offs = 0x16C,
|
.pwr_sta_offs = 0x16C,
|
||||||
.pwr_sta2nd_offs = 0x170,
|
.pwr_sta2nd_offs = 0x170,
|
||||||
|
.ext_buck_iso_offs = 0x3EC,
|
||||||
|
.ext_buck_iso_mask = BIT(12),
|
||||||
.bp_cfg = {
|
.bp_cfg = {
|
||||||
BUS_PROT_WR(INFRA,
|
BUS_PROT_WR(INFRA,
|
||||||
MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1,
|
MT8188_TOP_AXI_PROT_EN_MM_IMG_VCORE_STEP1,
|
||||||
@ -541,7 +545,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
|
|||||||
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
|
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||||
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
|
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
|
||||||
},
|
},
|
||||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY,
|
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY |
|
||||||
|
MTK_SCPD_EXT_BUCK_ISO,
|
||||||
},
|
},
|
||||||
[MT8188_POWER_DOMAIN_IMG_MAIN] = {
|
[MT8188_POWER_DOMAIN_IMG_MAIN] = {
|
||||||
.name = "img_main",
|
.name = "img_main",
|
||||||
@ -591,6 +596,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
|
|||||||
.ctl_offs = 0x3A0,
|
.ctl_offs = 0x3A0,
|
||||||
.pwr_sta_offs = 0x16C,
|
.pwr_sta_offs = 0x16C,
|
||||||
.pwr_sta2nd_offs = 0x170,
|
.pwr_sta2nd_offs = 0x170,
|
||||||
|
.ext_buck_iso_offs = 0x3EC,
|
||||||
|
.ext_buck_iso_mask = BIT(11),
|
||||||
.bp_cfg = {
|
.bp_cfg = {
|
||||||
BUS_PROT_WR(INFRA,
|
BUS_PROT_WR(INFRA,
|
||||||
MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1,
|
MT8188_TOP_AXI_PROT_EN_MM_CAM_VCORE_STEP1,
|
||||||
@ -618,7 +625,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
|
|||||||
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
|
MT8188_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||||
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
|
MT8188_TOP_AXI_PROT_EN_MM_2_STA),
|
||||||
},
|
},
|
||||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY,
|
.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY |
|
||||||
|
MTK_SCPD_EXT_BUCK_ISO,
|
||||||
},
|
},
|
||||||
[MT8188_POWER_DOMAIN_CAM_MAIN] = {
|
[MT8188_POWER_DOMAIN_CAM_MAIN] = {
|
||||||
.name = "cam_main",
|
.name = "cam_main",
|
||||||
|
@ -1138,7 +1138,6 @@ static struct platform_driver scpsys_drv = {
|
|||||||
.driver = {
|
.driver = {
|
||||||
.name = "mtk-scpsys",
|
.name = "mtk-scpsys",
|
||||||
.suppress_bind_attrs = true,
|
.suppress_bind_attrs = true,
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.of_match_table = of_scpsys_match_tbl,
|
.of_match_table = of_scpsys_match_tbl,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -14,8 +14,8 @@ obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o
|
|||||||
obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o
|
obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o
|
||||||
obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o
|
obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o
|
||||||
obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o
|
obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o
|
||||||
obj-$(CONFIG_SYSC_R8A77960) += r8a7796-sysc.o
|
obj-$(CONFIG_SYSC_R8A77960) += r8a77960-sysc.o
|
||||||
obj-$(CONFIG_SYSC_R8A77961) += r8a7796-sysc.o
|
obj-$(CONFIG_SYSC_R8A77961) += r8a77961-sysc.o
|
||||||
obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o
|
obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o
|
||||||
obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o
|
obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o
|
||||||
obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o
|
obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o
|
||||||
|
49
drivers/pmdomain/renesas/r8a77960-sysc.c
Normal file
49
drivers/pmdomain/renesas/r8a77960-sysc.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Renesas R-Car M3-W System Controller
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Glider bvba
|
||||||
|
* Copyright (C) 2018-2019 Renesas Electronics Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bits.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
|
#include <dt-bindings/power/r8a7796-sysc.h>
|
||||||
|
|
||||||
|
#include "rcar-sysc.h"
|
||||||
|
|
||||||
|
static const struct rcar_sysc_area r8a77960_areas[] __initconst = {
|
||||||
|
{ "always-on", 0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||||
|
{ "ca57-scu", 0x1c0, 0, R8A7796_PD_CA57_SCU, R8A7796_PD_ALWAYS_ON,
|
||||||
|
PD_SCU },
|
||||||
|
{ "ca57-cpu0", 0x80, 0, R8A7796_PD_CA57_CPU0, R8A7796_PD_CA57_SCU,
|
||||||
|
PD_CPU_NOCR },
|
||||||
|
{ "ca57-cpu1", 0x80, 1, R8A7796_PD_CA57_CPU1, R8A7796_PD_CA57_SCU,
|
||||||
|
PD_CPU_NOCR },
|
||||||
|
{ "ca53-scu", 0x140, 0, R8A7796_PD_CA53_SCU, R8A7796_PD_ALWAYS_ON,
|
||||||
|
PD_SCU },
|
||||||
|
{ "ca53-cpu0", 0x200, 0, R8A7796_PD_CA53_CPU0, R8A7796_PD_CA53_SCU,
|
||||||
|
PD_CPU_NOCR },
|
||||||
|
{ "ca53-cpu1", 0x200, 1, R8A7796_PD_CA53_CPU1, R8A7796_PD_CA53_SCU,
|
||||||
|
PD_CPU_NOCR },
|
||||||
|
{ "ca53-cpu2", 0x200, 2, R8A7796_PD_CA53_CPU2, R8A7796_PD_CA53_SCU,
|
||||||
|
PD_CPU_NOCR },
|
||||||
|
{ "ca53-cpu3", 0x200, 3, R8A7796_PD_CA53_CPU3, R8A7796_PD_CA53_SCU,
|
||||||
|
PD_CPU_NOCR },
|
||||||
|
{ "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON },
|
||||||
|
{ "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON,
|
||||||
|
PD_OFF_DELAY },
|
||||||
|
{ "a2vc0", 0x3c0, 0, R8A7796_PD_A2VC0, R8A7796_PD_A3VC },
|
||||||
|
{ "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC },
|
||||||
|
{ "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON },
|
||||||
|
{ "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A },
|
||||||
|
{ "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON,
|
||||||
|
PD_OFF_DELAY },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const struct rcar_sysc_info r8a77960_sysc_info __initconst = {
|
||||||
|
.areas = r8a77960_areas,
|
||||||
|
.num_areas = ARRAY_SIZE(r8a77960_areas),
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Renesas R-Car M3-W/W+ System Controller
|
* Renesas R-Car M3-W+ System Controller
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Glider bvba
|
* Copyright (C) 2016 Glider bvba
|
||||||
* Copyright (C) 2018-2019 Renesas Electronics Corporation
|
* Copyright (C) 2018-2019 Renesas Electronics Corporation
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "rcar-sysc.h"
|
#include "rcar-sysc.h"
|
||||||
|
|
||||||
static struct rcar_sysc_area r8a7796_areas[] __initdata = {
|
static const struct rcar_sysc_area r8a77961_areas[] __initconst = {
|
||||||
{ "always-on", 0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
{ "always-on", 0, 0, R8A7796_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
|
||||||
{ "ca57-scu", 0x1c0, 0, R8A7796_PD_CA57_SCU, R8A7796_PD_ALWAYS_ON,
|
{ "ca57-scu", 0x1c0, 0, R8A7796_PD_CA57_SCU, R8A7796_PD_ALWAYS_ON,
|
||||||
PD_SCU },
|
PD_SCU },
|
||||||
@ -33,35 +33,15 @@ static struct rcar_sysc_area r8a7796_areas[] __initdata = {
|
|||||||
PD_CPU_NOCR },
|
PD_CPU_NOCR },
|
||||||
{ "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON },
|
{ "cr7", 0x240, 0, R8A7796_PD_CR7, R8A7796_PD_ALWAYS_ON },
|
||||||
{ "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON },
|
{ "a3vc", 0x380, 0, R8A7796_PD_A3VC, R8A7796_PD_ALWAYS_ON },
|
||||||
{ "a2vc0", 0x3c0, 0, R8A7796_PD_A2VC0, R8A7796_PD_A3VC },
|
|
||||||
{ "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC },
|
{ "a2vc1", 0x3c0, 1, R8A7796_PD_A2VC1, R8A7796_PD_A3VC },
|
||||||
{ "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON },
|
{ "3dg-a", 0x100, 0, R8A7796_PD_3DG_A, R8A7796_PD_ALWAYS_ON },
|
||||||
{ "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A },
|
{ "3dg-b", 0x100, 1, R8A7796_PD_3DG_B, R8A7796_PD_3DG_A },
|
||||||
{ "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON },
|
{ "a3ir", 0x180, 0, R8A7796_PD_A3IR, R8A7796_PD_ALWAYS_ON },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYSC_R8A77960
|
|
||||||
const struct rcar_sysc_info r8a77960_sysc_info __initconst = {
|
|
||||||
.areas = r8a7796_areas,
|
|
||||||
.num_areas = ARRAY_SIZE(r8a7796_areas),
|
|
||||||
};
|
|
||||||
#endif /* CONFIG_SYSC_R8A77960 */
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYSC_R8A77961
|
|
||||||
static int __init r8a77961_sysc_init(void)
|
|
||||||
{
|
|
||||||
rcar_sysc_nullify(r8a7796_areas, ARRAY_SIZE(r8a7796_areas),
|
|
||||||
R8A7796_PD_A2VC0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct rcar_sysc_info r8a77961_sysc_info __initconst = {
|
const struct rcar_sysc_info r8a77961_sysc_info __initconst = {
|
||||||
.init = r8a77961_sysc_init,
|
.areas = r8a77961_areas,
|
||||||
.areas = r8a7796_areas,
|
.num_areas = ARRAY_SIZE(r8a77961_areas),
|
||||||
.num_areas = ARRAY_SIZE(r8a7796_areas),
|
|
||||||
.extmask_offs = 0x2f8,
|
.extmask_offs = 0x2f8,
|
||||||
.extmask_val = BIT(0),
|
.extmask_val = BIT(0),
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_SYSC_R8A77961 */
|
|
@ -56,17 +56,20 @@
|
|||||||
|
|
||||||
#define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */
|
#define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */
|
||||||
|
|
||||||
struct rcar_sysc_ch {
|
struct rcar_sysc_pd {
|
||||||
|
struct generic_pm_domain genpd;
|
||||||
u16 chan_offs;
|
u16 chan_offs;
|
||||||
u8 chan_bit;
|
u8 chan_bit;
|
||||||
u8 isr_bit;
|
u8 isr_bit;
|
||||||
|
unsigned int flags;
|
||||||
|
char name[];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __iomem *rcar_sysc_base;
|
static void __iomem *rcar_sysc_base;
|
||||||
static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
|
static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
|
||||||
static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val;
|
static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val;
|
||||||
|
|
||||||
static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
|
static int rcar_sysc_pwr_on_off(const struct rcar_sysc_pd *pd, bool on)
|
||||||
{
|
{
|
||||||
unsigned int sr_bit, reg_offs;
|
unsigned int sr_bit, reg_offs;
|
||||||
u32 val;
|
u32 val;
|
||||||
@ -87,17 +90,20 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
|
/* Power-off delay quirk */
|
||||||
|
if (!on && (pd->flags & PD_OFF_DELAY))
|
||||||
|
udelay(1);
|
||||||
|
|
||||||
/* Submit power shutoff or power resume request */
|
/* Submit power shutoff or power resume request */
|
||||||
iowrite32(BIT(sysc_ch->chan_bit),
|
iowrite32(BIT(pd->chan_bit), rcar_sysc_base + pd->chan_offs + reg_offs);
|
||||||
rcar_sysc_base + sysc_ch->chan_offs + reg_offs);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
|
static int rcar_sysc_power(const struct rcar_sysc_pd *pd, bool on)
|
||||||
{
|
{
|
||||||
unsigned int isr_mask = BIT(sysc_ch->isr_bit);
|
unsigned int isr_mask = BIT(pd->isr_bit);
|
||||||
unsigned int chan_mask = BIT(sysc_ch->chan_bit);
|
unsigned int chan_mask = BIT(pd->chan_bit);
|
||||||
unsigned int status, k;
|
unsigned int status, k;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
@ -125,12 +131,11 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
|
|||||||
|
|
||||||
/* Submit power shutoff or resume request until it was accepted */
|
/* Submit power shutoff or resume request until it was accepted */
|
||||||
for (k = 0; k < PWRER_RETRIES; k++) {
|
for (k = 0; k < PWRER_RETRIES; k++) {
|
||||||
ret = rcar_sysc_pwr_on_off(sysc_ch, on);
|
ret = rcar_sysc_pwr_on_off(pd, on);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
status = ioread32(rcar_sysc_base +
|
status = ioread32(rcar_sysc_base + pd->chan_offs + PWRER_OFFS);
|
||||||
sysc_ch->chan_offs + PWRER_OFFS);
|
|
||||||
if (!(status & chan_mask))
|
if (!(status & chan_mask))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -158,28 +163,21 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
|
|||||||
spin_unlock_irqrestore(&rcar_sysc_lock, flags);
|
spin_unlock_irqrestore(&rcar_sysc_lock, flags);
|
||||||
|
|
||||||
pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off",
|
pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off",
|
||||||
sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
|
pd->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch)
|
static bool rcar_sysc_power_is_off(const struct rcar_sysc_pd *pd)
|
||||||
{
|
{
|
||||||
unsigned int st;
|
unsigned int st;
|
||||||
|
|
||||||
st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS);
|
st = ioread32(rcar_sysc_base + pd->chan_offs + PWRSR_OFFS);
|
||||||
if (st & BIT(sysc_ch->chan_bit))
|
if (st & BIT(pd->chan_bit))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rcar_sysc_pd {
|
|
||||||
struct generic_pm_domain genpd;
|
|
||||||
struct rcar_sysc_ch ch;
|
|
||||||
unsigned int flags;
|
|
||||||
char name[];
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d)
|
static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d)
|
||||||
{
|
{
|
||||||
return container_of(d, struct rcar_sysc_pd, genpd);
|
return container_of(d, struct rcar_sysc_pd, genpd);
|
||||||
@ -190,7 +188,7 @@ static int rcar_sysc_pd_power_off(struct generic_pm_domain *genpd)
|
|||||||
struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
|
struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
|
||||||
|
|
||||||
pr_debug("%s: %s\n", __func__, genpd->name);
|
pr_debug("%s: %s\n", __func__, genpd->name);
|
||||||
return rcar_sysc_power(&pd->ch, false);
|
return rcar_sysc_power(pd, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
|
static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
|
||||||
@ -198,7 +196,7 @@ static int rcar_sysc_pd_power_on(struct generic_pm_domain *genpd)
|
|||||||
struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
|
struct rcar_sysc_pd *pd = to_rcar_pd(genpd);
|
||||||
|
|
||||||
pr_debug("%s: %s\n", __func__, genpd->name);
|
pr_debug("%s: %s\n", __func__, genpd->name);
|
||||||
return rcar_sysc_power(&pd->ch, true);
|
return rcar_sysc_power(pd, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool has_cpg_mstp;
|
static bool has_cpg_mstp;
|
||||||
@ -252,12 +250,12 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
|
|||||||
goto finalize;
|
goto finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rcar_sysc_power_is_off(&pd->ch)) {
|
if (!rcar_sysc_power_is_off(pd)) {
|
||||||
pr_debug("%s: %s is already powered\n", __func__, genpd->name);
|
pr_debug("%s: %s is already powered\n", __func__, genpd->name);
|
||||||
goto finalize;
|
goto finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcar_sysc_power(&pd->ch, true);
|
rcar_sysc_power(pd, true);
|
||||||
|
|
||||||
finalize:
|
finalize:
|
||||||
error = pm_genpd_init(genpd, &simple_qos_governor, false);
|
error = pm_genpd_init(genpd, &simple_qos_governor, false);
|
||||||
@ -412,9 +410,9 @@ static int __init rcar_sysc_pd_init(void)
|
|||||||
|
|
||||||
memcpy(pd->name, area->name, n);
|
memcpy(pd->name, area->name, n);
|
||||||
pd->genpd.name = pd->name;
|
pd->genpd.name = pd->name;
|
||||||
pd->ch.chan_offs = area->chan_offs;
|
pd->chan_offs = area->chan_offs;
|
||||||
pd->ch.chan_bit = area->chan_bit;
|
pd->chan_bit = area->chan_bit;
|
||||||
pd->ch.isr_bit = area->isr_bit;
|
pd->isr_bit = area->isr_bit;
|
||||||
pd->flags = area->flags;
|
pd->flags = area->flags;
|
||||||
|
|
||||||
error = rcar_sysc_pd_setup(pd);
|
error = rcar_sysc_pd_setup(pd);
|
||||||
@ -445,18 +443,6 @@ out_put:
|
|||||||
}
|
}
|
||||||
early_initcall(rcar_sysc_pd_init);
|
early_initcall(rcar_sysc_pd_init);
|
||||||
|
|
||||||
void __init rcar_sysc_nullify(struct rcar_sysc_area *areas,
|
|
||||||
unsigned int num_areas, u8 id)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < num_areas; i++)
|
|
||||||
if (areas[i].isr_bit == id) {
|
|
||||||
areas[i].name = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_R8A7779
|
#ifdef CONFIG_ARCH_R8A7779
|
||||||
static int rcar_sysc_power_cpu(unsigned int idx, bool on)
|
static int rcar_sysc_power_cpu(unsigned int idx, bool on)
|
||||||
{
|
{
|
||||||
@ -473,10 +459,10 @@ static int rcar_sysc_power_cpu(unsigned int idx, bool on)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
pd = to_rcar_pd(genpd);
|
pd = to_rcar_pd(genpd);
|
||||||
if (!(pd->flags & PD_CPU) || pd->ch.chan_bit != idx)
|
if (!(pd->flags & PD_CPU) || pd->chan_bit != idx)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return rcar_sysc_power(&pd->ch, on);
|
return rcar_sysc_power(pd, on);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define PD_CPU BIT(0) /* Area contains main CPU core */
|
#define PD_CPU BIT(0) /* Area contains main CPU core */
|
||||||
#define PD_SCU BIT(1) /* Area contains SCU and L2 cache */
|
#define PD_SCU BIT(1) /* Area contains SCU and L2 cache */
|
||||||
#define PD_NO_CR BIT(2) /* Area lacks PWR{ON,OFF}CR registers */
|
#define PD_NO_CR BIT(2) /* Area lacks PWR{ON,OFF}CR registers */
|
||||||
|
#define PD_OFF_DELAY BIT(3) /* Area is subject to power-off delay quirk */
|
||||||
|
|
||||||
#define PD_CPU_CR PD_CPU /* CPU area has CR (R-Car H1) */
|
#define PD_CPU_CR PD_CPU /* CPU area has CR (R-Car H1) */
|
||||||
#define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR (R-Car Gen2/3) */
|
#define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR (R-Car Gen2/3) */
|
||||||
@ -71,12 +72,4 @@ extern const struct rcar_sysc_info r8a77980_sysc_info;
|
|||||||
extern const struct rcar_sysc_info r8a77990_sysc_info;
|
extern const struct rcar_sysc_info r8a77990_sysc_info;
|
||||||
extern const struct rcar_sysc_info r8a77995_sysc_info;
|
extern const struct rcar_sysc_info r8a77995_sysc_info;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helpers for fixing up power area tables depending on SoC revision
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void rcar_sysc_nullify(struct rcar_sysc_area *areas,
|
|
||||||
unsigned int num_areas, u8 id);
|
|
||||||
|
|
||||||
#endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
|
#endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
|
||||||
|
@ -114,6 +114,18 @@ static const struct of_device_id ti_sci_pm_domain_matches[] = {
|
|||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches);
|
MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches);
|
||||||
|
|
||||||
|
static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 idx)
|
||||||
|
{
|
||||||
|
struct ti_sci_pm_domain *pd;
|
||||||
|
|
||||||
|
list_for_each_entry(pd, &pd_provider->pd_list, node) {
|
||||||
|
if (pd->idx == idx)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int ti_sci_pm_domain_probe(struct platform_device *pdev)
|
static int ti_sci_pm_domain_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
@ -149,8 +161,14 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (args.args_count >= 1 && args.np == dev->of_node) {
|
if (args.args_count >= 1 && args.np == dev->of_node) {
|
||||||
if (args.args[0] > max_id)
|
if (args.args[0] > max_id) {
|
||||||
max_id = args.args[0];
|
max_id = args.args[0];
|
||||||
|
} else {
|
||||||
|
if (ti_sci_pm_idx_exists(pd_provider, args.args[0])) {
|
||||||
|
index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||||
if (!pd) {
|
if (!pd) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user