From 0475b0d8a1e0f80a47536dfb19c28dc4bb6adc05 Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 6 May 2025 21:57:27 +0100 Subject: [PATCH 1/4] dt-bindings: soc: google: Add gs101-pmu-intr-gen binding documentation Add bindings documentation for the Power Management Unit (PMU) interrupt generator. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Peter Griffin Link: https://lore.kernel.org/r/20250506-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v4-1-9f64a2657316@linaro.org Signed-off-by: Krzysztof Kozlowski --- .../soc/google/google,gs101-pmu-intr-gen.yaml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml diff --git a/Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml b/Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml new file mode 100644 index 000000000000..2be022ca6a7d --- /dev/null +++ b/Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/google/google,gs101-pmu-intr-gen.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Google Power Management Unit (PMU) Interrupt Generation + +description: | + PMU interrupt generator for handshaking between PMU through interrupts. + +maintainers: + - Peter Griffin + +properties: + compatible: + items: + - const: google,gs101-pmu-intr-gen + - const: syscon + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pmu_intr_gen: syscon@17470000 { + compatible = "google,gs101-pmu-intr-gen", "syscon"; + reg = <0x17470000 0x10000>; + }; From 83b66cdb5d5b6aa4ed1f085b3b2f917af0c2890b Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 6 May 2025 21:57:28 +0100 Subject: [PATCH 2/4] dt-bindings: soc: samsung: exynos-pmu: gs101: add google,pmu-intr-gen phandle gs101 requires access to the pmu interrupt generation register region which is exposed as a syscon. Update the exynos-pmu bindings documentation to reflect this. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Peter Griffin Link: https://lore.kernel.org/r/20250506-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v4-2-9f64a2657316@linaro.org Signed-off-by: Krzysztof Kozlowski --- .../bindings/soc/samsung/exynos-pmu.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml index 204da6fe458d..3109df43d502 100644 --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml @@ -129,6 +129,11 @@ properties: description: Node for reboot method + google,pmu-intr-gen-syscon: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to PMU interrupt generation interface. + required: - compatible - reg @@ -189,6 +194,16 @@ allOf: properties: dp-phy: false + - if: + properties: + compatible: + contains: + enum: + - google,gs101-pmu + then: + required: + - google,pmu-intr-gen-syscon + examples: - | #include From 20adeaca8bc6a084f2610e7c89a8601c9904a0e2 Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 6 May 2025 21:57:29 +0100 Subject: [PATCH 3/4] MAINTAINERS: Add google,gs101-pmu-intr-gen.yaml binding file Add the newly added google,gs101-pmu-intr-gen.yaml file to the Tensor section. Signed-off-by: Peter Griffin Link: https://lore.kernel.org/r/20250506-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v4-3-9f64a2657316@linaro.org Signed-off-by: Krzysztof Kozlowski --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 96b827049501..0e3970a0214d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10080,6 +10080,7 @@ L: linux-samsung-soc@vger.kernel.org S: Maintained C: irc://irc.oftc.net/pixel6-kernel-dev F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml +F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml F: arch/arm64/boot/dts/exynos/google/ F: drivers/clk/samsung/clk-gs101.c F: drivers/phy/samsung/phy-gs101-ufs.c From 598995027b9181ada81789bf01fb8ef30d93c9dc Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 6 May 2025 21:57:31 +0100 Subject: [PATCH 4/4] soc: samsung: exynos-pmu: enable CPU hotplug support for gs101 Some additional register writes are required when hotplugging CPUs on gs101, without these the system hangs when hotplugging. Specifically a CPU_INFORM register needs to be programmed with a hint value which is used by the EL3 firmware (el3mon) and the pmu-intr-gen registers need to be programmed. With this patch applied, and corresponding DT update CPU hotplug now works as expected. e.g. echo 0 > /sys/devices/system/cpu/cpu6/online echo 1 > /sys/devices/system/cpu/cpu6/online Note: to maintain compatibility with older DTs that didn't specify pmu-intr-gen phandle only a warning is issued if the syscon can't be obtained. Signed-off-by: Peter Griffin Link: https://lore.kernel.org/r/20250506-contrib-pg-cpu-hotplug-suspend2ram-fixes-v1-v4-5-9f64a2657316@linaro.org [krzk: few blank line and white-space alignment fixes from checkpatch] Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/exynos-pmu.c | 78 ++++++++++++++++++++- drivers/soc/samsung/exynos-pmu.h | 1 + include/linux/soc/samsung/exynos-regs-pmu.h | 11 +++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index c40313886a01..a77288f49d24 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,7 @@ struct exynos_pmu_context { struct device *dev; const struct exynos_pmu_data *pmu_data; struct regmap *pmureg; + struct regmap *pmuintrgen; }; void __iomem *pmu_base_addr; @@ -222,7 +224,8 @@ static const struct regmap_config regmap_smccfg = { }; static const struct exynos_pmu_data gs101_pmu_data = { - .pmu_secure = true + .pmu_secure = true, + .pmu_cpuhp = true, }; /* @@ -326,6 +329,59 @@ struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np, } EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle); +/* + * CPU_INFORM register hint values which are used by + * EL3 firmware (el3mon). + */ +#define CPU_INFORM_CLEAR 0 +#define CPU_INFORM_C2 1 + +static int gs101_cpuhp_pmu_online(unsigned int cpu) +{ + unsigned int cpuhint = smp_processor_id(); + u32 reg, mask; + + /* clear cpu inform hint */ + regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpuhint), + CPU_INFORM_CLEAR); + + mask = BIT(cpu); + + regmap_update_bits(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_ENABLE, + mask, (0 << cpu)); + + regmap_read(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_UPEND, ®); + + regmap_write(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_CLEAR, + reg & mask); + + return 0; +} + +static int gs101_cpuhp_pmu_offline(unsigned int cpu) +{ + u32 reg, mask; + unsigned int cpuhint = smp_processor_id(); + + /* set cpu inform hint */ + regmap_write(pmu_context->pmureg, GS101_CPU_INFORM(cpuhint), + CPU_INFORM_C2); + + mask = BIT(cpu); + regmap_update_bits(pmu_context->pmuintrgen, GS101_GRP2_INTR_BID_ENABLE, + mask, BIT(cpu)); + + regmap_read(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_UPEND, ®); + regmap_write(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_CLEAR, + reg & mask); + + mask = (BIT(cpu + 8)); + regmap_read(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_UPEND, ®); + regmap_write(pmu_context->pmuintrgen, GS101_GRP1_INTR_BID_CLEAR, + reg & mask); + return 0; +} + static int exynos_pmu_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -378,6 +434,26 @@ static int exynos_pmu_probe(struct platform_device *pdev) pmu_context->pmureg = regmap; pmu_context->dev = dev; + if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp) { + pmu_context->pmuintrgen = syscon_regmap_lookup_by_phandle(dev->of_node, + "google,pmu-intr-gen-syscon"); + if (IS_ERR(pmu_context->pmuintrgen)) { + /* + * To maintain support for older DTs that didn't specify syscon phandle + * just issue a warning rather than fail to probe. + */ + dev_warn(&pdev->dev, "pmu-intr-gen syscon unavailable\n"); + } else { + cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, + "soc/exynos-pmu:prepare", + gs101_cpuhp_pmu_online, NULL); + + cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "soc/exynos-pmu:online", + NULL, gs101_cpuhp_pmu_offline); + } + } + if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_init) pmu_context->pmu_data->pmu_init(); diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h index 0a49a2c9a08e..0938bb4fe15f 100644 --- a/drivers/soc/samsung/exynos-pmu.h +++ b/drivers/soc/samsung/exynos-pmu.h @@ -22,6 +22,7 @@ struct exynos_pmu_data { const struct exynos_pmu_conf *pmu_config; const struct exynos_pmu_conf *pmu_config_extra; bool pmu_secure; + bool pmu_cpuhp; void (*pmu_init)(void); void (*powerdown_conf)(enum sys_powerdown); diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index ce1a3790d6fb..0d5a17ea8fb8 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -658,9 +658,20 @@ #define EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION (0x32A8) /* For Tensor GS101 */ +/* PMU ALIVE */ #define GS101_SYSIP_DAT0 (0x810) +#define GS101_CPU0_INFORM (0x860) +#define GS101_CPU_INFORM(cpu) \ + (GS101_CPU0_INFORM + (cpu*4)) #define GS101_SYSTEM_CONFIGURATION (0x3A00) #define GS101_PHY_CTRL_USB20 (0x3EB0) #define GS101_PHY_CTRL_USBDP (0x3EB4) +/* PMU INTR GEN */ +#define GS101_GRP1_INTR_BID_UPEND (0x0108) +#define GS101_GRP1_INTR_BID_CLEAR (0x010c) +#define GS101_GRP2_INTR_BID_ENABLE (0x0200) +#define GS101_GRP2_INTR_BID_UPEND (0x0208) +#define GS101_GRP2_INTR_BID_CLEAR (0x020c) + #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */