mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
sunxi-6.12: Add PRCM power domain controller Mali GPU on h616
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
From abf45c2a696b446a0f065f6d741d5a3767e56909 Mon Sep 17 00:00:00 2001
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
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 <andre.przywara@arm.com>
|
||||
---
|
||||
.../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 = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
|
||||
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ 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
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
From c70c739ee91159f283522fdcb151ad2f2ec78c6f Mon Sep 17 00:00:00 2001
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
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 <simons.philippe@gmail.com>
|
||||
---
|
||||
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
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
From fe3a7a361a95f4720824cdc82ce4dba878d90cf2 Mon Sep 17 00:00:00 2001
|
||||
From: Philippe Simons <simons.philippe@gmail.com>
|
||||
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 <simons.philippe@gmail.com>
|
||||
---
|
||||
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
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From d6540f3288c68dde3f4bb6df647fd47de237ad8b Mon Sep 17 00:00:00 2001
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
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 <andre.przywara@arm.com>
|
||||
---
|
||||
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
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
From d2915699906888faca6be57028be9d55196680e0 Mon Sep 17 00:00:00 2001
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
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 <andre.przywara@arm.com>
|
||||
---
|
||||
.../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 <andre.przywara@arm.com>
|
||||
+
|
||||
+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
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
From 1b05bf94b4d99c683ba426c3eeb2a0d075285057 Mon Sep 17 00:00:00 2001
|
||||
From: Andre Przywara <andre.przywara@arm.com>
|
||||
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 <andre.przywara@arm.com>
|
||||
---
|
||||
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 <linux/bitfield.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_domain.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+/*
|
||||
+ * 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 <andre.przywara@arm.com>");
|
||||
+MODULE_DESCRIPTION("Allwinner H6 PRCM power domain driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.35.3
|
||||
|
||||
@@ -287,6 +287,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
|
||||
|
||||
################################################################################
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user