From ed87b1d3f1721f0b4058a26d8c0a4fa00c1f262f Mon Sep 17 00:00:00 2001 From: The-going <48602507+The-going@users.noreply.github.com> Date: Fri, 14 Mar 2025 17:07:32 +0300 Subject: [PATCH] sunxi-6.13: H6/H616: Add a power domain driver for the Mali GPU --- ...dts-allwinner-h616-Add-Mali-GPU-node.patch | 61 +++++ .../drm-panfrost-Add-PM-runtime-flags.patch | 116 ++++++++ ...-panfrost-add-h616-compatible-string.patch | 43 +++ ...ifrost-Add-Allwinner-H616-compatible.patch | 30 +++ ...power-Add-Allwinner-H6-H616-PRCM-PPU.patch | 67 +++++ ...mdomain-sunxi-add-H6-PRCM-PPU-driver.patch | 249 ++++++++++++++++++ patch/kernel/archive/sunxi-6.13/series.conf | 6 + patch/kernel/archive/sunxi-6.13/series.drm | 6 + 8 files changed, 578 insertions(+) create mode 100644 patch/kernel/archive/sunxi-6.13/patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch create mode 100644 patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch create mode 100644 patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-add-h616-compatible-string.patch create mode 100644 patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-gpu-mali-bifrost-Add-Allwinner-H616-compatible.patch create mode 100644 patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch create mode 100644 patch/kernel/archive/sunxi-6.13/patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch diff --git a/patch/kernel/archive/sunxi-6.13/patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch b/patch/kernel/archive/sunxi-6.13/patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch new file mode 100644 index 000000000..8a00dac93 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.13/patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch @@ -0,0 +1,61 @@ +From 02dc976a5f62b393f378c056888f121ba1880fc5 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 21 Feb 2025 00:58:01 +0000 +Subject: arm64: dts: allwinner: h616: Add Mali GPU node + +The Allwinner H616 SoC contains a Mali-G31 MP2 GPU, which is of the Mali +Bifrost family. There is a power domain specifically for that GPU, which +needs to be enabled to make use of the it. + +Add the DT nodes for those two devices, and link them together through +the "power-domains" property. +Any board wishing to use the GPU would need to enable the GPU node and +specify the "mali-supply" regulator. + +Signed-off-by: Andre Przywara +--- + .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 21 +++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +index cdce3dcb8ec0..ceedae9e399b 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +@@ -150,6 +150,21 @@ soc { + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x40000000>; + ++ gpu: gpu@1800000 { ++ compatible = "allwinner,sun50i-h616-mali", ++ "arm,mali-bifrost"; ++ reg = <0x1800000 0x40000>; ++ interrupts = , ++ , ++ ; ++ interrupt-names = "job", "mmu", "gpu"; ++ clocks = <&ccu CLK_GPU0>, <&ccu CLK_BUS_GPU>; ++ clock-names = "core", "bus"; ++ power-domains = <&prcm_ppu 2>; ++ resets = <&ccu RST_BUS_GPU>; ++ status = "disabled"; ++ }; ++ + crypto: crypto@1904000 { + compatible = "allwinner,sun50i-h616-crypto"; + reg = <0x01904000 0x800>; +@@ -874,6 +889,12 @@ r_ccu: clock@7010000 { + #reset-cells = <1>; + }; + ++ prcm_ppu: power-controller@7010250 { ++ compatible = "allwinner,sun50i-h616-prcm-ppu"; ++ reg = <0x07010250 0x10>; ++ #power-domain-cells = <1>; ++ }; ++ + nmi_intc: interrupt-controller@7010320 { + compatible = "allwinner,sun50i-h616-nmi", + "allwinner,sun9i-a80-nmi"; +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch b/patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch new file mode 100644 index 000000000..1b38912c6 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch @@ -0,0 +1,116 @@ +From 278eb0c7c55813efa78f8d32afd559c1121bc9d4 Mon Sep 17 00:00:00 2001 +From: Philippe Simons +Date: Thu, 13 Mar 2025 00:23:18 +0100 +Subject: drm/panfrost: Add PM runtime flags + +Allwinner H616 has a dedicated power domain for its Mali G31. + +Currently after probe, the GPU is put in runtime suspend which +disable the power domain. +On first usage of GPU, the power domain enable hangs the system. + +This series adds the necessary calls to enable the clocks and +deasserting the reset line after the power domain enabling and +asserting the reset line and disabling the clocks prior to the +power domain disabling. + +This allows to use the Mali GPU on all Allwinner H616 +boards and devices. + +When the GPU is the only device attached to a single power domain, +core genpd disable and enable it when gpu enter and leave runtime suspend. + +Some power-domain requires a sequence before disabled, +and the reverse when enabled. + +Add PM flags for CLK and RST, and implement in +panfrost_device_runtime_suspend/resume. + +Signed-off-by: Philippe Simons +--- + drivers/gpu/drm/panfrost/panfrost_device.c | 37 ++++++++++++++++++++++ + drivers/gpu/drm/panfrost/panfrost_device.h | 4 +++ + 2 files changed, 41 insertions(+) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c +index a45e4addcc19..189ad2ad2b32 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.c ++++ b/drivers/gpu/drm/panfrost/panfrost_device.c +@@ -406,11 +406,38 @@ void panfrost_device_reset(struct panfrost_device *pfdev) + static int panfrost_device_runtime_resume(struct device *dev) + { + struct panfrost_device *pfdev = dev_get_drvdata(dev); ++ int ret; ++ ++ if (pfdev->comp->pm_features & BIT(GPU_PM_RT_RST_ASRT)) { ++ ret = reset_control_deassert(pfdev->rstc); ++ if (ret) ++ return ret; ++ } ++ ++ if (pfdev->comp->pm_features & BIT(GPU_PM_RT_CLK_DIS)) { ++ ret = clk_enable(pfdev->clock); ++ if (ret) ++ goto err_clk; ++ ++ if (pfdev->bus_clock) { ++ ret = clk_enable(pfdev->bus_clock); ++ if (ret) ++ goto err_bus_clk; ++ } ++ } + + panfrost_device_reset(pfdev); + panfrost_devfreq_resume(pfdev); + + return 0; ++ ++err_bus_clk: ++ if (pfdev->comp->pm_features & BIT(GPU_PM_RT_CLK_DIS)) ++ clk_disable(pfdev->clock); ++err_clk: ++ if (pfdev->comp->pm_features & BIT(GPU_PM_RT_RST_ASRT)) ++ reset_control_assert(pfdev->rstc); ++ return ret; + } + + static int panfrost_device_runtime_suspend(struct device *dev) +@@ -426,6 +453,16 @@ static int panfrost_device_runtime_suspend(struct device *dev) + panfrost_gpu_suspend_irq(pfdev); + panfrost_gpu_power_off(pfdev); + ++ if (pfdev->comp->pm_features & BIT(GPU_PM_RT_CLK_DIS)) { ++ if (pfdev->bus_clock) ++ clk_disable(pfdev->bus_clock); ++ ++ clk_disable(pfdev->clock); ++ } ++ ++ if (pfdev->comp->pm_features & BIT(GPU_PM_RT_RST_ASRT)) ++ reset_control_assert(pfdev->rstc); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h +index cffcb0ac7c11..f372d4819262 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -36,10 +36,14 @@ enum panfrost_drv_comp_bits { + * enum panfrost_gpu_pm - Supported kernel power management features + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend + * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend ++ * @GPU_PM_RT_CLK_DIS: Allow disabling clocks during system runtime suspend ++ * @GPU_PM_RST_ASRT: Allow asserting the reset control during runtime suspend + */ + enum panfrost_gpu_pm { + GPU_PM_CLK_DIS, + GPU_PM_VREG_OFF, ++ GPU_PM_RT_CLK_DIS, ++ GPU_PM_RT_RST_ASRT + }; + + struct panfrost_features { +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-add-h616-compatible-string.patch b/patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-add-h616-compatible-string.patch new file mode 100644 index 000000000..3c2ff521c --- /dev/null +++ b/patch/kernel/archive/sunxi-6.13/patches.drm/drm-panfrost-add-h616-compatible-string.patch @@ -0,0 +1,43 @@ +From b4b55cd1e58bc396b011f747116db0cfef38f27b Mon Sep 17 00:00:00 2001 +From: Philippe Simons +Date: Thu, 13 Mar 2025 00:23:19 +0100 +Subject: drm/panfrost: add h616 compatible string + +Tie the Allwinner compatible string to the two features bits that will +toggle the clocks and the reset line whenever the power domain is changing +state. + +Signed-off-by: Philippe Simons +--- + drivers/gpu/drm/panfrost/panfrost_drv.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index ee3864476eb9..a511edc3c045 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -777,6 +777,13 @@ static const struct panfrost_compatible default_data = { + .pm_domain_names = NULL, + }; + ++static const struct panfrost_compatible allwinner_h616_data = { ++ .num_supplies = ARRAY_SIZE(default_supplies) - 1, ++ .supply_names = default_supplies, ++ .num_pm_domains = 1, ++ .pm_features = BIT(GPU_PM_RT_CLK_DIS) | BIT(GPU_PM_RT_RST_ASRT), ++}; ++ + static const struct panfrost_compatible amlogic_data = { + .num_supplies = ARRAY_SIZE(default_supplies) - 1, + .supply_names = default_supplies, +@@ -860,6 +867,7 @@ static const struct of_device_id dt_match[] = { + { .compatible = "mediatek,mt8186-mali", .data = &mediatek_mt8186_data }, + { .compatible = "mediatek,mt8188-mali", .data = &mediatek_mt8188_data }, + { .compatible = "mediatek,mt8192-mali", .data = &mediatek_mt8192_data }, ++ { .compatible = "allwinner,sun50i-h616-mali", .data = &allwinner_h616_data }, + {} + }; + MODULE_DEVICE_TABLE(of, dt_match); +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-gpu-mali-bifrost-Add-Allwinner-H616-compatible.patch b/patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-gpu-mali-bifrost-Add-Allwinner-H616-compatible.patch new file mode 100644 index 000000000..73e24e0af --- /dev/null +++ b/patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-gpu-mali-bifrost-Add-Allwinner-H616-compatible.patch @@ -0,0 +1,30 @@ +From 7f350d05012873c129458241792d005ef1344d9a Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 21 Feb 2025 00:58:00 +0000 +Subject: dt-bindings: gpu: mali-bifrost: Add Allwinner H616 compatible + +The Allwinner H616 SoC has a Mali-G31 MP2 GPU, which is of the Mali +Bifrost family. +Add the SoC specific compatible string and pair it with the bifrost +fallback compatible. + +Signed-off-by: Andre Przywara +--- + Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml +index 735c7f06c24e..439d5c59daa2 100644 +--- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml ++++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml +@@ -17,6 +17,7 @@ properties: + oneOf: + - items: + - enum: ++ - allwinner,sun50i-h616-mali + - amlogic,meson-g12a-mali + - mediatek,mt8183-mali + - mediatek,mt8183b-mali +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch b/patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch new file mode 100644 index 000000000..87ec283f9 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.13/patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch @@ -0,0 +1,67 @@ +From af0be61ac5ff0f86567ddbf3924c46eaa211e07f Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 21 Feb 2025 00:57:58 +0000 +Subject: dt-bindings: power: Add Allwinner H6/H616 PRCM PPU + +The Allwinner H6 and some later SoCs contain some bits in the PRCM (Power +Reset Clock Management) block that control some power domains. +Those power domains include the one for the GPU, the PLLs and some +analogue circuits. + +Signed-off-by: Andre Przywara +--- + .../power/allwinner,sun50i-h6-prcm-ppu.yaml | 42 +++++++++++++++++++ + 1 file changed, 42 insertions(+) + create mode 100644 Documentation/devicetree/bindings/power/allwinner,sun50i-h6-prcm-ppu.yaml + +diff --git a/Documentation/devicetree/bindings/power/allwinner,sun50i-h6-prcm-ppu.yaml b/Documentation/devicetree/bindings/power/allwinner,sun50i-h6-prcm-ppu.yaml +new file mode 100644 +index 000000000000..7eaff9baf726 +--- /dev/null ++++ b/Documentation/devicetree/bindings/power/allwinner,sun50i-h6-prcm-ppu.yaml +@@ -0,0 +1,42 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/power/allwinner,sun50i-h6-prcm-ppu.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Allwinner SoCs PRCM power domain controller ++ ++maintainers: ++ - Andre Przywara ++ ++description: ++ The Allwinner Power Reset Clock Management (PRCM) unit contains bits to ++ control a few power domains. ++ ++properties: ++ compatible: ++ enum: ++ - allwinner,sun50i-h6-prcm-ppu ++ - allwinner,sun50i-h616-prcm-ppu ++ - allwinner,sun55i-a523-prcm-ppu ++ ++ reg: ++ maxItems: 1 ++ ++ '#power-domain-cells': ++ const: 1 ++ ++required: ++ - compatible ++ - reg ++ - '#power-domain-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ prcm_ppu: power-controller@7010210 { ++ compatible = "allwinner,sun50i-h616-prcm-ppu"; ++ reg = <0x07010250 0x10>; ++ #power-domain-cells = <1>; ++ }; +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.13/patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch b/patch/kernel/archive/sunxi-6.13/patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch new file mode 100644 index 000000000..2e7eccbb3 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.13/patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch @@ -0,0 +1,249 @@ +From 9fb1314045a676823428efa503b581c2910169d7 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 21 Feb 2025 00:57:59 +0000 +Subject: pmdomain: sunxi: add H6 PRCM PPU driver + +The Allwinner Power Reset Clock Management (RPCM) block contains a few +bits that control some power domains. The most prominent one is the one +for the Mali GPU. On the Allwinner H6 this domain is enabled at reset, so +we didn't care about it so far, but the H616 defaults to it being disabled. + +Add a power domain driver for those bits. Some BSP code snippets and +some spare documentation describe three bits, slightly different between +the H6 and H616, so add three power domains for each SoC, connected to +their compatible string. + +Signed-off-by: Andre Przywara +--- + drivers/pmdomain/sunxi/Kconfig | 10 + + drivers/pmdomain/sunxi/Makefile | 1 + + drivers/pmdomain/sunxi/sun50i-h6-prcm-ppu.c | 191 ++++++++++++++++++++ + 3 files changed, 202 insertions(+) + create mode 100644 drivers/pmdomain/sunxi/sun50i-h6-prcm-ppu.c + +diff --git a/drivers/pmdomain/sunxi/Kconfig b/drivers/pmdomain/sunxi/Kconfig +index 17781bf8d86d..43eecb3ea981 100644 +--- a/drivers/pmdomain/sunxi/Kconfig ++++ b/drivers/pmdomain/sunxi/Kconfig +@@ -8,3 +8,13 @@ config SUN20I_PPU + help + Say y to enable the PPU power domain driver. This saves power + when certain peripherals, such as the video engine, are idle. ++ ++config SUN50I_H6_PRCM_PPU ++ tristate "Allwinner H6 PRCM power domain driver" ++ depends on ARCH_SUNXI || COMPILE_TEST ++ depends on PM ++ select PM_GENERIC_DOMAINS ++ help ++ Say y to enable the Allwinner H6/H616 PRCM power domain driver. ++ This is required to enable the Mali GPU in the H616 SoC, it is ++ optional for the H6. +diff --git a/drivers/pmdomain/sunxi/Makefile b/drivers/pmdomain/sunxi/Makefile +index ec1d7a2fb21d..c1343e123759 100644 +--- a/drivers/pmdomain/sunxi/Makefile ++++ b/drivers/pmdomain/sunxi/Makefile +@@ -1,2 +1,3 @@ + # SPDX-License-Identifier: GPL-2.0-only + obj-$(CONFIG_SUN20I_PPU) += sun20i-ppu.o ++obj-$(CONFIG_SUN50I_H6_PRCM_PPU) += sun50i-h6-prcm-ppu.o +diff --git a/drivers/pmdomain/sunxi/sun50i-h6-prcm-ppu.c b/drivers/pmdomain/sunxi/sun50i-h6-prcm-ppu.c +new file mode 100644 +index 000000000000..1c6b0c78b222 +--- /dev/null ++++ b/drivers/pmdomain/sunxi/sun50i-h6-prcm-ppu.c +@@ -0,0 +1,191 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) Arm Ltd. 2024 ++ * ++ * Allwinner H6/H616 PRCM power domain driver. ++ * This covers a few registers inside the PRCM (Power Reset Clock Management) ++ * block that control some power rails, most prominently for the Mali GPU. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * The PRCM block covers multiple devices, starting with some clocks, ++ * then followed by the power rails. ++ * The clocks are covered by a different driver, so this driver's MMIO range ++ * starts later in the PRCM MMIO frame, not at the beginning of it. ++ * To keep the register offsets consistent with other PRCM documentation, ++ * express the registers relative to the beginning of the whole PRCM, and ++ * subtract the PPU offset this driver is bound to. ++ */ ++#define PD_H6_PPU_OFFSET 0x250 ++#define PD_H6_VDD_SYS_REG 0x250 ++#define PD_H616_ANA_VDD_GATE BIT(4) ++#define PD_H6_CPUS_VDD_GATE BIT(3) ++#define PD_H6_AVCC_VDD_GATE BIT(2) ++#define PD_H6_GPU_REG 0x254 ++#define PD_H6_GPU_GATE BIT(0) ++ ++struct sun50i_h6_ppu_pd { ++ struct generic_pm_domain genpd; ++ void __iomem *reg; ++ u32 gate_mask; ++ bool negated; ++}; ++ ++#define FLAG_PPU_ALWAYS_ON BIT(0) ++#define FLAG_PPU_NEGATED BIT(1) ++ ++struct sun50i_h6_ppu_desc { ++ const char *name; ++ u32 offset; ++ u32 mask; ++ unsigned int flags; ++}; ++ ++struct sun50i_h6_ppu_desc sun50i_h6_ppus[] = { ++ { "AVCC", PD_H6_VDD_SYS_REG, PD_H6_AVCC_VDD_GATE }, ++ { "CPUS", PD_H6_VDD_SYS_REG, PD_H6_CPUS_VDD_GATE }, ++ { "GPU", PD_H6_GPU_REG, PD_H6_GPU_GATE }, ++ {} ++}; ++ ++struct sun50i_h6_ppu_desc sun50i_h616_ppus[] = { ++ { "PLL", PD_H6_VDD_SYS_REG, PD_H6_AVCC_VDD_GATE, ++ FLAG_PPU_ALWAYS_ON | FLAG_PPU_NEGATED }, ++ { "ANA", PD_H6_VDD_SYS_REG, PD_H616_ANA_VDD_GATE, FLAG_PPU_ALWAYS_ON }, ++ { "GPU", PD_H6_GPU_REG, PD_H6_GPU_GATE, FLAG_PPU_NEGATED }, ++ {} ++}; ++#define to_sun50i_h6_ppu_pd(_genpd) \ ++ container_of(_genpd, struct sun50i_h6_ppu_pd, genpd) ++ ++static bool sun50i_h6_ppu_power_status(const struct sun50i_h6_ppu_pd *pd) ++{ ++ bool bit = readl(pd->reg) & pd->gate_mask; ++ ++ return bit ^ pd->negated; ++} ++ ++static int sun50i_h6_ppu_pd_set_power(const struct sun50i_h6_ppu_pd *pd, ++ bool set_bit) ++{ ++ u32 reg = readl(pd->reg); ++ ++ if (set_bit) ++ writel(reg | pd->gate_mask, pd->reg); ++ else ++ writel(reg & ~pd->gate_mask, pd->reg); ++ ++ return 0; ++} ++ ++static int sun50i_h6_ppu_pd_power_on(struct generic_pm_domain *genpd) ++{ ++ const struct sun50i_h6_ppu_pd *pd = to_sun50i_h6_ppu_pd(genpd); ++ ++ return sun50i_h6_ppu_pd_set_power(pd, !pd->negated); ++} ++ ++static int sun50i_h6_ppu_pd_power_off(struct generic_pm_domain *genpd) ++{ ++ const struct sun50i_h6_ppu_pd *pd = to_sun50i_h6_ppu_pd(genpd); ++ ++ return sun50i_h6_ppu_pd_set_power(pd, pd->negated); ++} ++ ++static int sun50i_h6_ppu_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct genpd_onecell_data *ppu; ++ struct sun50i_h6_ppu_pd *pds; ++ const struct sun50i_h6_ppu_desc *desc; ++ void __iomem *base; ++ int ret, i, count; ++ ++ desc = of_device_get_match_data(dev); ++ if (!desc) ++ return -EINVAL; ++ ++ for (count = 0; desc[count].name; count++) ++ ; ++ ++ pds = devm_kcalloc(dev, count, sizeof(*pds), GFP_KERNEL); ++ if (!pds) ++ return -ENOMEM; ++ ++ ppu = devm_kzalloc(dev, sizeof(*ppu), GFP_KERNEL); ++ if (!ppu) ++ return -ENOMEM; ++ ++ ppu->num_domains = count; ++ ppu->domains = devm_kcalloc(dev, count, sizeof(*ppu->domains), ++ GFP_KERNEL); ++ if (!ppu->domains) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, ppu); ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ for (i = 0; i < count; i++) { ++ struct sun50i_h6_ppu_pd *pd = &pds[i]; ++ ++ pd->genpd.name = desc[i].name; ++ pd->genpd.power_off = sun50i_h6_ppu_pd_power_off; ++ pd->genpd.power_on = sun50i_h6_ppu_pd_power_on; ++ if (desc[i].flags & FLAG_PPU_ALWAYS_ON) ++ pd->genpd.flags = GENPD_FLAG_ALWAYS_ON; ++ pd->negated = !!(desc[i].flags & FLAG_PPU_NEGATED); ++ pd->reg = base + desc[i].offset - PD_H6_PPU_OFFSET; ++ pd->gate_mask = desc[i].mask; ++ ++ ret = pm_genpd_init(&pd->genpd, NULL, ++ !sun50i_h6_ppu_power_status(pd)); ++ if (ret) { ++ dev_warn(dev, "Failed to add GPU power domain: %d\n", ret); ++ return ret; ++ } ++ ppu->domains[i] = &pd->genpd; ++ } ++ ++ ret = of_genpd_add_provider_onecell(dev->of_node, ppu); ++ if (ret) ++ dev_warn(dev, "Failed to add provider: %d\n", ret); ++ ++ return 0; ++} ++ ++static const struct of_device_id sun50i_h6_ppu_of_match[] = { ++ { .compatible = "allwinner,sun50i-h6-prcm-ppu", ++ .data = &sun50i_h6_ppus }, ++ { .compatible = "allwinner,sun50i-h616-prcm-ppu", ++ .data = &sun50i_h616_ppus }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, sun50i_h6_ppu_of_match); ++ ++static struct platform_driver sun50i_h6_ppu_driver = { ++ .probe = sun50i_h6_ppu_probe, ++ .driver = { ++ .name = "sun50i-h6-prcm-ppu", ++ .of_match_table = sun50i_h6_ppu_of_match, ++ /* Power domains cannot be removed while they are in use. */ ++ .suppress_bind_attrs = true, ++ }, ++}; ++module_platform_driver(sun50i_h6_ppu_driver); ++ ++MODULE_AUTHOR("Andre Przywara "); ++MODULE_DESCRIPTION("Allwinner H6 PRCM power domain driver"); ++MODULE_LICENSE("GPL"); +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.13/series.conf b/patch/kernel/archive/sunxi-6.13/series.conf index 9c9be163c..3d52d7a9c 100644 --- a/patch/kernel/archive/sunxi-6.13/series.conf +++ b/patch/kernel/archive/sunxi-6.13/series.conf @@ -284,6 +284,12 @@ patches.drm/drm-sun4i-de33-csc-add-Display-Engine-3.3-DE33-support.patch patches.drm/drm-sun4i-add-sun50i-h616-hdmi-phy-support.patch patches.drm/add-TCON-global-control-reg-for-pad-selection.patch + patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch + patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch + patches.drm/dt-bindings-gpu-mali-bifrost-Add-Allwinner-H616-compatible.patch + patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch + patches.drm/drm-panfrost-Add-PM-runtime-flags.patch + patches.drm/drm-panfrost-add-h616-compatible-string.patch ################################################################################ # diff --git a/patch/kernel/archive/sunxi-6.13/series.drm b/patch/kernel/archive/sunxi-6.13/series.drm index 8d6f3c805..c6d84f754 100644 --- a/patch/kernel/archive/sunxi-6.13/series.drm +++ b/patch/kernel/archive/sunxi-6.13/series.drm @@ -31,3 +31,9 @@ patches.drm/drm-sun4i-de33-csc-add-Display-Engine-3.3-DE33-support.patch patches.drm/drm-sun4i-add-sun50i-h616-hdmi-phy-support.patch patches.drm/add-TCON-global-control-reg-for-pad-selection.patch + patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch + patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch + patches.drm/dt-bindings-gpu-mali-bifrost-Add-Allwinner-H616-compatible.patch + patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch + patches.drm/drm-panfrost-Add-PM-runtime-flags.patch + patches.drm/drm-panfrost-add-h616-compatible-string.patch