From 8bbaa8666a8aa69c004c97ab3675ac71d5625e1c Mon Sep 17 00:00:00 2001 From: The-going <48602507+The-going@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:41:21 +0300 Subject: [PATCH] sunxi-6.16: remove unused megous patches --- ...global-control-reg-for-pad-selection.patch | 41 ++ ...dts-allwinner-h616-Add-Mali-GPU-node.patch | 61 ++ ...-add-Display-Engine-3.3-DE33-support.patch | 86 +++ .../drm-panfrost-Add-PM-runtime-flags.patch | 111 ++++ ...-panfrost-add-h616-compatible-string.patch | 43 ++ ...panfrost-reorder-pd-clk-rst-sequence.patch | 106 ++++ ...n4i-add-sun50i-h616-hdmi-phy-support.patch | 108 ++++ ...-de2-Initialize-layer-fields-earlier.patch | 75 +++ ...rm-sun4i-de2-de3-Change-CSC-argument.patch | 178 ++++++ ...de2-de3-Merge-CSC-functions-into-one.patch | 221 +++++++ ...ic-blender-register-reference-functi.patch | 38 ++ ...sun4i-de2-de3-add-mixer-version-enum.patch | 257 ++++++++ ...de3-call-csc-setup-also-for-UI-layer.patch | 64 ++ ...e2-de3-refactor-mixer-initialisation.patch | 121 ++++ ...ic-register-reference-function-for-l.patch | 117 ++++ ...m-sun4i-de3-Add-YUV-formatter-module.patch | 164 +++++ ...drm-sun4i-de3-Implement-AFBC-support.patch | 569 ++++++++++++++++++ ...de3-add-YUV-support-to-the-DE3-mixer.patch | 126 ++++ ...un4i-de3-add-YUV-support-to-the-TCON.patch | 83 +++ ...rt-to-the-color-space-correction-mod.patch | 225 +++++++ ...ormat-enumeration-function-to-engine.patch | 63 ++ ...3-add-formatter-flag-to-mixer-config.patch | 53 ++ ...ine-reference-to-ccsc-setup-function.patch | 54 ++ ...-add-Display-Engine-3.3-DE33-support.patch | 156 +++++ ...-add-Display-Engine-3.3-DE33-support.patch | 75 +++ ...-add-Display-Engine-3.3-DE33-support.patch | 302 ++++++++++ ...-add-Display-Engine-3.3-DE33-support.patch | 77 +++ ...n4i-support-YUV-formats-in-VI-scaler.patch | 140 +++++ ...scaler-refactor-vi_scaler-enablement.patch | 100 +++ ...-allwinner-add-H616-DE33-bus-binding.patch | 35 ++ ...llwinner-add-H616-DE33-clock-binding.patch | 32 + ...llwinner-add-H616-DE33-mixer-binding.patch | 36 ++ ...power-Add-Allwinner-H6-H616-PRCM-PPU.patch | 67 +++ ...mdomain-sunxi-add-H6-PRCM-PPU-driver.patch | 249 ++++++++ ...of-playback-speed-after-system-sleep.patch | 45 -- ...-with-information-and-u-boot-patches.patch | 215 ------- ...-dts-rockchip-rk3399-s-Add-DMC-table.patch | 62 -- ...56x-Fix-PCIe-register-map-and-ranges.patch | 47 -- ...reboot-when-DRM-device-fails-to-bind.patch | 36 -- ...rockchip-Fix-ISP1-PHY-initialization.patch | 35 -- ...rockchip-fix-sdmmc-after-soft-reboot.patch | 52 -- patch/kernel/archive/sunxi-6.16/series.conf | 7 - patch/kernel/archive/sunxi-6.16/series.megous | 7 - 43 files changed, 4233 insertions(+), 506 deletions(-) create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/add-TCON-global-control-reg-for-pad-selection.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/clk-sunxi-ng-ccu-add-Display-Engine-3.3-DE33-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-add-h616-compatible-string.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-reorder-pd-clk-rst-sequence.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-add-sun50i-h616-hdmi-phy-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-Initialize-layer-fields-earlier.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Change-CSC-argument.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Merge-CSC-functions-into-one.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-generic-blender-register-reference-functi.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-mixer-version-enum.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-call-csc-setup-also-for-UI-layer.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-refactor-mixer-initialisation.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-use-generic-register-reference-function-for-l.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Add-YUV-formatter-module.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Implement-AFBC-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-DE3-mixer.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-TCON.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-color-space-correction-mod.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-format-enumeration-function-to-engine.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-formatter-flag-to-mixer-config.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-pass-engine-reference-to-ccsc-setup-function.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-csc-add-Display-Engine-3.3-DE33-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-fmt-add-Display-Engine-3.3-DE33-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-mixer-add-Display-Engine-3.3-DE33-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-vi_scaler-add-Display-Engine-3.3-DE33-support.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-support-YUV-formats-in-VI-scaler.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-vi_scaler-refactor-vi_scaler-enablement.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-bus-binding.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-clock-binding.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-mixer-binding.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch create mode 100644 patch/kernel/archive/sunxi-6.16/patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch delete mode 100644 patch/kernel/archive/sunxi-6.16/patches.megous/ASoC-rockchip-Fix-doubling-of-playback-speed-after-system-sleep.patch delete mode 100644 patch/kernel/archive/sunxi-6.16/patches.megous/Add-README.md-with-information-and-u-boot-patches.patch delete mode 100644 patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk3399-s-Add-DMC-table.patch delete mode 100644 patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk356x-Fix-PCIe-register-map-and-ranges.patch delete mode 100644 patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch delete mode 100644 patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-dw-mipi-dsi-rockchip-Fix-ISP1-PHY-initialization.patch delete mode 100644 patch/kernel/archive/sunxi-6.16/patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/add-TCON-global-control-reg-for-pad-selection.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/add-TCON-global-control-reg-for-pad-selection.patch new file mode 100644 index 000000000..c1a25e969 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/add-TCON-global-control-reg-for-pad-selection.patch @@ -0,0 +1,41 @@ +From 86ef31fcb116682d399b9723a7ab66c87e6f2cc5 Mon Sep 17 00:00:00 2001 +From: Stephen Graf +Date: Tue, 18 Feb 2025 05:12:44 +0000 +Subject: add TCON global control reg for pad selection + +Signed-off-by: Stephen Graf +--- + drivers/gpu/drm/sun4i/sun4i_tcon.c | 4 ++++ + drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c +index af67bf2e6e09..88984572f5c5 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c +@@ -1308,6 +1308,10 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, + goto err_free_dclk; + } + ++ regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, ++ SUN4I_TCON_GCTL_PAD_SEL, ++ SUN4I_TCON_GCTL_PAD_SEL); ++ + if (tcon->quirks->has_channel_0) { + /* + * If we have an LVDS panel connected to the TCON, we should +diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h +index bd4abc90062b..e8d28bad4060 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h +@@ -19,6 +19,7 @@ + + #define SUN4I_TCON_GCTL_REG 0x0 + #define SUN4I_TCON_GCTL_TCON_ENABLE BIT(31) ++#define SUN4I_TCON_GCTL_PAD_SEL BIT(1) + #define SUN4I_TCON_GCTL_IOMAP_MASK BIT(0) + #define SUN4I_TCON_GCTL_IOMAP_TCON1 (1 << 0) + #define SUN4I_TCON_GCTL_IOMAP_TCON0 (0 << 0) +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/arm64-dts-allwinner-h616-Add-Mali-GPU-node.patch b/patch/kernel/archive/sunxi-6.16/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.16/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.16/patches.drm/clk-sunxi-ng-ccu-add-Display-Engine-3.3-DE33-support.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/clk-sunxi-ng-ccu-add-Display-Engine-3.3-DE33-support.patch new file mode 100644 index 000000000..6bd5c7665 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/clk-sunxi-ng-ccu-add-Display-Engine-3.3-DE33-support.patch @@ -0,0 +1,86 @@ +From b41f5a9ec8841c0342f101585c64c292019543d2 Mon Sep 17 00:00:00 2001 +From: Ryan Walklin +Date: Sun, 29 Sep 2024 22:04:54 +1300 +Subject: clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support + +The DE33 is a newer version of the Allwinner Display Engine IP block, +found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already +supported by the mainline driver. + +The DE33 in the H616 has mixer0 and writeback units. The clocks +and resets required are identical to the H3 and H5 respectively, so use +those existing structs for the H616 description. + +There are two additional 32-bit registers (at offsets 0x24 and 0x28) +which require clearing and setting respectively to bring up the +hardware. The function of these registers is currently unknown, and the +values are taken from the out-of-tree driver. + +Add the required clock description struct and compatible string to the +DE2 driver. + +Signed-off-by: Ryan Walklin +--- + drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +index 7683ea08d8e3..83eab6f132aa 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c ++++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -239,6 +240,16 @@ static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = { + .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), + }; + ++static const struct sunxi_ccu_desc sun50i_h616_de33_clk_desc = { ++ .ccu_clks = sun8i_de2_ccu_clks, ++ .num_ccu_clks = ARRAY_SIZE(sun8i_de2_ccu_clks), ++ ++ .hw_clks = &sun8i_h3_de2_hw_clks, ++ ++ .resets = sun50i_h5_de2_resets, ++ .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), ++}; ++ + static int sunxi_de2_clk_probe(struct platform_device *pdev) + { + struct clk *bus_clk, *mod_clk; +@@ -291,6 +302,16 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev) + goto err_disable_mod_clk; + } + ++ /* ++ * The DE33 requires these additional (unknown) registers set ++ * during initialisation. ++ */ ++ if (of_device_is_compatible(pdev->dev.of_node, ++ "allwinner,sun50i-h616-de33-clk")) { ++ writel(0, reg + 0x24); ++ writel(0x0000a980, reg + 0x28); ++ } ++ + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc); + if (ret) + goto err_assert_reset; +@@ -335,6 +356,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { + .compatible = "allwinner,sun50i-h6-de3-clk", + .data = &sun50i_h5_de2_clk_desc, + }, ++ { ++ .compatible = "allwinner,sun50i-h616-de33-clk", ++ .data = &sun50i_h616_de33_clk_desc, ++ }, + { } + }; + MODULE_DEVICE_TABLE(of, sunxi_de2_clk_ids); +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch new file mode 100644 index 000000000..7284fe0e0 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-Add-PM-runtime-flags.patch @@ -0,0 +1,111 @@ +From ce56f3f385e0830a1e242f9fca9a82c3067ba03f 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 GPU_PM_RT flag, and implement in +panfrost_device_runtime_suspend/resume. + +Signed-off-by: Philippe Simons +--- + drivers/gpu/drm/panfrost/panfrost_device.c | 33 ++++++++++++++++++++++ + drivers/gpu/drm/panfrost/panfrost_device.h | 3 ++ + 2 files changed, 36 insertions(+) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c +index a45e4addcc19..93d48e97ce10 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.c ++++ b/drivers/gpu/drm/panfrost/panfrost_device.c +@@ -406,11 +406,36 @@ 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)) { ++ ret = reset_control_deassert(pfdev->rstc); ++ if (ret) ++ return ret; ++ ++ 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_disable(pfdev->clock); ++err_clk: ++ if (pfdev->comp->pm_features & BIT(GPU_PM_RT)) ++ reset_control_assert(pfdev->rstc); ++ return ret; + } + + static int panfrost_device_runtime_suspend(struct device *dev) +@@ -426,6 +451,14 @@ 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)) { ++ if (pfdev->bus_clock) ++ clk_disable(pfdev->bus_clock); ++ ++ clk_disable(pfdev->clock); ++ 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..861555ceea65 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -36,10 +36,13 @@ 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: Allow disabling clocks and asserting the reset control during ++ * system runtime suspend + */ + enum panfrost_gpu_pm { + GPU_PM_CLK_DIS, + GPU_PM_VREG_OFF, ++ GPU_PM_RT + }; + + struct panfrost_features { +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-add-h616-compatible-string.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-add-h616-compatible-string.patch new file mode 100644 index 000000000..57ea76e9a --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-add-h616-compatible-string.patch @@ -0,0 +1,43 @@ +From 16e3a927918e0c6349c2bfcbe468ee1690eaaaca 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 GPU_PM_RT feature 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 0f3935556ac7..9470c04c5487 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -776,6 +776,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), ++}; ++ + static const struct panfrost_compatible amlogic_data = { + .num_supplies = ARRAY_SIZE(default_supplies) - 1, + .supply_names = default_supplies, +@@ -859,6 +866,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.16/patches.drm/drm-panfrost-reorder-pd-clk-rst-sequence.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-reorder-pd-clk-rst-sequence.patch new file mode 100644 index 000000000..a63c07fef --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-panfrost-reorder-pd-clk-rst-sequence.patch @@ -0,0 +1,106 @@ +From 37f8be7eaca786f85cf2a17dfd33227e2ff45780 Mon Sep 17 00:00:00 2001 +From: Philippe Simons +Date: Thu, 3 Apr 2025 07:52:10 +0200 +Subject: drm/panfrost: reorder pd/clk/rst sequence + +According to Mali manuals, the powerup sequence should be +enable pd, asserting the reset then enabling the clock and +the reverse for powerdown. + +Signed-off-by: Philippe Simons +--- + drivers/gpu/drm/panfrost/panfrost_device.c | 38 +++++++++++----------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c +index 93d48e97ce10..5d35076b2e6d 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.c ++++ b/drivers/gpu/drm/panfrost/panfrost_device.c +@@ -209,10 +209,20 @@ int panfrost_device_init(struct panfrost_device *pfdev) + + spin_lock_init(&pfdev->cycle_counter.lock); + ++ err = panfrost_pm_domain_init(pfdev); ++ if (err) ++ return err; ++ ++ err = panfrost_reset_init(pfdev); ++ if (err) { ++ dev_err(pfdev->dev, "reset init failed %d\n", err); ++ goto out_pm_domain; ++ } ++ + err = panfrost_clk_init(pfdev); + if (err) { + dev_err(pfdev->dev, "clk init failed %d\n", err); +- return err; ++ goto out_reset; + } + + err = panfrost_devfreq_init(pfdev); +@@ -229,25 +239,15 @@ int panfrost_device_init(struct panfrost_device *pfdev) + goto out_devfreq; + } + +- err = panfrost_reset_init(pfdev); +- if (err) { +- dev_err(pfdev->dev, "reset init failed %d\n", err); +- goto out_regulator; +- } +- +- err = panfrost_pm_domain_init(pfdev); +- if (err) +- goto out_reset; +- + pfdev->iomem = devm_platform_ioremap_resource(pfdev->pdev, 0); + if (IS_ERR(pfdev->iomem)) { + err = PTR_ERR(pfdev->iomem); +- goto out_pm_domain; ++ goto out_regulator; + } + + err = panfrost_gpu_init(pfdev); + if (err) +- goto out_pm_domain; ++ goto out_regulator; + + err = panfrost_mmu_init(pfdev); + if (err) +@@ -268,16 +268,16 @@ int panfrost_device_init(struct panfrost_device *pfdev) + panfrost_mmu_fini(pfdev); + out_gpu: + panfrost_gpu_fini(pfdev); +-out_pm_domain: +- panfrost_pm_domain_fini(pfdev); +-out_reset: +- panfrost_reset_fini(pfdev); + out_regulator: + panfrost_regulator_fini(pfdev); + out_devfreq: + panfrost_devfreq_fini(pfdev); + out_clk: + panfrost_clk_fini(pfdev); ++out_reset: ++ panfrost_reset_fini(pfdev); ++out_pm_domain: ++ panfrost_pm_domain_fini(pfdev); + return err; + } + +@@ -287,11 +287,11 @@ void panfrost_device_fini(struct panfrost_device *pfdev) + panfrost_job_fini(pfdev); + panfrost_mmu_fini(pfdev); + panfrost_gpu_fini(pfdev); +- panfrost_pm_domain_fini(pfdev); +- panfrost_reset_fini(pfdev); + panfrost_devfreq_fini(pfdev); + panfrost_regulator_fini(pfdev); + panfrost_clk_fini(pfdev); ++ panfrost_reset_fini(pfdev); ++ panfrost_pm_domain_fini(pfdev); + } + + #define PANFROST_EXCEPTION(id) \ +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-add-sun50i-h616-hdmi-phy-support.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-add-sun50i-h616-hdmi-phy-support.patch new file mode 100644 index 000000000..d1e28132f --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-add-sun50i-h616-hdmi-phy-support.patch @@ -0,0 +1,108 @@ +From 6c8bbaf43b8eaf62d4682ce66a35fc7f341f4a13 Mon Sep 17 00:00:00 2001 +From: The-going <48602507+The-going@users.noreply.github.com> +Date: Mon, 10 Feb 2025 15:45:13 +0300 +Subject: [PATCH] drm: sun4i: add sun50i-h616-hdmi-phy support + +--- + drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 71 ++++++++++++++++++++++++++ + 1 file changed, 71 insertions(+) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +index 4fa69c463dc4..8a07052037c3 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c ++++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +@@ -124,6 +124,66 @@ static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = { + { ~0UL, 0x0000, 0x0000, 0x0000} + }; + ++static const struct dw_hdmi_mpll_config sun50i_h616_mpll_cfg[] = { ++ { ++ 27000000, { ++ {0x00b3, 0x0003}, ++ {0x2153, 0x0003}, ++ {0x40f3, 0x0003}, ++ }, ++ }, { ++ 74250000, { ++ {0x0072, 0x0003}, ++ {0x2145, 0x0003}, ++ {0x4061, 0x0003}, ++ }, ++ }, { ++ 148500000, { ++ {0x0051, 0x0003}, ++ {0x214c, 0x0003}, ++ {0x4064, 0x0003}, ++ }, ++ }, { ++ 297000000, { ++ {0x0040, 0x0003}, ++ {0x3b4c, 0x0003}, ++ {0x5a64, 0x0003}, ++ }, ++ }, { ++ 594000000, { ++ {0x1a40, 0x0003}, ++ {0x3b4c, 0x0003}, ++ {0x5a64, 0x0003}, ++ }, ++ }, { ++ ~0UL, { ++ {0x0000, 0x0000}, ++ {0x0000, 0x0000}, ++ {0x0000, 0x0000}, ++ }, ++ } ++}; ++ ++static const struct dw_hdmi_curr_ctrl sun50i_h616_cur_ctr[] = { ++ /* pixelclk bpp8 bpp10 bpp12 */ ++ { 27000000, { 0x0012, 0x0000, 0x0000 }, }, ++ { 74250000, { 0x0013, 0x0013, 0x0013 }, }, ++ { 148500000, { 0x0019, 0x0019, 0x0019 }, }, ++ { 297000000, { 0x0019, 0x001b, 0x0019 }, }, ++ { 594000000, { 0x0010, 0x0010, 0x0010 }, }, ++ { ~0UL, { 0x0000, 0x0000, 0x0000 }, } ++}; ++ ++static const struct dw_hdmi_phy_config sun50i_h616_phy_config[] = { ++ /*pixelclk symbol term vlev*/ ++ {27000000, 0x8009, 0x0007, 0x02b0}, ++ {74250000, 0x8019, 0x0004, 0x0290}, ++ {148500000, 0x8019, 0x0004, 0x0290}, ++ {297000000, 0x8039, 0x0004, 0x022b}, ++ {594000000, 0x8029, 0x0000, 0x008a}, ++ {~0UL, 0x0000, 0x0000, 0x0000} ++}; ++ + static void sun8i_hdmi_phy_set_polarity(struct sun8i_hdmi_phy *phy, + const struct drm_display_mode *mode) + { +@@ -626,6 +686,13 @@ static const struct sun8i_hdmi_phy_variant sun50i_h6_hdmi_phy = { + .phy_init = &sun50i_hdmi_phy_init_h6, + }; + ++static const struct sun8i_hdmi_phy_variant sun50i_h616_hdmi_phy = { ++ .cur_ctr = sun50i_h616_cur_ctr, ++ .mpll_cfg = sun50i_h616_mpll_cfg, ++ .phy_cfg = sun50i_h616_phy_config, ++ .phy_init = &sun50i_hdmi_phy_init_h6, ++}; ++ + static const struct of_device_id sun8i_hdmi_phy_of_table[] = { + { + .compatible = "allwinner,sun8i-a83t-hdmi-phy", +@@ -647,6 +714,10 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = { + .compatible = "allwinner,sun50i-h6-hdmi-phy", + .data = &sun50i_h6_hdmi_phy, + }, ++ { ++ .compatible = "allwinner,sun50i-h616-hdmi-phy", ++ .data = &sun50i_h616_hdmi_phy, ++ }, + { /* sentinel */ } + }; + +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-Initialize-layer-fields-earlier.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-Initialize-layer-fields-earlier.patch new file mode 100644 index 000000000..f5555d4b0 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-Initialize-layer-fields-earlier.patch @@ -0,0 +1,75 @@ +From 5c2859b3cccd1b1b3f1700fd70c06770f418247a Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:36 +1300 +Subject: drm: sun4i: de2: Initialize layer fields earlier + +drm_universal_plane_init() can already call some callbacks, like +format_mod_supported, during initialization. Because of that, fields +should be initialized beforehand. + +Signed-off-by: Jernej Skrabec +Co-developed-by: Ryan Walklin +Signed-off-by: Ryan Walklin +Reviewed-by: Chen-Yu Tsai +--- + drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 9 +++++---- + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 9 +++++---- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +index aa987bca1dbb..cb9b694fef10 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +@@ -295,6 +295,11 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm, + if (!layer) + return ERR_PTR(-ENOMEM); + ++ layer->mixer = mixer; ++ layer->type = SUN8I_LAYER_TYPE_UI; ++ layer->channel = channel; ++ layer->overlay = 0; ++ + if (index == 0) + type = DRM_PLANE_TYPE_PRIMARY; + +@@ -325,10 +330,6 @@ struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm, + } + + drm_plane_helper_add(&layer->plane, &sun8i_ui_layer_helper_funcs); +- layer->mixer = mixer; +- layer->type = SUN8I_LAYER_TYPE_UI; +- layer->channel = channel; +- layer->overlay = 0; + + return layer; + } +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index f3a5329351ca..3c657b069d1f 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -478,6 +478,11 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + if (!layer) + return ERR_PTR(-ENOMEM); + ++ layer->mixer = mixer; ++ layer->type = SUN8I_LAYER_TYPE_VI; ++ layer->channel = index; ++ layer->overlay = 0; ++ + if (mixer->cfg->is_de3) { + formats = sun8i_vi_layer_de3_formats; + format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); +@@ -536,10 +541,6 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + } + + drm_plane_helper_add(&layer->plane, &sun8i_vi_layer_helper_funcs); +- layer->mixer = mixer; +- layer->type = SUN8I_LAYER_TYPE_VI; +- layer->channel = index; +- layer->overlay = 0; + + return layer; + } +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Change-CSC-argument.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Change-CSC-argument.patch new file mode 100644 index 000000000..9125e4fa0 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Change-CSC-argument.patch @@ -0,0 +1,178 @@ +From 54669ac67e47835b8cc3eea215026385a0050567 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:33 +1300 +Subject: drm: sun4i: de2/de3: Change CSC argument + +Currently, CSC module takes care only for converting YUV to RGB. +However, DE3 is more suited to work in YUV color space. Change CSC mode +argument to format type to be more neutral. New argument only tells +layer format type and doesn't imply output type. + +This commit doesn't make any functional change. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +Reviewed-by: Andre Przywara +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 22 +++++++++++----------- + drivers/gpu/drm/sun4i/sun8i_csc.h | 10 +++++----- + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 16 ++++++++-------- + 3 files changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index 58480d8e4f70..6ebd1c3aa3ab 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -108,7 +108,7 @@ static const u32 yuv2rgb_de3[2][3][12] = { + }; + + static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, +- enum sun8i_csc_mode mode, ++ enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) + { +@@ -118,12 +118,12 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, + + table = yuv2rgb[range][encoding]; + +- switch (mode) { +- case SUN8I_CSC_MODE_YUV2RGB: ++ switch (fmt_type) { ++ case FORMAT_TYPE_YUV: + base_reg = SUN8I_CSC_COEFF(base, 0); + regmap_bulk_write(map, base_reg, table, 12); + break; +- case SUN8I_CSC_MODE_YVU2RGB: ++ case FORMAT_TYPE_YVU: + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) + base_reg = SUN8I_CSC_COEFF(base, i + 1); +@@ -141,7 +141,7 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, + } + + static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, +- enum sun8i_csc_mode mode, ++ enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) + { +@@ -151,12 +151,12 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, + + table = yuv2rgb_de3[range][encoding]; + +- switch (mode) { +- case SUN8I_CSC_MODE_YUV2RGB: ++ switch (fmt_type) { ++ case FORMAT_TYPE_YUV: + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); + regmap_bulk_write(map, addr, table, 12); + break; +- case SUN8I_CSC_MODE_YVU2RGB: ++ case FORMAT_TYPE_YVU: + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, +@@ -206,7 +206,7 @@ static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable) + } + + void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, +- enum sun8i_csc_mode mode, ++ enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) + { +@@ -214,14 +214,14 @@ void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, + + if (mixer->cfg->is_de3) { + sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer, +- mode, encoding, range); ++ fmt_type, encoding, range); + return; + } + + base = ccsc_base[mixer->cfg->ccsc][layer]; + + sun8i_csc_set_coefficients(mixer->engine.regs, base, +- mode, encoding, range); ++ fmt_type, encoding, range); + } + + void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable) +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h +index 828b86fd0cab..7322770f39f0 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.h ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.h +@@ -22,14 +22,14 @@ struct sun8i_mixer; + + #define SUN8I_CSC_CTRL_EN BIT(0) + +-enum sun8i_csc_mode { +- SUN8I_CSC_MODE_OFF, +- SUN8I_CSC_MODE_YUV2RGB, +- SUN8I_CSC_MODE_YVU2RGB, ++enum format_type { ++ FORMAT_TYPE_RGB, ++ FORMAT_TYPE_YUV, ++ FORMAT_TYPE_YVU, + }; + + void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, +- enum sun8i_csc_mode mode, ++ enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range); + void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable); +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 9c09d9c08496..8a80934e928f 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -193,19 +193,19 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + return 0; + } + +-static u32 sun8i_vi_layer_get_csc_mode(const struct drm_format_info *format) ++static u32 sun8i_vi_layer_get_format_type(const struct drm_format_info *format) + { + if (!format->is_yuv) +- return SUN8I_CSC_MODE_OFF; ++ return FORMAT_TYPE_RGB; + + switch (format->format) { + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YVU444: +- return SUN8I_CSC_MODE_YVU2RGB; ++ return FORMAT_TYPE_YVU; + default: +- return SUN8I_CSC_MODE_YUV2RGB; ++ return FORMAT_TYPE_YUV; + } + } + +@@ -213,7 +213,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane) + { + struct drm_plane_state *state = plane->state; +- u32 val, ch_base, csc_mode, hw_fmt; ++ u32 val, ch_base, fmt_type, hw_fmt; + const struct drm_format_info *fmt; + int ret; + +@@ -231,9 +231,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, + SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay), + SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); + +- csc_mode = sun8i_vi_layer_get_csc_mode(fmt); +- if (csc_mode != SUN8I_CSC_MODE_OFF) { +- sun8i_csc_set_ccsc_coefficients(mixer, channel, csc_mode, ++ fmt_type = sun8i_vi_layer_get_format_type(fmt); ++ if (fmt_type != FORMAT_TYPE_RGB) { ++ sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_type, + state->color_encoding, + state->color_range); + sun8i_csc_enable_ccsc(mixer, channel, true); +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Merge-CSC-functions-into-one.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Merge-CSC-functions-into-one.patch new file mode 100644 index 000000000..a487d9d89 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-Merge-CSC-functions-into-one.patch @@ -0,0 +1,221 @@ +From 09744193cdcf400e5a4c54d9309acf5aea3a591c Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:34 +1300 +Subject: drm: sun4i: de2/de3: Merge CSC functions into one + +At the moment the colour space conversion is handled by two functions: +one to setup the conversion parameters, and another one to enable the +conversion. Merging both into one gives more flexibility for upcoming +extensions to support whole YUV pipelines, in the DE33. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +Reviewed-by: Andre Przywara +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 89 ++++++++++---------------- + drivers/gpu/drm/sun4i/sun8i_csc.h | 9 ++- + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 11 +--- + 3 files changed, 40 insertions(+), 69 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index 6ebd1c3aa3ab..0dcbc0866ae8 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -107,23 +107,28 @@ static const u32 yuv2rgb_de3[2][3][12] = { + }, + }; + +-static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, +- enum format_type fmt_type, +- enum drm_color_encoding encoding, +- enum drm_color_range range) ++static void sun8i_csc_setup(struct regmap *map, u32 base, ++ enum format_type fmt_type, ++ enum drm_color_encoding encoding, ++ enum drm_color_range range) + { ++ u32 base_reg, val; + const u32 *table; +- u32 base_reg; + int i; + + table = yuv2rgb[range][encoding]; + + switch (fmt_type) { ++ case FORMAT_TYPE_RGB: ++ val = 0; ++ break; + case FORMAT_TYPE_YUV: ++ val = SUN8I_CSC_CTRL_EN; + base_reg = SUN8I_CSC_COEFF(base, 0); + regmap_bulk_write(map, base_reg, table, 12); + break; + case FORMAT_TYPE_YVU: ++ val = SUN8I_CSC_CTRL_EN; + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) + base_reg = SUN8I_CSC_COEFF(base, i + 1); +@@ -135,28 +140,37 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, + } + break; + default: ++ val = 0; + DRM_WARN("Wrong CSC mode specified.\n"); + return; + } ++ ++ regmap_write(map, SUN8I_CSC_CTRL(base), val); + } + +-static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, +- enum format_type fmt_type, +- enum drm_color_encoding encoding, +- enum drm_color_range range) ++static void sun8i_de3_ccsc_setup(struct regmap *map, int layer, ++ enum format_type fmt_type, ++ enum drm_color_encoding encoding, ++ enum drm_color_range range) + { ++ u32 addr, val, mask; + const u32 *table; +- u32 addr; + int i; + ++ mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); + table = yuv2rgb_de3[range][encoding]; + + switch (fmt_type) { ++ case FORMAT_TYPE_RGB: ++ val = 0; ++ break; + case FORMAT_TYPE_YUV: ++ val = mask; + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); + regmap_bulk_write(map, addr, table, 12); + break; + case FORMAT_TYPE_YVU: ++ val = mask; + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, +@@ -173,67 +187,30 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, + } + break; + default: ++ val = 0; + DRM_WARN("Wrong CSC mode specified.\n"); + return; + } +-} +- +-static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable) +-{ +- u32 val; +- +- if (enable) +- val = SUN8I_CSC_CTRL_EN; +- else +- val = 0; +- +- regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val); +-} +- +-static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable) +-{ +- u32 val, mask; +- +- mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); +- +- if (enable) +- val = mask; +- else +- val = 0; + + regmap_update_bits(map, SUN50I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE), + mask, val); + } + +-void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, +- enum format_type fmt_type, +- enum drm_color_encoding encoding, +- enum drm_color_range range) +-{ +- u32 base; +- +- if (mixer->cfg->is_de3) { +- sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer, +- fmt_type, encoding, range); +- return; +- } +- +- base = ccsc_base[mixer->cfg->ccsc][layer]; +- +- sun8i_csc_set_coefficients(mixer->engine.regs, base, +- fmt_type, encoding, range); +-} +- +-void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable) ++void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, ++ enum format_type fmt_type, ++ enum drm_color_encoding encoding, ++ enum drm_color_range range) + { + u32 base; + + if (mixer->cfg->is_de3) { +- sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable); ++ sun8i_de3_ccsc_setup(mixer->engine.regs, layer, ++ fmt_type, encoding, range); + return; + } + + base = ccsc_base[mixer->cfg->ccsc][layer]; + +- sun8i_csc_enable(mixer->engine.regs, base, enable); ++ sun8i_csc_setup(mixer->engine.regs, base, ++ fmt_type, encoding, range); + } +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h +index 7322770f39f0..b7546e06e315 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.h ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.h +@@ -28,10 +28,9 @@ enum format_type { + FORMAT_TYPE_YVU, + }; + +-void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, +- enum format_type fmt_type, +- enum drm_color_encoding encoding, +- enum drm_color_range range); +-void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable); ++void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, ++ enum format_type fmt_type, ++ enum drm_color_encoding encoding, ++ enum drm_color_range range); + + #endif +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 8a80934e928f..f3a5329351ca 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -232,14 +232,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, + SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); + + fmt_type = sun8i_vi_layer_get_format_type(fmt); +- if (fmt_type != FORMAT_TYPE_RGB) { +- sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_type, +- state->color_encoding, +- state->color_range); +- sun8i_csc_enable_ccsc(mixer, channel, true); +- } else { +- sun8i_csc_enable_ccsc(mixer, channel, false); +- } ++ sun8i_csc_set_ccsc(mixer, channel, fmt_type, ++ state->color_encoding, ++ state->color_range); + + if (!fmt->is_yuv) + val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE; +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-generic-blender-register-reference-functi.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-generic-blender-register-reference-functi.patch new file mode 100644 index 000000000..2757ba5e2 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-generic-blender-register-reference-functi.patch @@ -0,0 +1,38 @@ +From 45d06599927825fe1fa3c374508d6d0c8c9f9f52 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:48 +1300 +Subject: drm: sun4i: de2/de3: add generic blender register reference function + +The DE2 and DE3 engines have a blender register range within the +mixer engine register map, whereas the DE33 separates this out into +a separate display group. + +Prepare for this by adding a function to look the blender reference up, +with a subsequent patch to add a conditional based on the DE type. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h +index 82956cb97cfd..75facc7d1fa6 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h +@@ -224,6 +224,12 @@ sun8i_blender_base(struct sun8i_mixer *mixer) + return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE; + } + ++static inline struct regmap * ++sun8i_blender_regmap(struct sun8i_mixer *mixer) ++{ ++ return mixer->engine.regs; ++} ++ + static inline u32 + sun8i_channel_base(struct sun8i_mixer *mixer, int channel) + { +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-mixer-version-enum.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-mixer-version-enum.patch new file mode 100644 index 000000000..0df4a242c --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-add-mixer-version-enum.patch @@ -0,0 +1,257 @@ +From b49e4fb3439c50eb6effc559366b3e88e2ac2f27 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:45 +1300 +Subject: drm: sun4i: de2/de3: add mixer version enum + +The Allwinner DE2 and DE3 display engine mixers are currently identified +by a simple boolean flag. This will not scale to support additional DE +variants. + +Convert the boolean flag to an enum. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +Reviewed-by: Andre Przywara +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 2 +- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 14 ++++++++++++-- + drivers/gpu/drm/sun4i/sun8i_mixer.h | 11 ++++++++--- + drivers/gpu/drm/sun4i/sun8i_ui_scaler.c | 2 +- + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 8 ++++---- + drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 4 ++-- + 6 files changed, 28 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index e12a81fa9108..2d5a2cf7cba2 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -365,7 +365,7 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, + { + u32 base; + +- if (mixer->cfg->is_de3) { ++ if (mixer->cfg->de_type == sun8i_mixer_de3) { + sun8i_de3_ccsc_setup(&mixer->engine, layer, + fmt_type, encoding, range); + return; +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index a50c583852ed..16e018aa4aae 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -584,7 +584,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, + base = sun8i_blender_base(mixer); + + /* Reset registers and disable unused sub-engines */ +- if (mixer->cfg->is_de3) { ++ if (mixer->cfg->de_type == sun8i_mixer_de3) { + for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4) + regmap_write(mixer->engine.regs, i, 0); + +@@ -675,6 +675,7 @@ static void sun8i_mixer_remove(struct platform_device *pdev) + + static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = { + .ccsc = CCSC_MIXER0_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .scaler_mask = 0xf, + .scanline_yuv = 2048, + .ui_num = 3, +@@ -683,6 +684,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer0_cfg = { + + static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = { + .ccsc = CCSC_MIXER1_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .scaler_mask = 0x3, + .scanline_yuv = 2048, + .ui_num = 1, +@@ -691,6 +693,7 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = { + + static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = { + .ccsc = CCSC_MIXER0_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .mod_rate = 432000000, + .scaler_mask = 0xf, + .scanline_yuv = 2048, +@@ -700,6 +703,7 @@ static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = { + + static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = { + .ccsc = CCSC_MIXER0_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .mod_rate = 297000000, + .scaler_mask = 0xf, + .scanline_yuv = 2048, +@@ -709,6 +713,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer0_cfg = { + + static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = { + .ccsc = CCSC_MIXER1_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .mod_rate = 297000000, + .scaler_mask = 0x3, + .scanline_yuv = 2048, +@@ -717,6 +722,7 @@ static const struct sun8i_mixer_cfg sun8i_r40_mixer1_cfg = { + }; + + static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { ++ .de_type = sun8i_mixer_de2, + .vi_num = 2, + .ui_num = 1, + .scaler_mask = 0x3, +@@ -727,6 +733,7 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { + + static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = { + .ccsc = CCSC_D1_MIXER0_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .mod_rate = 297000000, + .scaler_mask = 0x3, + .scanline_yuv = 2048, +@@ -736,6 +743,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer0_cfg = { + + static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = { + .ccsc = CCSC_MIXER1_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .mod_rate = 297000000, + .scaler_mask = 0x1, + .scanline_yuv = 1024, +@@ -745,6 +753,7 @@ static const struct sun8i_mixer_cfg sun20i_d1_mixer1_cfg = { + + static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = { + .ccsc = CCSC_MIXER0_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .mod_rate = 297000000, + .scaler_mask = 0xf, + .scanline_yuv = 4096, +@@ -754,6 +763,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = { + + static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = { + .ccsc = CCSC_MIXER1_LAYOUT, ++ .de_type = sun8i_mixer_de2, + .mod_rate = 297000000, + .scaler_mask = 0x3, + .scanline_yuv = 2048, +@@ -763,7 +773,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = { + + static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = { + .ccsc = CCSC_MIXER0_LAYOUT, +- .is_de3 = true, ++ .de_type = sun8i_mixer_de3, + .has_formatter = 1, + .mod_rate = 600000000, + .scaler_mask = 0xf, +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h +index 8417b8fef2e1..82956cb97cfd 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h +@@ -151,6 +151,11 @@ enum { + CCSC_D1_MIXER0_LAYOUT, + }; + ++enum sun8i_mixer_type { ++ sun8i_mixer_de2, ++ sun8i_mixer_de3, ++}; ++ + /** + * struct sun8i_mixer_cfg - mixer HW configuration + * @vi_num: number of VI channels +@@ -172,7 +177,7 @@ struct sun8i_mixer_cfg { + int scaler_mask; + int ccsc; + unsigned long mod_rate; +- unsigned int is_de3 : 1; ++ unsigned int de_type; + unsigned int has_formatter : 1; + unsigned int scanline_yuv; + }; +@@ -216,13 +221,13 @@ engine_to_sun8i_mixer(struct sunxi_engine *engine) + static inline u32 + sun8i_blender_base(struct sun8i_mixer *mixer) + { +- return mixer->cfg->is_de3 ? DE3_BLD_BASE : DE2_BLD_BASE; ++ return mixer->cfg->de_type == sun8i_mixer_de3 ? DE3_BLD_BASE : DE2_BLD_BASE; + } + + static inline u32 + sun8i_channel_base(struct sun8i_mixer *mixer, int channel) + { +- if (mixer->cfg->is_de3) ++ if (mixer->cfg->de_type == sun8i_mixer_de3) + return DE3_CH_BASE + channel * DE3_CH_SIZE; + else + return DE2_CH_BASE + channel * DE2_CH_SIZE; +diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c +index ae0806bccac7..504ffa0971a4 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c ++++ b/drivers/gpu/drm/sun4i/sun8i_ui_scaler.c +@@ -93,7 +93,7 @@ static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel) + { + int vi_num = mixer->cfg->vi_num; + +- if (mixer->cfg->is_de3) ++ if (mixer->cfg->de_type == sun8i_mixer_de3) + return DE3_VI_SCALER_UNIT_BASE + + DE3_VI_SCALER_UNIT_SIZE * vi_num + + DE3_UI_SCALER_UNIT_SIZE * (channel - vi_num); +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 3c657b069d1f..4647e9bcccaa 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -25,7 +25,7 @@ static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel, + + ch_base = sun8i_channel_base(mixer, channel); + +- if (mixer->cfg->is_de3) { ++ if (mixer->cfg->de_type >= sun8i_mixer_de3) { + mask = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK | + SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_MASK; + val = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA +@@ -483,7 +483,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + layer->channel = index; + layer->overlay = 0; + +- if (mixer->cfg->is_de3) { ++ if (mixer->cfg->de_type >= sun8i_mixer_de3) { + formats = sun8i_vi_layer_de3_formats; + format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); + } else { +@@ -507,7 +507,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + + plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num; + +- if (mixer->cfg->vi_num == 1 || mixer->cfg->is_de3) { ++ if (mixer->cfg->vi_num == 1 || mixer->cfg->de_type >= sun8i_mixer_de3) { + ret = drm_plane_create_alpha_property(&layer->plane); + if (ret) { + dev_err(drm->dev, "Couldn't add alpha property\n"); +@@ -524,7 +524,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + + supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709); +- if (mixer->cfg->is_de3) ++ if (mixer->cfg->de_type >= sun8i_mixer_de3) + supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020); + + supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +index 2e49a6e5f1f1..aa346c3beb30 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +@@ -835,7 +835,7 @@ static const u32 bicubic4coefftab32[480] = { + + static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) + { +- if (mixer->cfg->is_de3) ++ if (mixer->cfg->de_type == sun8i_mixer_de3) + return DE3_VI_SCALER_UNIT_BASE + + DE3_VI_SCALER_UNIT_SIZE * channel; + else +@@ -982,7 +982,7 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, + cvphase = vphase; + } + +- if (mixer->cfg->is_de3) { ++ if (mixer->cfg->de_type >= sun8i_mixer_de3) { + u32 val; + + if (format->hsub == 1 && format->vsub == 1) +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-call-csc-setup-also-for-UI-layer.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-call-csc-setup-also-for-UI-layer.patch new file mode 100644 index 000000000..96847a05d --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-call-csc-setup-also-for-UI-layer.patch @@ -0,0 +1,64 @@ +From 000c586a34ad82e4673e6dfda5457147b0d85606 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:35 +1300 +Subject: drm: sun4i: de2/de3: call csc setup also for UI layer + +Currently, only VI layer calls CSC setup function. This comes from DE2 +limitation, which doesn't have CSC unit for UI layers. However, DE3 has +separate CSC units for each layer. This allows display pipeline to make +output signal in different color spaces. To support both use cases, add +a call to CSC setup function also in UI layer code. For DE2, this will +be a no-op, but it will allow DE3 to output signal in multiple formats. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 8 +++++--- + drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 6 ++++++ + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index 0dcbc0866ae8..68d955c63b05 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -209,8 +209,10 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, + return; + } + +- base = ccsc_base[mixer->cfg->ccsc][layer]; ++ if (layer < mixer->cfg->vi_num) { ++ base = ccsc_base[mixer->cfg->ccsc][layer]; + +- sun8i_csc_setup(mixer->engine.regs, base, +- fmt_type, encoding, range); ++ sun8i_csc_setup(mixer->engine.regs, base, ++ fmt_type, encoding, range); ++ } + } +diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +index b90e5edef4e8..aa987bca1dbb 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +@@ -20,6 +20,7 @@ + #include + #include + ++#include "sun8i_csc.h" + #include "sun8i_mixer.h" + #include "sun8i_ui_layer.h" + #include "sun8i_ui_scaler.h" +@@ -135,6 +136,11 @@ static int sun8i_ui_layer_update_formats(struct sun8i_mixer *mixer, int channel, + SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay), + SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK, val); + ++ /* Note: encoding and range arguments are ignored for RGB */ ++ sun8i_csc_set_ccsc(mixer, channel, FORMAT_TYPE_RGB, ++ DRM_COLOR_YCBCR_BT601, ++ DRM_COLOR_YCBCR_FULL_RANGE); ++ + return 0; + } + +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-refactor-mixer-initialisation.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-refactor-mixer-initialisation.patch new file mode 100644 index 000000000..4357b5b77 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-refactor-mixer-initialisation.patch @@ -0,0 +1,121 @@ +From 18890b5c9dbf9270b7f0e42875d6b8bd14ee6624 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:46 +1300 +Subject: drm: sun4i: de2/de3: refactor mixer initialisation + +Now that the DE variant can be selected by enum, take the oppportunity +to factor out some common initialisation code to a separate function. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +Reviewed-by: Andre Przywara +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 64 +++++++++++++++-------------- + 1 file changed, 34 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 16e018aa4aae..18745af08954 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -468,6 +468,38 @@ static int sun8i_mixer_of_get_id(struct device_node *node) + return of_ep.id; + } + ++static void sun8i_mixer_init(struct sun8i_mixer *mixer) ++{ ++ unsigned int base = sun8i_blender_base(mixer); ++ int plane_cnt, i; ++ ++ /* Enable the mixer */ ++ regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL, ++ SUN8I_MIXER_GLOBAL_CTL_RT_EN); ++ ++ /* Set background color to black */ ++ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base), ++ SUN8I_MIXER_BLEND_COLOR_BLACK); ++ ++ /* ++ * Set fill color of bottom plane to black. Generally not needed ++ * except when VI plane is at bottom (zpos = 0) and enabled. ++ */ ++ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), ++ SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); ++ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), ++ SUN8I_MIXER_BLEND_COLOR_BLACK); ++ ++ plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; ++ for (i = 0; i < plane_cnt; i++) ++ regmap_write(mixer->engine.regs, ++ SUN8I_MIXER_BLEND_MODE(base, i), ++ SUN8I_MIXER_BLEND_MODE_DEF); ++ ++ regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), ++ SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0); ++} ++ + static int sun8i_mixer_bind(struct device *dev, struct device *master, + void *data) + { +@@ -476,8 +508,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, + struct sun4i_drv *drv = drm->dev_private; + struct sun8i_mixer *mixer; + void __iomem *regs; +- unsigned int base; +- int plane_cnt; + int i, ret; + + /* +@@ -581,8 +611,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, + + list_add_tail(&mixer->engine.list, &drv->engine_list); + +- base = sun8i_blender_base(mixer); +- + /* Reset registers and disable unused sub-engines */ + if (mixer->cfg->de_type == sun8i_mixer_de3) { + for (i = 0; i < DE3_MIXER_UNIT_SIZE; i += 4) +@@ -598,7 +626,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, + regmap_write(mixer->engine.regs, SUN50I_MIXER_FMT_EN, 0); + regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC0_EN, 0); + regmap_write(mixer->engine.regs, SUN50I_MIXER_CDC1_EN, 0); +- } else { ++ } else if (mixer->cfg->de_type == sun8i_mixer_de2) { + for (i = 0; i < DE2_MIXER_UNIT_SIZE; i += 4) + regmap_write(mixer->engine.regs, i, 0); + +@@ -611,31 +639,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, + regmap_write(mixer->engine.regs, SUN8I_MIXER_DCSC_EN, 0); + } + +- /* Enable the mixer */ +- regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL, +- SUN8I_MIXER_GLOBAL_CTL_RT_EN); +- +- /* Set background color to black */ +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base), +- SUN8I_MIXER_BLEND_COLOR_BLACK); +- +- /* +- * Set fill color of bottom plane to black. Generally not needed +- * except when VI plane is at bottom (zpos = 0) and enabled. +- */ +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), +- SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), +- SUN8I_MIXER_BLEND_COLOR_BLACK); +- +- plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; +- for (i = 0; i < plane_cnt; i++) +- regmap_write(mixer->engine.regs, +- SUN8I_MIXER_BLEND_MODE(base, i), +- SUN8I_MIXER_BLEND_MODE_DEF); +- +- regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), +- SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0); ++ sun8i_mixer_init(mixer); + + return 0; + +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-use-generic-register-reference-function-for-l.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-use-generic-register-reference-function-for-l.patch new file mode 100644 index 000000000..ae503d937 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de2-de3-use-generic-register-reference-function-for-l.patch @@ -0,0 +1,117 @@ +From a756d6b4ac645ac3c18d5758faec068b3c8819a6 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:49 +1300 +Subject: drm: sun4i: de2/de3: use generic register reference function for + layer configuration + +Use the new blender register lookup function where required in the layer +commit and update code. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 5 +++-- + drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 7 +++++-- + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 6 ++++-- + 3 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 18745af08954..600084286b39 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -277,6 +277,7 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine, + { + struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); + u32 bld_base = sun8i_blender_base(mixer); ++ struct regmap *bld_regs = sun8i_blender_regmap(mixer); + struct drm_plane_state *plane_state; + struct drm_plane *plane; + u32 route = 0, pipe_en = 0; +@@ -316,8 +317,8 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine, + pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos); + } + +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route); +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base), ++ regmap_write(bld_regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route); ++ regmap_write(bld_regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base), + pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); + + regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF, +diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +index cb9b694fef10..7f1231cf0f01 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +@@ -24,6 +24,7 @@ + #include "sun8i_mixer.h" + #include "sun8i_ui_layer.h" + #include "sun8i_ui_scaler.h" ++#include "sun8i_vi_scaler.h" + + static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane) +@@ -52,6 +53,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, + { + struct drm_plane_state *state = plane->state; + u32 src_w, src_h, dst_w, dst_h; ++ struct regmap *bld_regs; + u32 bld_base, ch_base; + u32 outsize, insize; + u32 hphase, vphase; +@@ -60,6 +62,7 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, + channel, overlay); + + bld_base = sun8i_blender_base(mixer); ++ bld_regs = sun8i_blender_regmap(mixer); + ch_base = sun8i_channel_base(mixer, channel); + + src_w = drm_rect_width(&state->src) >> 16; +@@ -104,10 +107,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, + DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n", + state->dst.x1, state->dst.y1); + DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); +- regmap_write(mixer->engine.regs, ++ regmap_write(bld_regs, + SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos), + SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); +- regmap_write(mixer->engine.regs, ++ regmap_write(bld_regs, + SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos), + outsize); + +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index e348fd0a3d81..d19349eecc9d 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -55,6 +55,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + struct drm_plane_state *state = plane->state; + const struct drm_format_info *format = state->fb->format; + u32 src_w, src_h, dst_w, dst_h; ++ struct regmap *bld_regs; + u32 bld_base, ch_base; + u32 outsize, insize; + u32 hphase, vphase; +@@ -66,6 +67,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + channel, overlay); + + bld_base = sun8i_blender_base(mixer); ++ bld_regs = sun8i_blender_regmap(mixer); + ch_base = sun8i_channel_base(mixer, channel); + + src_w = drm_rect_width(&state->src) >> 16; +@@ -182,10 +184,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + DRM_DEBUG_DRIVER("Layer destination coordinates X: %d Y: %d\n", + state->dst.x1, state->dst.y1); + DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); +- regmap_write(mixer->engine.regs, ++ regmap_write(bld_regs, + SUN8I_MIXER_BLEND_ATTR_COORD(bld_base, zpos), + SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); +- regmap_write(mixer->engine.regs, ++ regmap_write(bld_regs, + SUN8I_MIXER_BLEND_ATTR_INSIZE(bld_base, zpos), + outsize); + +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Add-YUV-formatter-module.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Add-YUV-formatter-module.patch new file mode 100644 index 000000000..14f17b6d5 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Add-YUV-formatter-module.patch @@ -0,0 +1,164 @@ +From 8bdcc131fedb576a8db65bb6e87ca8742660add0 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:37 +1300 +Subject: drm: sun4i: de3: Add YUV formatter module + +The display engine formatter (FMT) module is present in the DE3 engine +and provides YUV444 to YUV422/YUV420 conversion, format re-mapping and +color depth conversion. + +Add support for this module. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/Makefile | 3 +- + drivers/gpu/drm/sun4i/sun50i_fmt.c | 82 ++++++++++++++++++++++++++++++ + drivers/gpu/drm/sun4i/sun50i_fmt.h | 32 ++++++++++++ + 3 files changed, 116 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.c + create mode 100644 drivers/gpu/drm/sun4i/sun50i_fmt.h + +diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile +index bad7497a0d11..3f516329f51e 100644 +--- a/drivers/gpu/drm/sun4i/Makefile ++++ b/drivers/gpu/drm/sun4i/Makefile +@@ -16,7 +16,8 @@ sun8i-drm-hdmi-y += sun8i_hdmi_phy_clk.o + + sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \ + sun8i_vi_layer.o sun8i_ui_scaler.o \ +- sun8i_vi_scaler.o sun8i_csc.o ++ sun8i_vi_scaler.o sun8i_csc.o \ ++ sun50i_fmt.o + + sun4i-tcon-y += sun4i_crtc.o + sun4i-tcon-y += sun4i_tcon_dclk.o +diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.c b/drivers/gpu/drm/sun4i/sun50i_fmt.c +new file mode 100644 +index 000000000000..050a8716ae86 +--- /dev/null ++++ b/drivers/gpu/drm/sun4i/sun50i_fmt.c +@@ -0,0 +1,82 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (C) Jernej Skrabec ++ */ ++ ++#include ++ ++#include "sun50i_fmt.h" ++ ++static bool sun50i_fmt_is_10bit(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_RGB101010_1X30: ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ case MEDIA_BUS_FMT_UYVY10_1X20: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static u32 sun50i_fmt_get_colorspace(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ return SUN50I_FMT_CS_YUV420; ++ case MEDIA_BUS_FMT_UYVY8_1X16: ++ case MEDIA_BUS_FMT_UYVY10_1X20: ++ return SUN50I_FMT_CS_YUV422; ++ default: ++ return SUN50I_FMT_CS_YUV444RGB; ++ } ++} ++ ++static void sun50i_fmt_de3_limits(u32 *limits, u32 colorspace, bool bit10) ++{ ++ if (colorspace != SUN50I_FMT_CS_YUV444RGB) { ++ limits[0] = SUN50I_FMT_LIMIT(64, 940); ++ limits[1] = SUN50I_FMT_LIMIT(64, 960); ++ limits[2] = SUN50I_FMT_LIMIT(64, 960); ++ } else if (bit10) { ++ limits[0] = SUN50I_FMT_LIMIT(0, 1023); ++ limits[1] = SUN50I_FMT_LIMIT(0, 1023); ++ limits[2] = SUN50I_FMT_LIMIT(0, 1023); ++ } else { ++ limits[0] = SUN50I_FMT_LIMIT(0, 1021); ++ limits[1] = SUN50I_FMT_LIMIT(0, 1021); ++ limits[2] = SUN50I_FMT_LIMIT(0, 1021); ++ } ++} ++ ++void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, ++ u16 height, u32 format) ++{ ++ u32 colorspace, limit[3], base; ++ struct regmap *regs; ++ bool bit10; ++ ++ colorspace = sun50i_fmt_get_colorspace(format); ++ bit10 = sun50i_fmt_is_10bit(format); ++ base = SUN50I_FMT_DE3; ++ regs = sun8i_blender_regmap(mixer); ++ ++ sun50i_fmt_de3_limits(limit, colorspace, bit10); ++ ++ regmap_write(regs, SUN50I_FMT_CTRL(base), 0); ++ ++ regmap_write(regs, SUN50I_FMT_SIZE(base), ++ SUN8I_MIXER_SIZE(width, height)); ++ regmap_write(regs, SUN50I_FMT_SWAP(base), 0); ++ regmap_write(regs, SUN50I_FMT_DEPTH(base), bit10); ++ regmap_write(regs, SUN50I_FMT_FORMAT(base), colorspace); ++ regmap_write(regs, SUN50I_FMT_COEF(base), 0); ++ ++ regmap_write(regs, SUN50I_FMT_LMT_Y(base), limit[0]); ++ regmap_write(regs, SUN50I_FMT_LMT_C0(base), limit[1]); ++ regmap_write(regs, SUN50I_FMT_LMT_C1(base), limit[2]); ++ ++ regmap_write(regs, SUN50I_FMT_CTRL(base), 1); ++} +diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.h b/drivers/gpu/drm/sun4i/sun50i_fmt.h +new file mode 100644 +index 000000000000..4127f7206aad +--- /dev/null ++++ b/drivers/gpu/drm/sun4i/sun50i_fmt.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * Copyright (C) Jernej Skrabec ++ */ ++ ++#ifndef _SUN50I_FMT_H_ ++#define _SUN50I_FMT_H_ ++ ++#include "sun8i_mixer.h" ++ ++#define SUN50I_FMT_DE3 0xa8000 ++ ++#define SUN50I_FMT_CTRL(base) ((base) + 0x00) ++#define SUN50I_FMT_SIZE(base) ((base) + 0x04) ++#define SUN50I_FMT_SWAP(base) ((base) + 0x08) ++#define SUN50I_FMT_DEPTH(base) ((base) + 0x0c) ++#define SUN50I_FMT_FORMAT(base) ((base) + 0x10) ++#define SUN50I_FMT_COEF(base) ((base) + 0x14) ++#define SUN50I_FMT_LMT_Y(base) ((base) + 0x20) ++#define SUN50I_FMT_LMT_C0(base) ((base) + 0x24) ++#define SUN50I_FMT_LMT_C1(base) ((base) + 0x28) ++ ++#define SUN50I_FMT_LIMIT(low, high) (((high) << 16) | (low)) ++ ++#define SUN50I_FMT_CS_YUV444RGB 0 ++#define SUN50I_FMT_CS_YUV422 1 ++#define SUN50I_FMT_CS_YUV420 2 ++ ++void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, ++ u16 height, u32 format); ++ ++#endif +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Implement-AFBC-support.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Implement-AFBC-support.patch new file mode 100644 index 000000000..e4d21564c --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-Implement-AFBC-support.patch @@ -0,0 +1,569 @@ +From 0788787d1240dba85ecbbdb559cb46d413975656 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:50 +1300 +Subject: drm: sun4i: de3: Implement AFBC support + +Buffers, compressed with AFBC, are supported by the DE3 and above, and +are generally more efficient for memory transfers. Add support for them. + +Currently it's implemented only for VI layers, but vendor code and +documentation suggest UI layers can have them too. However, I haven't +observed any SoC with such feature. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/Makefile | 2 +- + drivers/gpu/drm/sun4i/sun50i_afbc.c | 250 +++++++++++++++++++++++++ + drivers/gpu/drm/sun4i/sun50i_afbc.h | 87 +++++++++ + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 84 +++++++-- + 4 files changed, 409 insertions(+), 14 deletions(-) + create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.c + create mode 100644 drivers/gpu/drm/sun4i/sun50i_afbc.h + +diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile +index 3f516329f51e..78290f1660fb 100644 +--- a/drivers/gpu/drm/sun4i/Makefile ++++ b/drivers/gpu/drm/sun4i/Makefile +@@ -17,7 +17,7 @@ sun8i-drm-hdmi-y += sun8i_hdmi_phy_clk.o + sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \ + sun8i_vi_layer.o sun8i_ui_scaler.o \ + sun8i_vi_scaler.o sun8i_csc.o \ +- sun50i_fmt.o ++ sun50i_fmt.o sun50i_afbc.o + + sun4i-tcon-y += sun4i_crtc.o + sun4i-tcon-y += sun4i_tcon_dclk.o +diff --git a/drivers/gpu/drm/sun4i/sun50i_afbc.c b/drivers/gpu/drm/sun4i/sun50i_afbc.c +new file mode 100644 +index 000000000000..b55e1c553371 +--- /dev/null ++++ b/drivers/gpu/drm/sun4i/sun50i_afbc.c +@@ -0,0 +1,250 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (C) Jernej Skrabec ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sun50i_afbc.h" ++#include "sun8i_mixer.h" ++ ++static u32 sun50i_afbc_get_base(struct sun8i_mixer *mixer, unsigned int channel) ++{ ++ u32 base = sun8i_channel_base(mixer, channel); ++ ++ if (mixer->cfg->de_type == sun8i_mixer_de3) ++ return base + SUN50I_AFBC_CH_OFFSET; ++ ++ return base + 0x4000; ++} ++ ++bool sun50i_afbc_format_mod_supported(struct sun8i_mixer *mixer, ++ u32 format, u64 modifier) ++{ ++ u64 mode; ++ ++ if (modifier == DRM_FORMAT_MOD_INVALID) ++ return false; ++ ++ if (modifier == DRM_FORMAT_MOD_LINEAR) { ++ if (format == DRM_FORMAT_YUV420_8BIT || ++ format == DRM_FORMAT_YUV420_10BIT || ++ format == DRM_FORMAT_Y210) ++ return false; ++ return true; ++ } ++ ++ if (mixer->cfg->de_type == sun8i_mixer_de2) ++ return false; ++ ++ mode = AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_SPARSE | ++ AFBC_FORMAT_MOD_SPLIT; ++ ++ switch (format) { ++ case DRM_FORMAT_RGBA8888: ++ case DRM_FORMAT_RGB888: ++ case DRM_FORMAT_RGB565: ++ case DRM_FORMAT_RGBA4444: ++ case DRM_FORMAT_RGBA5551: ++ case DRM_FORMAT_RGBA1010102: ++ mode |= AFBC_FORMAT_MOD_YTR; ++ break; ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_Y210: ++ case DRM_FORMAT_YUV420_8BIT: ++ case DRM_FORMAT_YUV420_10BIT: ++ break; ++ default: ++ return false; ++ } ++ ++ return modifier == DRM_FORMAT_MOD_ARM_AFBC(mode); ++} ++ ++void sun50i_afbc_atomic_update(struct sun8i_mixer *mixer, unsigned int channel, ++ struct drm_plane *plane) ++{ ++ struct drm_plane_state *state = plane->state; ++ struct drm_framebuffer *fb = state->fb; ++ const struct drm_format_info *format = fb->format; ++ struct drm_gem_dma_object *gem; ++ u32 base, val, src_w, src_h; ++ u32 def_color0, def_color1; ++ struct regmap *regs; ++ dma_addr_t dma_addr; ++ ++ base = sun50i_afbc_get_base(mixer, channel); ++ regs = mixer->engine.regs; ++ ++ src_w = drm_rect_width(&state->src) >> 16; ++ src_h = drm_rect_height(&state->src) >> 16; ++ ++ val = SUN50I_FBD_SIZE_HEIGHT(src_h); ++ val |= SUN50I_FBD_SIZE_WIDTH(src_w); ++ regmap_write(regs, SUN50I_FBD_SIZE(base), val); ++ ++ val = SUN50I_FBD_BLK_SIZE_HEIGHT(DIV_ROUND_UP(src_h, 16)); ++ val = SUN50I_FBD_BLK_SIZE_WIDTH(DIV_ROUND_UP(src_w, 16)); ++ regmap_write(regs, SUN50I_FBD_BLK_SIZE(base), val); ++ ++ val = SUN50I_FBD_SRC_CROP_TOP(0); ++ val |= SUN50I_FBD_SRC_CROP_LEFT(0); ++ regmap_write(regs, SUN50I_FBD_SRC_CROP(base), val); ++ ++ val = SUN50I_FBD_LAY_CROP_TOP(state->src.y1 >> 16); ++ val |= SUN50I_FBD_LAY_CROP_LEFT(state->src.x1 >> 16); ++ regmap_write(regs, SUN50I_FBD_LAY_CROP(base), val); ++ ++ /* ++ * Default color is always set to white, in colorspace and bitness ++ * that coresponds to used format. If it is actually used or not ++ * depends on AFBC buffer. At least in Cedrus it can be turned on ++ * or off. ++ * NOTE: G and B channels are off by 1 (up). It's unclear if this ++ * is because HW need such value or it is due to good enough code ++ * in vendor driver and HW clips the value anyway. ++ */ ++ def_color0 = 0; ++ def_color1 = 0; ++ ++ val = 0; ++ switch (format->format) { ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_YUV420_10BIT: ++ val |= SUN50I_FBD_FMT_SBS1(2); ++ val |= SUN50I_FBD_FMT_SBS0(1); ++ break; ++ case DRM_FORMAT_Y210: ++ val |= SUN50I_FBD_FMT_SBS1(3); ++ val |= SUN50I_FBD_FMT_SBS0(2); ++ break; ++ default: ++ val |= SUN50I_FBD_FMT_SBS1(1); ++ val |= SUN50I_FBD_FMT_SBS0(1); ++ break; ++ } ++ switch (format->format) { ++ case DRM_FORMAT_RGBA8888: ++ val |= SUN50I_FBD_FMT_YUV_TRAN; ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA_8888); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(255) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(255); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(256) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(256); ++ break; ++ case DRM_FORMAT_RGB888: ++ val |= SUN50I_FBD_FMT_YUV_TRAN; ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGB_888); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(255); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(256) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(256); ++ break; ++ case DRM_FORMAT_RGB565: ++ val |= SUN50I_FBD_FMT_YUV_TRAN; ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGB_565); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(31); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(64) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(32); ++ break; ++ case DRM_FORMAT_RGBA4444: ++ val |= SUN50I_FBD_FMT_YUV_TRAN; ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA_4444); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(15) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(15); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(16) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(16); ++ break; ++ case DRM_FORMAT_RGBA5551: ++ val |= SUN50I_FBD_FMT_YUV_TRAN; ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA_5551); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(1) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(31); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(32) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(32); ++ break; ++ case DRM_FORMAT_RGBA1010102: ++ val |= SUN50I_FBD_FMT_YUV_TRAN; ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_RGBA1010102); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(3) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(1023); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(1024) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(1024); ++ break; ++ case DRM_FORMAT_YUV420_8BIT: ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_YUV420); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(255); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(128) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(128); ++ break; ++ case DRM_FORMAT_YUYV: ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_YUV422); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(255); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(128) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(128); ++ break; ++ case DRM_FORMAT_YUV420_10BIT: ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_P010); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(1023); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(512) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(512); ++ break; ++ case DRM_FORMAT_Y210: ++ val |= SUN50I_FBD_FMT_IN_FMT(SUN50I_AFBC_P210); ++ def_color0 = SUN50I_FBD_DEFAULT_COLOR0_ALPHA(0) | ++ SUN50I_FBD_DEFAULT_COLOR0_YR(1023); ++ def_color1 = SUN50I_FBD_DEFAULT_COLOR1_UG(512) | ++ SUN50I_FBD_DEFAULT_COLOR1_VB(512); ++ break; ++ } ++ regmap_write(regs, SUN50I_FBD_FMT(base), val); ++ ++ /* Get the physical address of the buffer in memory */ ++ gem = drm_fb_dma_get_gem_obj(fb, 0); ++ ++ DRM_DEBUG_DRIVER("Using GEM @ %pad\n", &gem->dma_addr); ++ ++ /* Compute the start of the displayed memory */ ++ dma_addr = gem->dma_addr + fb->offsets[0]; ++ ++ regmap_write(regs, SUN50I_FBD_LADDR(base), lower_32_bits(dma_addr)); ++ regmap_write(regs, SUN50I_FBD_HADDR(base), upper_32_bits(dma_addr)); ++ ++ val = SUN50I_FBD_OVL_SIZE_HEIGHT(src_h); ++ val |= SUN50I_FBD_OVL_SIZE_WIDTH(src_w); ++ regmap_write(regs, SUN50I_FBD_OVL_SIZE(base), val); ++ ++ val = SUN50I_FBD_OVL_COOR_Y(0); ++ val |= SUN50I_FBD_OVL_COOR_X(0); ++ regmap_write(regs, SUN50I_FBD_OVL_COOR(base), val); ++ ++ regmap_write(regs, SUN50I_FBD_OVL_BG_COLOR(base), ++ SUN8I_MIXER_BLEND_COLOR_BLACK); ++ regmap_write(regs, SUN50I_FBD_DEFAULT_COLOR0(base), def_color0); ++ regmap_write(regs, SUN50I_FBD_DEFAULT_COLOR1(base), def_color1); ++ ++ val = SUN50I_FBD_CTL_GLB_ALPHA(state->alpha >> 16); ++ val |= SUN50I_FBD_CTL_CLK_GATE; ++ val |= (state->alpha == DRM_BLEND_ALPHA_OPAQUE) ? ++ SUN50I_FBD_CTL_ALPHA_MODE_PIXEL : ++ SUN50I_FBD_CTL_ALPHA_MODE_COMBINED; ++ val |= SUN50I_FBD_CTL_FBD_EN; ++ regmap_write(regs, SUN50I_FBD_CTL(base), val); ++} ++ ++void sun50i_afbc_disable(struct sun8i_mixer *mixer, unsigned int channel) ++{ ++ u32 base = sun50i_afbc_get_base(mixer, channel); ++ ++ regmap_write(mixer->engine.regs, SUN50I_FBD_CTL(base), 0); ++} +diff --git a/drivers/gpu/drm/sun4i/sun50i_afbc.h b/drivers/gpu/drm/sun4i/sun50i_afbc.h +new file mode 100644 +index 000000000000..cea685c86855 +--- /dev/null ++++ b/drivers/gpu/drm/sun4i/sun50i_afbc.h +@@ -0,0 +1,87 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * Copyright (C) Jernej Skrabec ++ */ ++ ++#ifndef _SUN50I_AFBC_H_ ++#define _SUN50I_AFBC_H_ ++ ++#include ++ ++#define SUN50I_AFBC_CH_OFFSET 0x300 ++ ++#define SUN50I_AFBC_RGBA_8888 0x02 ++#define SUN50I_AFBC_RGB_888 0x08 ++#define SUN50I_AFBC_RGB_565 0x0a ++#define SUN50I_AFBC_RGBA_4444 0x0e ++#define SUN50I_AFBC_RGBA_5551 0x12 ++#define SUN50I_AFBC_RGBA1010102 0x16 ++#define SUN50I_AFBC_YUV422 0x26 ++#define SUN50I_AFBC_YUV420 0x2a ++#define SUN50I_AFBC_P010 0x30 ++#define SUN50I_AFBC_P210 0x32 ++ ++#define SUN50I_FBD_CTL(base) ((base) + 0x00) ++#define SUN50I_FBD_CTL_GLB_ALPHA(v) ((v) << 24) ++#define SUN50I_FBD_CTL_CLK_GATE BIT(4) ++#define SUN50I_FBD_CTL_ALPHA_MODE_PIXEL ((0) << 2) ++#define SUN50I_FBD_CTL_ALPHA_MODE_LAYER ((1) << 2) ++#define SUN50I_FBD_CTL_ALPHA_MODE_COMBINED ((2) << 2) ++#define SUN50I_FBD_CTL_FBD_FCEN BIT(1) ++#define SUN50I_FBD_CTL_FBD_EN BIT(0) ++ ++#define SUN50I_FBD_SIZE(base) ((base) + 0x08) ++#define SUN50I_FBD_SIZE_HEIGHT(v) (((v) - 1) << 16) ++#define SUN50I_FBD_SIZE_WIDTH(v) (((v) - 1) << 0) ++ ++#define SUN50I_FBD_BLK_SIZE(base) ((base) + 0x0c) ++#define SUN50I_FBD_BLK_SIZE_HEIGHT(v) ((v) << 16) ++#define SUN50I_FBD_BLK_SIZE_WIDTH(v) ((v) << 0) ++ ++#define SUN50I_FBD_SRC_CROP(base) ((base) + 0x10) ++#define SUN50I_FBD_SRC_CROP_TOP(v) ((v) << 16) ++#define SUN50I_FBD_SRC_CROP_LEFT(v) ((v) << 0) ++ ++#define SUN50I_FBD_LAY_CROP(base) ((base) + 0x14) ++#define SUN50I_FBD_LAY_CROP_TOP(v) ((v) << 16) ++#define SUN50I_FBD_LAY_CROP_LEFT(v) ((v) << 0) ++ ++#define SUN50I_FBD_FMT(base) ((base) + 0x18) ++#define SUN50I_FBD_FMT_SBS1(v) ((v) << 18) ++#define SUN50I_FBD_FMT_SBS0(v) ((v) << 16) ++#define SUN50I_FBD_FMT_YUV_TRAN BIT(7) ++#define SUN50I_FBD_FMT_IN_FMT(v) ((v) << 0) ++ ++#define SUN50I_FBD_LADDR(base) ((base) + 0x20) ++#define SUN50I_FBD_HADDR(base) ((base) + 0x24) ++ ++#define SUN50I_FBD_OVL_SIZE(base) ((base) + 0x30) ++#define SUN50I_FBD_OVL_SIZE_HEIGHT(v) (((v) - 1) << 16) ++#define SUN50I_FBD_OVL_SIZE_WIDTH(v) (((v) - 1) << 0) ++ ++#define SUN50I_FBD_OVL_COOR(base) ((base) + 0x34) ++#define SUN50I_FBD_OVL_COOR_Y(v) ((v) << 16) ++#define SUN50I_FBD_OVL_COOR_X(v) ((v) << 0) ++ ++#define SUN50I_FBD_OVL_BG_COLOR(base) ((base) + 0x38) ++#define SUN50I_FBD_OVL_FILL_COLOR(base) ((base) + 0x3c) ++ ++#define SUN50I_FBD_DEFAULT_COLOR0(base) ((base) + 0x50) ++#define SUN50I_FBD_DEFAULT_COLOR0_ALPHA(v) ((v) << 16) ++#define SUN50I_FBD_DEFAULT_COLOR0_YR(v) ((v) << 0) ++ ++#define SUN50I_FBD_DEFAULT_COLOR1(base) ((base) + 0x54) ++#define SUN50I_FBD_DEFAULT_COLOR1_VB(v) ((v) << 16) ++#define SUN50I_FBD_DEFAULT_COLOR1_UG(v) ((v) << 0) ++ ++struct sun8i_mixer; ++struct drm_plane; ++ ++bool sun50i_afbc_format_mod_supported(struct sun8i_mixer *mixer, ++ u32 format, u64 modifier); ++ ++void sun50i_afbc_atomic_update(struct sun8i_mixer *mixer, unsigned int channel, ++ struct drm_plane *plane); ++void sun50i_afbc_disable(struct sun8i_mixer *mixer, unsigned int channel); ++ ++#endif +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index d19349eecc9d..84f8917e2dd8 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -11,8 +11,10 @@ + #include + #include + #include ++#include + #include + ++#include "sun50i_afbc.h" + #include "sun8i_csc.h" + #include "sun8i_mixer.h" + #include "sun8i_vi_layer.h" +@@ -50,7 +52,7 @@ static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel, + + static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane, +- unsigned int zpos) ++ unsigned int zpos, bool afbc) + { + struct drm_plane_state *state = plane->state; + const struct drm_format_info *format = state->fb->format; +@@ -135,7 +137,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + + required = src_h * 100 / dst_h; + +- if (ability < required) { ++ if (!afbc && ability < required) { + DRM_DEBUG_DRIVER("Using vertical coarse scaling\n"); + vm = src_h; + vn = (u32)ability * dst_h / 100; +@@ -145,7 +147,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + /* it seems that every RGB scaler has buffer for 2048 pixels */ + scanline = subsampled ? mixer->cfg->scanline_yuv : 2048; + +- if (src_w > scanline) { ++ if (!afbc && src_w > scanline) { + DRM_DEBUG_DRIVER("Using horizontal coarse scaling\n"); + hm = src_w; + hn = scanline; +@@ -308,6 +310,15 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel, + return 0; + } + ++static void sun8i_vi_layer_prepare_non_linear(struct sun8i_mixer *mixer, ++ int channel, int overlay) ++{ ++ u32 base = sun8i_channel_base(mixer, channel); ++ ++ regmap_write(mixer->engine.regs, ++ SUN8I_MIXER_CHAN_VI_LAYER_ATTR(base, overlay), 0); ++} ++ + static int sun8i_vi_layer_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) + { +@@ -348,18 +359,45 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, + struct sun8i_layer *layer = plane_to_sun8i_layer(plane); + unsigned int zpos = new_state->normalized_zpos; + struct sun8i_mixer *mixer = layer->mixer; ++ struct drm_framebuffer *fb = plane->state->fb; ++ bool afbc = drm_is_afbc(fb->modifier); + +- if (!new_state->crtc || !new_state->visible) ++ if (!new_state->crtc || !new_state->visible) { ++ if (mixer->cfg->de_type >= sun8i_mixer_de3) ++ sun50i_afbc_disable(mixer, layer->channel); + return; ++ } + + sun8i_vi_layer_update_coord(mixer, layer->channel, +- layer->overlay, plane, zpos); +- sun8i_vi_layer_update_alpha(mixer, layer->channel, +- layer->overlay, plane); +- sun8i_vi_layer_update_formats(mixer, layer->channel, +- layer->overlay, plane); +- sun8i_vi_layer_update_buffer(mixer, layer->channel, +- layer->overlay, plane); ++ layer->overlay, plane, zpos, afbc); ++ ++ if (afbc) { ++ u32 fmt_type; ++ ++ sun8i_vi_layer_prepare_non_linear(mixer, layer->channel, ++ layer->overlay); ++ sun50i_afbc_atomic_update(mixer, layer->channel, plane); ++ ++ fmt_type = sun8i_vi_layer_get_format_type(fb->format); ++ sun8i_csc_set_ccsc(mixer, layer->channel, fmt_type, ++ plane->state->color_encoding, ++ plane->state->color_range); ++ } else { ++ sun8i_vi_layer_update_alpha(mixer, layer->channel, ++ layer->overlay, plane); ++ sun8i_vi_layer_update_formats(mixer, layer->channel, ++ layer->overlay, plane); ++ sun8i_vi_layer_update_buffer(mixer, layer->channel, ++ layer->overlay, plane); ++ } ++} ++ ++static bool sun8i_vi_layer_format_mod_supported(struct drm_plane *plane, ++ u32 format, u64 modifier) ++{ ++ struct sun8i_layer *layer = plane_to_sun8i_layer(plane); ++ ++ return sun50i_afbc_format_mod_supported(layer->mixer, format, modifier); + } + + static const struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = { +@@ -374,6 +412,7 @@ static const struct drm_plane_funcs sun8i_vi_layer_funcs = { + .disable_plane = drm_atomic_helper_disable_plane, + .reset = drm_atomic_helper_plane_reset, + .update_plane = drm_atomic_helper_update_plane, ++ .format_mod_supported = sun8i_vi_layer_format_mod_supported, + }; + + /* +@@ -457,6 +496,11 @@ static const u32 sun8i_vi_layer_de3_formats[] = { + DRM_FORMAT_YVU411, + DRM_FORMAT_YVU420, + DRM_FORMAT_YVU422, ++ ++ /* AFBC only formats */ ++ DRM_FORMAT_YUV420_8BIT, ++ DRM_FORMAT_YUV420_10BIT, ++ DRM_FORMAT_Y210, + }; + + static const uint64_t sun8i_layer_modifiers[] = { +@@ -464,6 +508,18 @@ static const uint64_t sun8i_layer_modifiers[] = { + DRM_FORMAT_MOD_INVALID + }; + ++static const uint64_t sun50i_layer_de3_modifiers[] = { ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_SPARSE | ++ AFBC_FORMAT_MOD_SPLIT), ++ DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | ++ AFBC_FORMAT_MOD_YTR | ++ AFBC_FORMAT_MOD_SPARSE | ++ AFBC_FORMAT_MOD_SPLIT), ++ DRM_FORMAT_MOD_LINEAR, ++ DRM_FORMAT_MOD_INVALID ++}; ++ + struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + struct sun8i_mixer *mixer, + int index) +@@ -472,6 +528,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + u32 supported_encodings, supported_ranges; + unsigned int plane_cnt, format_count; + struct sun8i_layer *layer; ++ const uint64_t *modifiers; + const u32 *formats; + int ret; + +@@ -487,9 +544,11 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + if (mixer->cfg->de_type >= sun8i_mixer_de3) { + formats = sun8i_vi_layer_de3_formats; + format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); ++ modifiers = sun50i_layer_de3_modifiers; + } else { + formats = sun8i_vi_layer_formats; + format_count = ARRAY_SIZE(sun8i_vi_layer_formats); ++ modifiers = sun8i_layer_modifiers; + } + + if (!mixer->cfg->ui_num && index == 0) +@@ -499,8 +558,7 @@ struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + ret = drm_universal_plane_init(drm, &layer->plane, 0, + &sun8i_vi_layer_funcs, + formats, format_count, +- sun8i_layer_modifiers, +- type, NULL); ++ modifiers, type, NULL); + if (ret) { + dev_err(drm->dev, "Couldn't initialize layer\n"); + return ERR_PTR(ret); +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-DE3-mixer.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-DE3-mixer.patch new file mode 100644 index 000000000..8a814bcaf --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-DE3-mixer.patch @@ -0,0 +1,126 @@ +From 3b6462ebad249f4762acfd8e262442bb0cda95b4 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:40 +1300 +Subject: drm: sun4i: de3: add YUV support to the DE3 mixer + +The mixer in the DE3 display engine supports YUV 8 and 10 bit +formats in addition to 8-bit RGB. Add the required register +configuration and format enumeration callback functions to the mixer, +and store the in-use output format (defaulting to RGB) and color +encoding in engine variables. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 53 ++++++++++++++++++++++++++-- + drivers/gpu/drm/sun4i/sunxi_engine.h | 5 +++ + 2 files changed, 55 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 252827715de1..a50c583852ed 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -23,7 +23,10 @@ + #include + #include + ++#include ++ + #include "sun4i_drv.h" ++#include "sun50i_fmt.h" + #include "sun8i_mixer.h" + #include "sun8i_ui_layer.h" + #include "sun8i_vi_layer.h" +@@ -390,12 +393,52 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine, + + DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", + interlaced ? "on" : "off"); ++ ++ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24) ++ val = SUN8I_MIXER_BLEND_COLOR_BLACK; ++ else ++ val = 0xff108080; ++ ++ regmap_write(mixer->engine.regs, ++ SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val); ++ regmap_write(mixer->engine.regs, ++ SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val); ++ ++ if (mixer->cfg->has_formatter) ++ sun50i_fmt_setup(mixer, mode->hdisplay, ++ mode->vdisplay, mixer->engine.format); ++} ++ ++static u32 *sun8i_mixer_get_supported_fmts(struct sunxi_engine *engine, u32 *num) ++{ ++ struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); ++ u32 *formats, count; ++ ++ count = 0; ++ ++ formats = kcalloc(5, sizeof(*formats), GFP_KERNEL); ++ if (!formats) ++ return NULL; ++ ++ if (mixer->cfg->has_formatter) { ++ formats[count++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; ++ formats[count++] = MEDIA_BUS_FMT_YUV8_1X24; ++ formats[count++] = MEDIA_BUS_FMT_UYVY8_1X16; ++ formats[count++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; ++ } ++ ++ formats[count++] = MEDIA_BUS_FMT_RGB888_1X24; ++ ++ *num = count; ++ ++ return formats; + } + + static const struct sunxi_engine_ops sun8i_engine_ops = { +- .commit = sun8i_mixer_commit, +- .layers_init = sun8i_layers_init, +- .mode_set = sun8i_mixer_mode_set, ++ .commit = sun8i_mixer_commit, ++ .layers_init = sun8i_layers_init, ++ .mode_set = sun8i_mixer_mode_set, ++ .get_supported_fmts = sun8i_mixer_get_supported_fmts, + }; + + static const struct regmap_config sun8i_mixer_regmap_config = { +@@ -456,6 +499,10 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, + dev_set_drvdata(dev, mixer); + mixer->engine.ops = &sun8i_engine_ops; + mixer->engine.node = dev->of_node; ++ /* default output format, supported by all mixers */ ++ mixer->engine.format = MEDIA_BUS_FMT_RGB888_1X24; ++ /* default color encoding, ignored with RGB I/O */ ++ mixer->engine.encoding = DRM_COLOR_YCBCR_BT601; + + if (of_property_present(dev->of_node, "iommus")) { + /* +diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h +index c48cbc1aceb8..ffafc29b3a0c 100644 +--- a/drivers/gpu/drm/sun4i/sunxi_engine.h ++++ b/drivers/gpu/drm/sun4i/sunxi_engine.h +@@ -6,6 +6,8 @@ + #ifndef _SUNXI_ENGINE_H_ + #define _SUNXI_ENGINE_H_ + ++#include ++ + struct drm_plane; + struct drm_crtc; + struct drm_device; +@@ -151,6 +153,9 @@ struct sunxi_engine { + + int id; + ++ u32 format; ++ enum drm_color_encoding encoding; ++ + /* Engine list management */ + struct list_head list; + }; +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-TCON.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-TCON.patch new file mode 100644 index 000000000..5fb39d4f0 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-TCON.patch @@ -0,0 +1,83 @@ +From ff794822d56721795fec59dea66164cc19ba792c Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:43 +1300 +Subject: drm: sun4i: de3: add YUV support to the TCON + +Account for U/V channel subsampling by reducing the dot clock and +resolution with a divider in the DE3 timing controller if a YUV format +is selected. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun4i_tcon.c | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c +index 3675c87461e9..af67bf2e6e09 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c +@@ -649,14 +649,26 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, + static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, + const struct drm_display_mode *mode) + { +- unsigned int bp, hsync, vsync, vtotal; ++ unsigned int bp, hsync, vsync, vtotal, div; ++ struct sun4i_crtc *scrtc = tcon->crtc; ++ struct sunxi_engine *engine = scrtc->engine; + u8 clk_delay; + u32 val; + + WARN_ON(!tcon->quirks->has_channel_1); + ++ switch (engine->format) { ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ div = 2; ++ break; ++ default: ++ div = 1; ++ break; ++ } ++ + /* Configure the dot clock */ +- clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); ++ clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000 / div); + + /* Adjust clock delay */ + clk_delay = sun4i_tcon_get_clk_delay(mode, 1); +@@ -675,17 +687,17 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, + + /* Set the input resolution */ + regmap_write(tcon->regs, SUN4I_TCON1_BASIC0_REG, +- SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay) | ++ SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay / div) | + SUN4I_TCON1_BASIC0_Y(mode->crtc_vdisplay)); + + /* Set the upscaling resolution */ + regmap_write(tcon->regs, SUN4I_TCON1_BASIC1_REG, +- SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay) | ++ SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay / div) | + SUN4I_TCON1_BASIC1_Y(mode->crtc_vdisplay)); + + /* Set the output resolution */ + regmap_write(tcon->regs, SUN4I_TCON1_BASIC2_REG, +- SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay) | ++ SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay / div) | + SUN4I_TCON1_BASIC2_Y(mode->crtc_vdisplay)); + + /* Set horizontal display timings */ +@@ -693,8 +705,8 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, + DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n", + mode->htotal, bp); + regmap_write(tcon->regs, SUN4I_TCON1_BASIC3_REG, +- SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal) | +- SUN4I_TCON1_BASIC3_H_BACKPORCH(bp)); ++ SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal / div) | ++ SUN4I_TCON1_BASIC3_H_BACKPORCH(bp / div)); + + bp = mode->crtc_vtotal - mode->crtc_vsync_start; + DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n", +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-color-space-correction-mod.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-color-space-correction-mod.patch new file mode 100644 index 000000000..68774b67b --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-YUV-support-to-the-color-space-correction-mod.patch @@ -0,0 +1,225 @@ +From a23ed976ee720c2445791716d975f040ef576c2b Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:42 +1300 +Subject: drm: sun4i: de3: add YUV support to the color space correction module + +Add coefficients and support for YUV formats to the display engine +colorspace and dynamic range correction submodule. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 164 +++++++++++++++++++++++++++++- + 1 file changed, 162 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index 8a336ccb27d3..e12a81fa9108 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -5,6 +5,8 @@ + + #include + ++#include ++ + #include "sun8i_csc.h" + #include "sun8i_mixer.h" + +@@ -107,6 +109,135 @@ static const u32 yuv2rgb_de3[2][3][12] = { + }, + }; + ++/* always convert to limited mode */ ++static const u32 rgb2yuv_de3[3][12] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ 0x0000837A, 0x0001021D, 0x00003221, 0x00000040, ++ 0xFFFFB41C, 0xFFFF6B03, 0x0000E0E1, 0x00000200, ++ 0x0000E0E1, 0xFFFF43B1, 0xFFFFDB6E, 0x00000200, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ 0x00005D7C, 0x00013A7C, 0x00001FBF, 0x00000040, ++ 0xFFFFCC78, 0xFFFF52A7, 0x0000E0E1, 0x00000200, ++ 0x0000E0E1, 0xFFFF33BE, 0xFFFFEB61, 0x00000200, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ 0x00007384, 0x00012A21, 0x00001A13, 0x00000040, ++ 0xFFFFC133, 0xFFFF5DEC, 0x0000E0E1, 0x00000200, ++ 0x0000E0E1, 0xFFFF3135, 0xFFFFEDEA, 0x00000200, ++ }, ++}; ++ ++/* always convert to limited mode */ ++static const u32 yuv2yuv_de3[2][3][3][12] = { ++ [DRM_COLOR_YCBCR_LIMITED_RANGE] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ 0x00020000, 0x00000000, 0x00000000, 0x00000000, ++ 0x00000000, 0x00020000, 0x00000000, 0x00000000, ++ 0x00000000, 0x00000000, 0x00020000, 0x00000000, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ 0x00020000, 0xFFFFC4D7, 0xFFFF9589, 0xFFC00040, ++ 0x00000000, 0x0002098B, 0x00003AAF, 0xFE000200, ++ 0x00000000, 0x0000266D, 0x00020CF8, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ 0x00020000, 0xFFFFBFCE, 0xFFFFC5FF, 0xFFC00040, ++ 0x00000000, 0x00020521, 0x00001F89, 0xFE000200, ++ 0x00000000, 0x00002C87, 0x00020F07, 0xFE000200, ++ }, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ 0x00020000, 0x000032D9, 0x00006226, 0xFFC00040, ++ 0x00000000, 0x0001FACE, 0xFFFFC759, 0xFE000200, ++ 0x00000000, 0xFFFFDAE7, 0x0001F780, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ 0x00020000, 0x00000000, 0x00000000, 0x00000000, ++ 0x00000000, 0x00020000, 0x00000000, 0x00000000, ++ 0x00000000, 0x00000000, 0x00020000, 0x00000000, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ 0x00020000, 0xFFFFF782, 0x00003036, 0xFFC00040, ++ 0x00000000, 0x0001FD99, 0xFFFFE5CA, 0xFE000200, ++ 0x00000000, 0x000005E4, 0x0002015A, 0xFE000200, ++ }, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ 0x00020000, 0x00003B03, 0x000034D2, 0xFFC00040, ++ 0x00000000, 0x0001FD8C, 0xFFFFE183, 0xFE000200, ++ 0x00000000, 0xFFFFD4F3, 0x0001F3FA, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ 0x00020000, 0x00000916, 0xFFFFD061, 0xFFC00040, ++ 0x00000000, 0x0002021C, 0x00001A40, 0xFE000200, ++ 0x00000000, 0xFFFFFA19, 0x0001FE5A, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ 0x00020000, 0x00000000, 0x00000000, 0x00000000, ++ 0x00000000, 0x00020000, 0x00000000, 0x00000000, ++ 0x00000000, 0x00000000, 0x00020000, 0x00000000, ++ }, ++ }, ++ }, ++ [DRM_COLOR_YCBCR_FULL_RANGE] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040, ++ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200, ++ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ 0x0001B7B8, 0xFFFFCC08, 0xFFFFA27B, 0x00000040, ++ 0x00000000, 0x0001CA24, 0x0000338D, 0xFE000200, ++ 0x00000000, 0x000021C1, 0x0001CD26, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ 0x0001B7B8, 0xFFFFC79C, 0xFFFFCD0C, 0x00000040, ++ 0x00000000, 0x0001C643, 0x00001BB4, 0xFE000200, ++ 0x00000000, 0x0000271D, 0x0001CEF5, 0xFE000200, ++ }, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ 0x0001B7B8, 0x00002CAB, 0x00005638, 0x00000040, ++ 0x00000000, 0x0001BD32, 0xFFFFCE3C, 0xFE000200, ++ 0x00000000, 0xFFFFDF6A, 0x0001BA4A, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040, ++ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200, ++ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ 0x0001B7B8, 0xFFFFF88A, 0x00002A5A, 0x00000040, ++ 0x00000000, 0x0001BFA5, 0xFFFFE8FA, 0xFE000200, ++ 0x00000000, 0x0000052D, 0x0001C2F1, 0xFE000200, ++ }, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ [DRM_COLOR_YCBCR_BT601] = { ++ 0x0001B7B8, 0x000033D6, 0x00002E66, 0x00000040, ++ 0x00000000, 0x0001BF9A, 0xFFFFE538, 0xFE000200, ++ 0x00000000, 0xFFFFDA2F, 0x0001B732, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT709] = { ++ 0x0001B7B8, 0x000007FB, 0xFFFFD62B, 0x00000040, ++ 0x00000000, 0x0001C39D, 0x0000170F, 0xFE000200, ++ 0x00000000, 0xFFFFFAD1, 0x0001C04F, 0xFE000200, ++ }, ++ [DRM_COLOR_YCBCR_BT2020] = { ++ 0x0001B7B8, 0x00000000, 0x00000000, 0x00000040, ++ 0x00000000, 0x0001C1C2, 0x00000000, 0xFE000200, ++ 0x00000000, 0x00000000, 0x0001C1C2, 0xFE000200, ++ }, ++ }, ++ }, ++}; ++ + static void sun8i_csc_setup(struct regmap *map, u32 base, + enum format_type fmt_type, + enum drm_color_encoding encoding, +@@ -148,12 +279,27 @@ static void sun8i_csc_setup(struct regmap *map, u32 base, + regmap_write(map, SUN8I_CSC_CTRL(base), val); + } + ++static const u32 *sun8i_csc_get_de3_yuv_table(enum drm_color_encoding in_enc, ++ enum drm_color_range in_range, ++ u32 out_format, ++ enum drm_color_encoding out_enc) ++{ ++ if (out_format == MEDIA_BUS_FMT_RGB888_1X24) ++ return yuv2rgb_de3[in_range][in_enc]; ++ ++ /* check for identity transformation */ ++ if (in_range == DRM_COLOR_YCBCR_LIMITED_RANGE && out_enc == in_enc) ++ return NULL; ++ ++ return yuv2yuv_de3[in_range][in_enc][out_enc]; ++} ++ + static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, + enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) + { +- u32 addr, val, mask; ++ u32 addr, val = 0, mask; + struct regmap *map; + const u32 *table; + int i; +@@ -164,14 +310,28 @@ static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, + + switch (fmt_type) { + case FORMAT_TYPE_RGB: +- val = 0; ++ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24) ++ break; ++ val = mask; ++ addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); ++ regmap_bulk_write(map, addr, rgb2yuv_de3[engine->encoding], 12); + break; + case FORMAT_TYPE_YUV: ++ table = sun8i_csc_get_de3_yuv_table(encoding, range, ++ engine->format, ++ engine->encoding); ++ if (!table) ++ break; + val = mask; + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); + regmap_bulk_write(map, addr, table, 12); + break; + case FORMAT_TYPE_YVU: ++ table = sun8i_csc_get_de3_yuv_table(encoding, range, ++ engine->format, ++ engine->encoding); ++ if (!table) ++ table = yuv2yuv_de3[range][encoding][encoding]; + val = mask; + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-format-enumeration-function-to-engine.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-format-enumeration-function-to-engine.patch new file mode 100644 index 000000000..581242c38 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-format-enumeration-function-to-engine.patch @@ -0,0 +1,63 @@ +From 99d327853acbc5d6c6d4140f004f82fcd5c40ea1 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:38 +1300 +Subject: drm: sun4i: de3: add format enumeration function to engine + +The DE3 display engine supports YUV formats in addition to RGB. + +Add an optional format enumeration function to the engine. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sunxi_engine.h | 29 ++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h +index ec0c4932f15c..c48cbc1aceb8 100644 +--- a/drivers/gpu/drm/sun4i/sunxi_engine.h ++++ b/drivers/gpu/drm/sun4i/sunxi_engine.h +@@ -123,6 +123,17 @@ struct sunxi_engine_ops { + */ + void (*mode_set)(struct sunxi_engine *engine, + const struct drm_display_mode *mode); ++ ++ /** ++ * @get_supported_fmts ++ * ++ * This callback is used to enumerate all supported output ++ * formats by the engine. They are used for bridge format ++ * negotiation. ++ * ++ * This function is optional. ++ */ ++ u32 *(*get_supported_fmts)(struct sunxi_engine *engine, u32 *num); + }; + + /** +@@ -215,4 +226,22 @@ sunxi_engine_mode_set(struct sunxi_engine *engine, + if (engine->ops && engine->ops->mode_set) + engine->ops->mode_set(engine, mode); + } ++ ++/** ++ * sunxi_engine_get_supported_formats - Provide array of supported formats ++ * @engine: pointer to the engine ++ * @num: pointer to variable, which will hold number of formats ++ * ++ * This list can be used for format negotiation by bridge. ++ */ ++static inline u32 * ++sunxi_engine_get_supported_formats(struct sunxi_engine *engine, u32 *num) ++{ ++ if (engine->ops && engine->ops->get_supported_fmts) ++ return engine->ops->get_supported_fmts(engine, num); ++ ++ *num = 0; ++ ++ return NULL; ++} + #endif /* _SUNXI_ENGINE_H_ */ +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-formatter-flag-to-mixer-config.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-formatter-flag-to-mixer-config.patch new file mode 100644 index 000000000..90f86befd --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-add-formatter-flag-to-mixer-config.patch @@ -0,0 +1,53 @@ +From f9a39553dcf5e87eba968d2aac4f5acf52baa392 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:39 +1300 +Subject: drm: sun4i: de3: add formatter flag to mixer config + +Only the DE3 (and newer) display engines have a formatter module. This +could be inferred from the is_de3 flag alone, however this will not +scale with addition of future DE versions in subsequent patches. + +Add a separate flag to signal this in the mixer configuration. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 1 + + drivers/gpu/drm/sun4i/sun8i_mixer.h | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index bd0fe2c6624e..252827715de1 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -717,6 +717,7 @@ static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = { + static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = { + .ccsc = CCSC_MIXER0_LAYOUT, + .is_de3 = true, ++ .has_formatter = 1, + .mod_rate = 600000000, + .scaler_mask = 0xf, + .scanline_yuv = 4096, +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h +index d7898c9c9cc0..8417b8fef2e1 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h +@@ -163,6 +163,7 @@ enum { + * @mod_rate: module clock rate that needs to be set in order to have + * a functional block. + * @is_de3: true, if this is next gen display engine 3.0, false otherwise. ++ * @has_formatter: true, if mixer has formatter core, for 10-bit and YUV handling + * @scaline_yuv: size of a scanline for VI scaler for YUV formats. + */ + struct sun8i_mixer_cfg { +@@ -172,6 +173,7 @@ struct sun8i_mixer_cfg { + int ccsc; + unsigned long mod_rate; + unsigned int is_de3 : 1; ++ unsigned int has_formatter : 1; + unsigned int scanline_yuv; + }; + +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-pass-engine-reference-to-ccsc-setup-function.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-pass-engine-reference-to-ccsc-setup-function.patch new file mode 100644 index 000000000..41bd02377 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de3-pass-engine-reference-to-ccsc-setup-function.patch @@ -0,0 +1,54 @@ +From 2d7c88fc2af6d07ccadc99b157753638b4940293 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:41 +1300 +Subject: drm: sun4i: de3: pass engine reference to ccsc setup function + +Configuration of the DE3 colorspace and dynamic range correction module +requires knowledge of the current video format and encoding. + +Pass the display engine by reference to the csc setup function, rather +than the register map alone, to allow access to this information. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index 68d955c63b05..8a336ccb27d3 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -148,17 +148,19 @@ static void sun8i_csc_setup(struct regmap *map, u32 base, + regmap_write(map, SUN8I_CSC_CTRL(base), val); + } + +-static void sun8i_de3_ccsc_setup(struct regmap *map, int layer, ++static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, + enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) + { + u32 addr, val, mask; ++ struct regmap *map; + const u32 *table; + int i; + + mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); + table = yuv2rgb_de3[range][encoding]; ++ map = engine->regs; + + switch (fmt_type) { + case FORMAT_TYPE_RGB: +@@ -204,7 +206,7 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, + u32 base; + + if (mixer->cfg->is_de3) { +- sun8i_de3_ccsc_setup(mixer->engine.regs, layer, ++ sun8i_de3_ccsc_setup(&mixer->engine, layer, + fmt_type, encoding, range); + return; + } +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-csc-add-Display-Engine-3.3-DE33-support.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-csc-add-Display-Engine-3.3-DE33-support.patch new file mode 100644 index 000000000..3479d96ff --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-csc-add-Display-Engine-3.3-DE33-support.patch @@ -0,0 +1,156 @@ +From 0d003a88bcacf5f405f3922b0c56b7eecdb68386 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:58 +1300 +Subject: drm: sun4i: de33: csc: add Display Engine 3.3 (DE33) support + +Like earlier DE versions, the DE33 has a CSC (Color Space Correction) +module. which provides color space conversion between BT2020/BT709, and +dynamic range conversion between SDR/ST2084/HLG. + +Add support for the DE33. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 96 +++++++++++++++++++++++++++++++ + drivers/gpu/drm/sun4i/sun8i_csc.h | 3 + + 2 files changed, 99 insertions(+) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index 2d5a2cf7cba2..45bd1ca06400 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -238,6 +238,14 @@ static const u32 yuv2yuv_de3[2][3][3][12] = { + }, + }; + ++static u32 sun8i_csc_base(struct sun8i_mixer *mixer, int layer) ++{ ++ if (mixer->cfg->de_type == sun8i_mixer_de33) ++ return sun8i_channel_base(mixer, layer) - 0x800; ++ else ++ return ccsc_base[mixer->cfg->ccsc][layer]; ++} ++ + static void sun8i_csc_setup(struct regmap *map, u32 base, + enum format_type fmt_type, + enum drm_color_encoding encoding, +@@ -358,6 +366,90 @@ static void sun8i_de3_ccsc_setup(struct sunxi_engine *engine, int layer, + mask, val); + } + ++/* extract constant from high word and invert sign if necessary */ ++static u32 sun8i_de33_ccsc_get_constant(u32 value) ++{ ++ value >>= 16; ++ ++ if (value & BIT(15)) ++ return 0x400 - (value & 0x3ff); ++ ++ return value; ++} ++ ++static void sun8i_de33_convert_table(const u32 *src, u32 *dst) ++{ ++ dst[0] = sun8i_de33_ccsc_get_constant(src[3]); ++ dst[1] = sun8i_de33_ccsc_get_constant(src[7]); ++ dst[2] = sun8i_de33_ccsc_get_constant(src[11]); ++ memcpy(&dst[3], src, sizeof(u32) * 12); ++ dst[6] &= 0xffff; ++ dst[10] &= 0xffff; ++ dst[14] &= 0xffff; ++} ++ ++static void sun8i_de33_ccsc_setup(struct sun8i_mixer *mixer, int layer, ++ enum format_type fmt_type, ++ enum drm_color_encoding encoding, ++ enum drm_color_range range) ++{ ++ u32 addr, val = 0, base, csc[15]; ++ struct sunxi_engine *engine; ++ struct regmap *map; ++ const u32 *table; ++ int i; ++ ++ table = yuv2rgb_de3[range][encoding]; ++ base = sun8i_csc_base(mixer, layer); ++ engine = &mixer->engine; ++ map = engine->regs; ++ ++ switch (fmt_type) { ++ case FORMAT_TYPE_RGB: ++ if (engine->format == MEDIA_BUS_FMT_RGB888_1X24) ++ break; ++ val = SUN8I_CSC_CTRL_EN; ++ sun8i_de33_convert_table(rgb2yuv_de3[engine->encoding], csc); ++ regmap_bulk_write(map, SUN50I_CSC_COEFF(base, 0), csc, 15); ++ break; ++ case FORMAT_TYPE_YUV: ++ table = sun8i_csc_get_de3_yuv_table(encoding, range, ++ engine->format, ++ engine->encoding); ++ if (!table) ++ break; ++ val = SUN8I_CSC_CTRL_EN; ++ sun8i_de33_convert_table(table, csc); ++ regmap_bulk_write(map, SUN50I_CSC_COEFF(base, 0), csc, 15); ++ break; ++ case FORMAT_TYPE_YVU: ++ table = sun8i_csc_get_de3_yuv_table(encoding, range, ++ engine->format, ++ engine->encoding); ++ if (!table) ++ table = yuv2yuv_de3[range][encoding][encoding]; ++ val = SUN8I_CSC_CTRL_EN; ++ sun8i_de33_convert_table(table, csc); ++ for (i = 0; i < 15; i++) { ++ addr = SUN50I_CSC_COEFF(base, i); ++ if (i > 3) { ++ if (((i - 3) & 3) == 1) ++ addr = SUN50I_CSC_COEFF(base, i + 1); ++ else if (((i - 3) & 3) == 2) ++ addr = SUN50I_CSC_COEFF(base, i - 1); ++ } ++ regmap_write(map, addr, csc[i]); ++ } ++ break; ++ default: ++ val = 0; ++ DRM_WARN("Wrong CSC mode specified.\n"); ++ return; ++ } ++ ++ regmap_write(map, SUN8I_CSC_CTRL(base), val); ++} ++ + void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, + enum format_type fmt_type, + enum drm_color_encoding encoding, +@@ -369,6 +461,10 @@ void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, + sun8i_de3_ccsc_setup(&mixer->engine, layer, + fmt_type, encoding, range); + return; ++ } else if (mixer->cfg->de_type == sun8i_mixer_de33) { ++ sun8i_de33_ccsc_setup(mixer, layer, fmt_type, ++ encoding, range); ++ return; + } + + if (layer < mixer->cfg->vi_num) { +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h +index b7546e06e315..2b762cb79f02 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.h ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.h +@@ -20,6 +20,9 @@ struct sun8i_mixer; + #define SUN8I_CSC_CTRL(base) ((base) + 0x0) + #define SUN8I_CSC_COEFF(base, i) ((base) + 0x10 + 4 * (i)) + ++#define SUN50I_CSC_COEFF(base, i) ((base) + 0x04 + 4 * (i)) ++#define SUN50I_CSC_ALPHA(base) ((base) + 0x40) ++ + #define SUN8I_CSC_CTRL_EN BIT(0) + + enum format_type { +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-fmt-add-Display-Engine-3.3-DE33-support.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-fmt-add-Display-Engine-3.3-DE33-support.patch new file mode 100644 index 000000000..cd060b367 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-fmt-add-Display-Engine-3.3-DE33-support.patch @@ -0,0 +1,75 @@ +From 792b816c952bcf5dbf7c3ac7d90937bc71f0a7cd Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:57 +1300 +Subject: drm: sun4i: de33: fmt: add Display Engine 3.3 (DE33) support + +Like the DE3, the DE33 has a FMT (formatter) module, which +provides YUV444 to YUV422/YUV420 conversion, format re-mapping and color +depth conversion, although the DE33 module appears significantly more +capable, including up to 4K video support. + +Add support for the DE33. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun50i_fmt.c | 21 +++++++++++++++++++-- + drivers/gpu/drm/sun4i/sun50i_fmt.h | 1 + + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.c b/drivers/gpu/drm/sun4i/sun50i_fmt.c +index 050a8716ae86..39682d4e6d20 100644 +--- a/drivers/gpu/drm/sun4i/sun50i_fmt.c ++++ b/drivers/gpu/drm/sun4i/sun50i_fmt.c +@@ -51,6 +51,19 @@ static void sun50i_fmt_de3_limits(u32 *limits, u32 colorspace, bool bit10) + } + } + ++static void sun50i_fmt_de33_limits(u32 *limits, u32 colorspace) ++{ ++ if (colorspace == SUN50I_FMT_CS_YUV444RGB) { ++ limits[0] = SUN50I_FMT_LIMIT(0, 4095); ++ limits[1] = SUN50I_FMT_LIMIT(0, 4095); ++ limits[2] = SUN50I_FMT_LIMIT(0, 4095); ++ } else { ++ limits[0] = SUN50I_FMT_LIMIT(256, 3840); ++ limits[1] = SUN50I_FMT_LIMIT(256, 3840); ++ limits[2] = SUN50I_FMT_LIMIT(256, 3840); ++ } ++} ++ + void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, + u16 height, u32 format) + { +@@ -60,10 +73,14 @@ void sun50i_fmt_setup(struct sun8i_mixer *mixer, u16 width, + + colorspace = sun50i_fmt_get_colorspace(format); + bit10 = sun50i_fmt_is_10bit(format); +- base = SUN50I_FMT_DE3; ++ base = mixer->cfg->de_type == sun8i_mixer_de3 ? ++ SUN50I_FMT_DE3 : SUN50I_FMT_DE33; + regs = sun8i_blender_regmap(mixer); + +- sun50i_fmt_de3_limits(limit, colorspace, bit10); ++ if (mixer->cfg->de_type == sun8i_mixer_de3) ++ sun50i_fmt_de3_limits(limit, colorspace, bit10); ++ else ++ sun50i_fmt_de33_limits(limit, colorspace); + + regmap_write(regs, SUN50I_FMT_CTRL(base), 0); + +diff --git a/drivers/gpu/drm/sun4i/sun50i_fmt.h b/drivers/gpu/drm/sun4i/sun50i_fmt.h +index 4127f7206aad..3e60d5c788b3 100644 +--- a/drivers/gpu/drm/sun4i/sun50i_fmt.h ++++ b/drivers/gpu/drm/sun4i/sun50i_fmt.h +@@ -9,6 +9,7 @@ + #include "sun8i_mixer.h" + + #define SUN50I_FMT_DE3 0xa8000 ++#define SUN50I_FMT_DE33 0x5000 + + #define SUN50I_FMT_CTRL(base) ((base) + 0x00) + #define SUN50I_FMT_SIZE(base) ((base) + 0x04) +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-mixer-add-Display-Engine-3.3-DE33-support.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-mixer-add-Display-Engine-3.3-DE33-support.patch new file mode 100644 index 000000000..84e9458fb --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-mixer-add-Display-Engine-3.3-DE33-support.patch @@ -0,0 +1,302 @@ +From 66c111f3315d2c34c2f9bfb39de61bf3ec46a5f6 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:55 +1300 +Subject: drm: sun4i: de33: mixer: add Display Engine 3.3 (DE33) support + +The DE33 is a newer version of the Allwinner Display Engine IP block, +found in the H616, H618, H700 and T507 SoCs. DE2 and DE3 are already +supported by the mainline driver. + +Notable features (from the H616 datasheet and implemented): +- 4096 x 2048 (4K) output support +- AFBC ARM Frame Buffer Compression support +- YUV420 input support + +The DE2 and DE3 engines have a blender register range within the +mixer engine register map, whereas the DE33 separates this out into +a separate display group, and adds a top register map. + +Extend the mixer to support the DE33. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 109 ++++++++++++++++++++++++---- + drivers/gpu/drm/sun4i/sun8i_mixer.h | 16 +++- + 2 files changed, 108 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 600084286b39..204fc8055b32 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -321,8 +321,12 @@ static void sun8i_mixer_commit(struct sunxi_engine *engine, + regmap_write(bld_regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base), + pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); + +- regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF, +- SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); ++ if (mixer->cfg->de_type == sun8i_mixer_de33) ++ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_DBUFF, ++ SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); ++ else ++ regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF, ++ SUN8I_MIXER_GLOBAL_DBUFF_ENABLE); + } + + static struct drm_plane **sun8i_layers_init(struct drm_device *drm, +@@ -371,25 +375,33 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine, + const struct drm_display_mode *mode) + { + struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); ++ struct regmap *bld_regs, *disp_regs; + u32 bld_base, size, val; + bool interlaced; + + bld_base = sun8i_blender_base(mixer); ++ bld_regs = sun8i_blender_regmap(mixer); + interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); + size = SUN8I_MIXER_SIZE(mode->hdisplay, mode->vdisplay); + + DRM_DEBUG_DRIVER("Updating global size W: %u H: %u\n", + mode->hdisplay, mode->vdisplay); + +- regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_SIZE, size); +- regmap_write(engine->regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size); ++ if (mixer->cfg->de_type == sun8i_mixer_de33) { ++ disp_regs = mixer->disp_regs; ++ regmap_write(mixer->top_regs, SUN50I_MIXER_GLOBAL_SIZE, size); ++ } else { ++ disp_regs = mixer->engine.regs; ++ regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, size); ++ } ++ regmap_write(bld_regs, SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size); + + if (interlaced) + val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED; + else + val = 0; + +- regmap_update_bits(engine->regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base), ++ regmap_update_bits(bld_regs, SUN8I_MIXER_BLEND_OUTCTL(bld_base), + SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, val); + + DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", +@@ -400,10 +412,8 @@ static void sun8i_mixer_mode_set(struct sunxi_engine *engine, + else + val = 0xff108080; + +- regmap_write(mixer->engine.regs, +- SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val); +- regmap_write(mixer->engine.regs, +- SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val); ++ regmap_write(disp_regs, SUN8I_MIXER_BLEND_BKCOLOR(bld_base), val); ++ regmap_write(disp_regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(bld_base, 0), val); + + if (mixer->cfg->has_formatter) + sun50i_fmt_setup(mixer, mode->hdisplay, +@@ -443,12 +453,29 @@ static const struct sunxi_engine_ops sun8i_engine_ops = { + }; + + static const struct regmap_config sun8i_mixer_regmap_config = { ++ .name = "layers", + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0xffffc, /* guessed */ + }; + ++static const struct regmap_config sun8i_top_regmap_config = { ++ .name = "top", ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x3c, ++}; ++ ++static const struct regmap_config sun8i_disp_regmap_config = { ++ .name = "display", ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x20000, ++}; ++ + static int sun8i_mixer_of_get_id(struct device_node *node) + { + struct device_node *ep, *remote; +@@ -471,33 +498,45 @@ static int sun8i_mixer_of_get_id(struct device_node *node) + + static void sun8i_mixer_init(struct sun8i_mixer *mixer) + { ++ struct regmap *top_regs, *disp_regs; + unsigned int base = sun8i_blender_base(mixer); + int plane_cnt, i; + ++ if (mixer->cfg->de_type == sun8i_mixer_de33) { ++ top_regs = mixer->top_regs; ++ disp_regs = mixer->disp_regs; ++ } else { ++ top_regs = mixer->engine.regs; ++ disp_regs = mixer->engine.regs; ++ } ++ + /* Enable the mixer */ +- regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_CTL, ++ regmap_write(top_regs, SUN8I_MIXER_GLOBAL_CTL, + SUN8I_MIXER_GLOBAL_CTL_RT_EN); + ++ if (mixer->cfg->de_type == sun8i_mixer_de33) ++ regmap_write(top_regs, SUN50I_MIXER_GLOBAL_CLK, 1); ++ + /* Set background color to black */ +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_BKCOLOR(base), ++ regmap_write(disp_regs, SUN8I_MIXER_BLEND_BKCOLOR(base), + SUN8I_MIXER_BLEND_COLOR_BLACK); + + /* + * Set fill color of bottom plane to black. Generally not needed + * except when VI plane is at bottom (zpos = 0) and enabled. + */ +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), ++ regmap_write(disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), + SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0)); +- regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), ++ regmap_write(disp_regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(base, 0), + SUN8I_MIXER_BLEND_COLOR_BLACK); + + plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; + for (i = 0; i < plane_cnt; i++) +- regmap_write(mixer->engine.regs, ++ regmap_write(disp_regs, + SUN8I_MIXER_BLEND_MODE(base, i), + SUN8I_MIXER_BLEND_MODE_DEF); + +- regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), ++ regmap_update_bits(disp_regs, SUN8I_MIXER_BLEND_PIPE_CTL(base), + SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0); + } + +@@ -573,6 +612,30 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, + return PTR_ERR(mixer->engine.regs); + } + ++ if (mixer->cfg->de_type == sun8i_mixer_de33) { ++ regs = devm_platform_ioremap_resource(pdev, 1); ++ if (IS_ERR(regs)) ++ return PTR_ERR(regs); ++ ++ mixer->top_regs = devm_regmap_init_mmio(dev, regs, ++ &sun8i_top_regmap_config); ++ if (IS_ERR(mixer->top_regs)) { ++ dev_err(dev, "Couldn't create the top regmap\n"); ++ return PTR_ERR(mixer->top_regs); ++ } ++ ++ regs = devm_platform_ioremap_resource(pdev, 2); ++ if (IS_ERR(regs)) ++ return PTR_ERR(regs); ++ ++ mixer->disp_regs = devm_regmap_init_mmio(dev, regs, ++ &sun8i_disp_regmap_config); ++ if (IS_ERR(mixer->disp_regs)) { ++ dev_err(dev, "Couldn't create the disp regmap\n"); ++ return PTR_ERR(mixer->disp_regs); ++ } ++ } ++ + mixer->reset = devm_reset_control_get(dev, NULL); + if (IS_ERR(mixer->reset)) { + dev_err(dev, "Couldn't get our reset line\n"); +@@ -787,6 +850,18 @@ static const struct sun8i_mixer_cfg sun50i_h6_mixer0_cfg = { + .vi_num = 1, + }; + ++static const struct sun8i_mixer_cfg sun50i_h616_mixer0_cfg = { ++ .ccsc = CCSC_MIXER0_LAYOUT, ++ .de_type = sun8i_mixer_de33, ++ .has_formatter = 1, ++ .mod_rate = 600000000, ++ .scaler_mask = 0xf, ++ .scanline_yuv = 4096, ++ .ui_num = 3, ++ .vi_num = 1, ++ .map = {0, 6, 7, 8}, ++}; ++ + static const struct of_device_id sun8i_mixer_of_table[] = { + { + .compatible = "allwinner,sun8i-a83t-de2-mixer-0", +@@ -832,6 +907,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = { + .compatible = "allwinner,sun50i-h6-de3-mixer-0", + .data = &sun50i_h6_mixer0_cfg, + }, ++ { ++ .compatible = "allwinner,sun50i-h616-de33-mixer-0", ++ .data = &sun50i_h616_mixer0_cfg, ++ }, + { } + }; + MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table); +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h +index 75facc7d1fa6..26b001164647 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h +@@ -21,6 +21,10 @@ + #define SUN8I_MIXER_GLOBAL_DBUFF 0x8 + #define SUN8I_MIXER_GLOBAL_SIZE 0xc + ++#define SUN50I_MIXER_GLOBAL_SIZE 0x8 ++#define SUN50I_MIXER_GLOBAL_CLK 0xc ++#define SUN50I_MIXER_GLOBAL_DBUFF 0x10 ++ + #define SUN8I_MIXER_GLOBAL_CTL_RT_EN BIT(0) + + #define SUN8I_MIXER_GLOBAL_DBUFF_ENABLE BIT(0) +@@ -154,6 +158,7 @@ enum { + enum sun8i_mixer_type { + sun8i_mixer_de2, + sun8i_mixer_de3, ++ sun8i_mixer_de33, + }; + + /** +@@ -180,6 +185,7 @@ struct sun8i_mixer_cfg { + unsigned int de_type; + unsigned int has_formatter : 1; + unsigned int scanline_yuv; ++ unsigned int map[6]; + }; + + struct sun8i_mixer { +@@ -191,6 +197,9 @@ struct sun8i_mixer { + + struct clk *bus_clk; + struct clk *mod_clk; ++ ++ struct regmap *top_regs; ++ struct regmap *disp_regs; + }; + + enum { +@@ -227,13 +236,16 @@ sun8i_blender_base(struct sun8i_mixer *mixer) + static inline struct regmap * + sun8i_blender_regmap(struct sun8i_mixer *mixer) + { +- return mixer->engine.regs; ++ return mixer->cfg->de_type == sun8i_mixer_de33 ? ++ mixer->disp_regs : mixer->engine.regs; + } + + static inline u32 + sun8i_channel_base(struct sun8i_mixer *mixer, int channel) + { +- if (mixer->cfg->de_type == sun8i_mixer_de3) ++ if (mixer->cfg->de_type == sun8i_mixer_de33) ++ return mixer->cfg->map[channel] * 0x20000 + DE2_CH_SIZE; ++ else if (mixer->cfg->de_type == sun8i_mixer_de3) + return DE3_CH_BASE + channel * DE3_CH_SIZE; + else + return DE2_CH_BASE + channel * DE2_CH_SIZE; +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-vi_scaler-add-Display-Engine-3.3-DE33-support.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-vi_scaler-add-Display-Engine-3.3-DE33-support.patch new file mode 100644 index 000000000..9028d40a3 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-de33-vi_scaler-add-Display-Engine-3.3-DE33-support.patch @@ -0,0 +1,77 @@ +From 412294545ec91452cc3eccff746a4243879b4cde Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:56 +1300 +Subject: drm: sun4i: de33: vi_scaler: add Display Engine 3.3 (DE33) support + +The vi_scaler appears to be used in preference to the ui_scaler module +for hardware video scaling in the DE33. + +Enable support for this scaler. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 19 +++++++++++++++---- + drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 7 ++++++- + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +index 7f1231cf0f01..180be9d67d9c 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +@@ -95,12 +95,23 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, + hscale = state->src_w / state->crtc_w; + vscale = state->src_h / state->crtc_h; + +- sun8i_ui_scaler_setup(mixer, channel, src_w, src_h, dst_w, +- dst_h, hscale, vscale, hphase, vphase); +- sun8i_ui_scaler_enable(mixer, channel, true); ++ if (mixer->cfg->de_type == sun8i_mixer_de33) { ++ sun8i_vi_scaler_setup(mixer, channel, src_w, src_h, ++ dst_w, dst_h, hscale, vscale, ++ hphase, vphase, ++ state->fb->format); ++ } else { ++ sun8i_ui_scaler_setup(mixer, channel, src_w, src_h, ++ dst_w, dst_h, hscale, vscale, ++ hphase, vphase); ++ sun8i_ui_scaler_enable(mixer, channel, true); ++ } + } else { + DRM_DEBUG_DRIVER("HW scaling is not needed\n"); +- sun8i_ui_scaler_enable(mixer, channel, false); ++ if (mixer->cfg->de_type == sun8i_mixer_de33) ++ sun8i_vi_scaler_disable(mixer, channel); ++ else ++ sun8i_ui_scaler_enable(mixer, channel, false); + } + + /* Set base coordinates */ +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +index e7242301b312..9c7f6e7d71d5 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +@@ -835,7 +835,9 @@ static const u32 bicubic4coefftab32[480] = { + + static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) + { +- if (mixer->cfg->de_type == sun8i_mixer_de3) ++ if (mixer->cfg->de_type == sun8i_mixer_de33) ++ return sun8i_channel_base(mixer, channel) + 0x3000; ++ else if (mixer->cfg->de_type == sun8i_mixer_de3) + return DE3_VI_SCALER_UNIT_BASE + + DE3_VI_SCALER_UNIT_SIZE * channel; + else +@@ -845,6 +847,9 @@ static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) + + static bool sun8i_vi_scaler_is_vi_plane(struct sun8i_mixer *mixer, int channel) + { ++ if (mixer->cfg->de_type == sun8i_mixer_de33) ++ return mixer->cfg->map[channel] < mixer->cfg->vi_num; ++ + return true; + } + +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-support-YUV-formats-in-VI-scaler.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-support-YUV-formats-in-VI-scaler.patch new file mode 100644 index 000000000..1aff0b4bc --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-support-YUV-formats-in-VI-scaler.patch @@ -0,0 +1,140 @@ +From e0de25f60a3535d345b33dcc541c814499151788 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:44 +1300 +Subject: drm: sun4i: support YUV formats in VI scaler + +Now that YUV formats are available, enable support in the VI scaler. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin + +Changelog v4..v5: +- Add commit description +--- + drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 85 +++++++++++++++++-------- + 1 file changed, 58 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +index 7ba75011adf9..2e49a6e5f1f1 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +@@ -843,6 +843,11 @@ static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) + DE2_VI_SCALER_UNIT_SIZE * channel; + } + ++static bool sun8i_vi_scaler_is_vi_plane(struct sun8i_mixer *mixer, int channel) ++{ ++ return true; ++} ++ + static int sun8i_vi_scaler_coef_index(unsigned int step) + { + unsigned int scale, int_part, float_part; +@@ -867,44 +872,65 @@ static int sun8i_vi_scaler_coef_index(unsigned int step) + } + } + +-static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base, +- u32 hstep, u32 vstep, +- const struct drm_format_info *format) ++static void sun8i_vi_scaler_set_coeff_vi(struct regmap *map, u32 base, ++ u32 hstep, u32 vstep, ++ const struct drm_format_info *format) + { + const u32 *ch_left, *ch_right, *cy; +- int offset, i; ++ int offset; + +- if (format->hsub == 1 && format->vsub == 1) { +- ch_left = lan3coefftab32_left; +- ch_right = lan3coefftab32_right; +- cy = lan2coefftab32; +- } else { ++ if (format->is_yuv) { + ch_left = bicubic8coefftab32_left; + ch_right = bicubic8coefftab32_right; + cy = bicubic4coefftab32; ++ } else { ++ ch_left = lan3coefftab32_left; ++ ch_right = lan3coefftab32_right; ++ cy = lan2coefftab32; + } + + offset = sun8i_vi_scaler_coef_index(hstep) * + SUN8I_VI_SCALER_COEFF_COUNT; +- for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) { +- regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, i), +- lan3coefftab32_left[offset + i]); +- regmap_write(map, SUN8I_SCALER_VSU_YHCOEFF1(base, i), +- lan3coefftab32_right[offset + i]); +- regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, i), +- ch_left[offset + i]); +- regmap_write(map, SUN8I_SCALER_VSU_CHCOEFF1(base, i), +- ch_right[offset + i]); +- } ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, 0), ++ &lan3coefftab32_left[offset], ++ SUN8I_VI_SCALER_COEFF_COUNT); ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_YHCOEFF1(base, 0), ++ &lan3coefftab32_right[offset], ++ SUN8I_VI_SCALER_COEFF_COUNT); ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, 0), ++ &ch_left[offset], SUN8I_VI_SCALER_COEFF_COUNT); ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_CHCOEFF1(base, 0), ++ &ch_right[offset], SUN8I_VI_SCALER_COEFF_COUNT); + + offset = sun8i_vi_scaler_coef_index(hstep) * + SUN8I_VI_SCALER_COEFF_COUNT; +- for (i = 0; i < SUN8I_VI_SCALER_COEFF_COUNT; i++) { +- regmap_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, i), +- lan2coefftab32[offset + i]); +- regmap_write(map, SUN8I_SCALER_VSU_CVCOEFF(base, i), +- cy[offset + i]); +- } ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, 0), ++ &lan2coefftab32[offset], SUN8I_VI_SCALER_COEFF_COUNT); ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_CVCOEFF(base, 0), ++ &cy[offset], SUN8I_VI_SCALER_COEFF_COUNT); ++} ++ ++static void sun8i_vi_scaler_set_coeff_ui(struct regmap *map, u32 base, ++ u32 hstep, u32 vstep, ++ const struct drm_format_info *format) ++{ ++ const u32 *table; ++ int offset; ++ ++ offset = sun8i_vi_scaler_coef_index(hstep) * ++ SUN8I_VI_SCALER_COEFF_COUNT; ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_YHCOEFF0(base, 0), ++ &lan2coefftab32[offset], SUN8I_VI_SCALER_COEFF_COUNT); ++ offset = sun8i_vi_scaler_coef_index(vstep) * ++ SUN8I_VI_SCALER_COEFF_COUNT; ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_YVCOEFF(base, 0), ++ &lan2coefftab32[offset], SUN8I_VI_SCALER_COEFF_COUNT); ++ ++ table = format->is_yuv ? bicubic4coefftab32 : lan2coefftab32; ++ offset = sun8i_vi_scaler_coef_index(hstep) * ++ SUN8I_VI_SCALER_COEFF_COUNT; ++ regmap_bulk_write(map, SUN8I_SCALER_VSU_CHCOEFF0(base, 0), ++ &table[offset], SUN8I_VI_SCALER_COEFF_COUNT); + } + + void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable) +@@ -994,6 +1020,11 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, + SUN8I_SCALER_VSU_CHPHASE(base), chphase); + regmap_write(mixer->engine.regs, + SUN8I_SCALER_VSU_CVPHASE(base), cvphase); +- sun8i_vi_scaler_set_coeff(mixer->engine.regs, base, +- hscale, vscale, format); ++ ++ if (sun8i_vi_scaler_is_vi_plane(mixer, layer)) ++ sun8i_vi_scaler_set_coeff_vi(mixer->engine.regs, base, ++ hscale, vscale, format); ++ else ++ sun8i_vi_scaler_set_coeff_ui(mixer->engine.regs, base, ++ hscale, vscale, format); + } +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-vi_scaler-refactor-vi_scaler-enablement.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-vi_scaler-refactor-vi_scaler-enablement.patch new file mode 100644 index 000000000..59a56dd02 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/drm-sun4i-vi_scaler-refactor-vi_scaler-enablement.patch @@ -0,0 +1,100 @@ +From 0c10a80b8e37d9a7fc57d8bf968c70419423065a Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 29 Sep 2024 22:04:47 +1300 +Subject: drm: sun4i: vi_scaler refactor vi_scaler enablement + +If the video scaler is required, then it is obligatory to set the +relevant register to enable it, so move this to the +sun8i_vi_scaler_setup() function. + +This simplifies the alternate case (scaler not required) so replace the +vi_scaler_enable() function with a vi_scaler_disable() function. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Ryan Walklin +--- + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 3 +-- + drivers/gpu/drm/sun4i/sun8i_vi_scaler.c | 21 +++++++++++---------- + drivers/gpu/drm/sun4i/sun8i_vi_scaler.h | 2 +- + 3 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 4647e9bcccaa..e348fd0a3d81 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -156,10 +156,9 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, + sun8i_vi_scaler_setup(mixer, channel, src_w, src_h, dst_w, + dst_h, hscale, vscale, hphase, vphase, + format); +- sun8i_vi_scaler_enable(mixer, channel, true); + } else { + DRM_DEBUG_DRIVER("HW scaling is not needed\n"); +- sun8i_vi_scaler_enable(mixer, channel, false); ++ sun8i_vi_scaler_disable(mixer, channel); + } + + regmap_write(mixer->engine.regs, +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +index aa346c3beb30..e7242301b312 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c +@@ -933,20 +933,13 @@ static void sun8i_vi_scaler_set_coeff_ui(struct regmap *map, u32 base, + &table[offset], SUN8I_VI_SCALER_COEFF_COUNT); + } + +-void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable) ++void sun8i_vi_scaler_disable(struct sun8i_mixer *mixer, int layer) + { +- u32 val, base; ++ u32 base; + + base = sun8i_vi_scaler_base(mixer, layer); + +- if (enable) +- val = SUN8I_SCALER_VSU_CTRL_EN | +- SUN8I_SCALER_VSU_CTRL_COEFF_RDY; +- else +- val = 0; +- +- regmap_write(mixer->engine.regs, +- SUN8I_SCALER_VSU_CTRL(base), val); ++ regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(base), 0); + } + + void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, +@@ -982,6 +975,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, + cvphase = vphase; + } + ++ regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(base), ++ SUN8I_SCALER_VSU_CTRL_EN); ++ + if (mixer->cfg->de_type >= sun8i_mixer_de3) { + u32 val; + +@@ -1027,4 +1023,9 @@ void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, + else + sun8i_vi_scaler_set_coeff_ui(mixer->engine.regs, base, + hscale, vscale, format); ++ ++ if (mixer->cfg->de_type <= sun8i_mixer_de3) ++ regmap_write(mixer->engine.regs, SUN8I_SCALER_VSU_CTRL(base), ++ SUN8I_SCALER_VSU_CTRL_EN | ++ SUN8I_SCALER_VSU_CTRL_COEFF_RDY); + } +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h +index 68f6593b369a..e801bc7a4189 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h +@@ -69,7 +69,7 @@ + #define SUN50I_SCALER_VSU_ANGLE_SHIFT(x) (((x) << 16) & 0xF) + #define SUN50I_SCALER_VSU_ANGLE_OFFSET(x) ((x) & 0xFF) + +-void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable); ++void sun8i_vi_scaler_disable(struct sun8i_mixer *mixer, int layer); + void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer, + u32 src_w, u32 src_h, u32 dst_w, u32 dst_h, + u32 hscale, u32 vscale, u32 hphase, u32 vphase, +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-bus-binding.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-bus-binding.patch new file mode 100644 index 000000000..86b0c0cb3 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-bus-binding.patch @@ -0,0 +1,35 @@ +From b8344d8eb9d000bc2984a5fcafc25b527f361b5b Mon Sep 17 00:00:00 2001 +From: Ryan Walklin +Date: Sun, 29 Sep 2024 22:04:51 +1300 +Subject: dt-bindings: allwinner: add H616 DE33 bus binding + +The Allwinner H616 and variants have a new display engine revision +(DE33). + +Add a display engine bus binding for the DE33. + +Signed-off-by: Ryan Walklin +Acked-by: Conor Dooley +Reviewed-by: Chen-Yu Tsai +--- + .../devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml +index 9845a187bdf6..ea7ee89158c6 100644 +--- a/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml ++++ b/Documentation/devicetree/bindings/bus/allwinner,sun50i-a64-de2.yaml +@@ -24,7 +24,9 @@ properties: + oneOf: + - const: allwinner,sun50i-a64-de2 + - items: +- - const: allwinner,sun50i-h6-de3 ++ - enum: ++ - allwinner,sun50i-h6-de3 ++ - allwinner,sun50i-h616-de33 + - const: allwinner,sun50i-a64-de2 + + reg: +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-clock-binding.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-clock-binding.patch new file mode 100644 index 000000000..65411eb51 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-clock-binding.patch @@ -0,0 +1,32 @@ +From 58a606c8136c57d23b4e35f0f50cb140f1d65d9b Mon Sep 17 00:00:00 2001 +From: Ryan Walklin +Date: Sun, 29 Sep 2024 22:04:52 +1300 +Subject: dt-bindings: allwinner: add H616 DE33 clock binding + +The Allwinner H616 and variants have a new display engine revision +(DE33). + +Add a clock binding for the DE33. + +Signed-off-by: Ryan Walklin +Acked-by: Conor Dooley +Reviewed-by: Chen-Yu Tsai +--- + .../devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml +index 70369bd633e4..7fcd55d468d4 100644 +--- a/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml ++++ b/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml +@@ -25,6 +25,7 @@ properties: + - const: allwinner,sun50i-a64-de2-clk + - const: allwinner,sun50i-h5-de2-clk + - const: allwinner,sun50i-h6-de3-clk ++ - const: allwinner,sun50i-h616-de33-clk + - items: + - const: allwinner,sun8i-r40-de2-clk + - const: allwinner,sun8i-h3-de2-clk +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-mixer-binding.patch b/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-mixer-binding.patch new file mode 100644 index 000000000..d3a92736c --- /dev/null +++ b/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-allwinner-add-H616-DE33-mixer-binding.patch @@ -0,0 +1,36 @@ +From 12d7983166ed867dd72c023af036b1397aec66ba Mon Sep 17 00:00:00 2001 +From: Ryan Walklin +Date: Sun, 29 Sep 2024 22:04:53 +1300 +Subject: dt-bindings: allwinner: add H616 DE33 mixer binding + +The Allwinner H616 and variants have a new display engine revision +(DE33). + +The mixer configuration registers are significantly different to the DE3 +and DE2 revisions, being split into separate top and display blocks, +therefore a fallback for the mixer compatible is not provided. + +Add a display engine mixer binding for the DE33. + +Signed-off-by: Ryan Walklin +Acked-by: Conor Dooley +Reviewed-by: Chen-Yu Tsai +--- + .../bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml +index b75c1ec686ad..c37eb8ae1b8e 100644 +--- a/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml ++++ b/Documentation/devicetree/bindings/display/allwinner,sun8i-a83t-de2-mixer.yaml +@@ -24,6 +24,7 @@ properties: + - allwinner,sun50i-a64-de2-mixer-0 + - allwinner,sun50i-a64-de2-mixer-1 + - allwinner,sun50i-h6-de3-mixer-0 ++ - allwinner,sun50i-h616-de33-mixer-0 + + reg: + maxItems: 1 +-- +2.35.3 + diff --git a/patch/kernel/archive/sunxi-6.16/patches.drm/dt-bindings-power-Add-Allwinner-H6-H616-PRCM-PPU.patch b/patch/kernel/archive/sunxi-6.16/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.16/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.16/patches.drm/pmdomain-sunxi-add-H6-PRCM-PPU-driver.patch b/patch/kernel/archive/sunxi-6.16/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.16/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.16/patches.megous/ASoC-rockchip-Fix-doubling-of-playback-speed-after-system-sleep.patch b/patch/kernel/archive/sunxi-6.16/patches.megous/ASoC-rockchip-Fix-doubling-of-playback-speed-after-system-sleep.patch deleted file mode 100644 index fc5b3bfa1..000000000 --- a/patch/kernel/archive/sunxi-6.16/patches.megous/ASoC-rockchip-Fix-doubling-of-playback-speed-after-system-sleep.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d7510ae26674448d46b308be4f2ddab88a087093 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 15 Aug 2022 02:23:37 +0200 -Subject: ASoC: rockchip: Fix doubling of playback speed after system sleep - -There is some issue with CRU on RK3399 that can be reproduced by: - -- playing some audio and stopping the playback (so that runtime PM suspends I2S) -- putting system to deep sleep and resuming it (using mainline TF-A) -- playing some audio (audio plays at 2x the normal speed) - -If the audio is kept playing during system sleep cycle, the issue -does not manifest. Relevant registers in CRU are identical in bug/ -no-bug scenarios, so this patch is just touching the CRU registers -without actually changing anything in the end. Touching the registers -fixes the playback speed, though. - -Inspired by: https://github.com/djselbeck/linux/commit/cb4be5dec3fa18c4b344c11fed3fc57aa3bea424 - -Signed-off-by: Ondrej Jirman ---- - sound/soc/rockchip/rockchip_i2s.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c -index 0a0a95b4f520..6dce1db85427 100644 ---- a/sound/soc/rockchip/rockchip_i2s.c -+++ b/sound/soc/rockchip/rockchip_i2s.c -@@ -114,6 +114,13 @@ static int i2s_runtime_resume(struct device *dev) - if (ret) - clk_disable_unprepare(i2s->mclk); - -+ if (ret == 0) { -+ unsigned long rate = clk_get_rate(i2s->mclk); -+ -+ clk_set_rate(i2s->mclk, rate - 1); -+ clk_set_rate(i2s->mclk, rate); -+ } -+ - return ret; - } - --- -2.51.0 - diff --git a/patch/kernel/archive/sunxi-6.16/patches.megous/Add-README.md-with-information-and-u-boot-patches.patch b/patch/kernel/archive/sunxi-6.16/patches.megous/Add-README.md-with-information-and-u-boot-patches.patch deleted file mode 100644 index 927da5a20..000000000 --- a/patch/kernel/archive/sunxi-6.16/patches.megous/Add-README.md-with-information-and-u-boot-patches.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 13de56c82a52f64f32089881b77152aefc01595d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= -Date: Tue, 22 Nov 2016 01:01:49 +0100 -Subject: Add README.md with information and u-boot patches - -Signed-off-by: Ondrej Jirman ---- - ...Fix-PLL1-setup-to-never-use-dividers.patch | 33 ++++ - README.md | 154 ++++++++++++++++++ - 2 files changed, 187 insertions(+) - create mode 100644 0001-sunxi-h3-Fix-PLL1-setup-to-never-use-dividers.patch - create mode 100644 README.md - -diff --git a/0001-sunxi-h3-Fix-PLL1-setup-to-never-use-dividers.patch b/0001-sunxi-h3-Fix-PLL1-setup-to-never-use-dividers.patch -new file mode 100644 -index 000000000000..2b892e805a2b ---- /dev/null -+++ b/0001-sunxi-h3-Fix-PLL1-setup-to-never-use-dividers.patch -@@ -0,0 +1,33 @@ -+From 7f5071f906f79bdc99d6b4b0ccf0cb280abe740b Mon Sep 17 00:00:00 2001 -+From: Ondrej Jirman -+Date: Tue, 20 Dec 2016 11:25:12 +0100 -+Subject: [PATCH] sunxi: h3: Fix PLL1 setup to never use dividers -+ -+Kernel would lower the divider on first CLK change and cause the -+lock up. -+--- -+ arch/arm/mach-sunxi/clock_sun6i.c | 7 +++---- -+ 1 file changed, 3 insertions(+), 4 deletions(-) -+ -+diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c -+index 50fb302a19..91aa2a0478 100644 -+--- a/arch/arm/mach-sunxi/clock_sun6i.c -++++ b/arch/arm/mach-sunxi/clock_sun6i.c -+@@ -94,11 +94,10 @@ void clock_set_pll1(unsigned int clk) -+ int k = 1; -+ int m = 1; -+ -+- if (clk > 1152000000) { -+- k = 2; -+- } else if (clk > 768000000) { -++ if (clk >= 1368000000) { -+ k = 3; -+- m = 2; -++ } else if (clk >= 768000000) { -++ k = 2; -+ } -+ -+ /* Switch to 24MHz clock while changing PLL1 */ -+-- -+2.11.0 -+ -diff --git a/README.md b/README.md -new file mode 100644 -index 000000000000..74c4c16416d3 ---- /dev/null -+++ b/README.md -@@ -0,0 +1,154 @@ -+Mainline linux kernel for Orange Pi PC/PC2/PC3/One, TBS A711, PinePhone (Pro), PocketBook Touch Lux 3 -+------------------------------------------------------------------------------------------------------ -+ -+This kernel tree is meant for: -+ -+- Orange Pi One -+- Orange Pi PC -+- Orange Pi PC 2 -+- Orange Pi 3 -+- PinePhone 1.0, 1.1 and 1.2(a/b) -+- TBS A711 Tablet -+- PocketBook Touch Lux 3 -+- Pinebook Pro -+- Pinephone Pro -+ -+Features in addition to mainline: -+ -+- [Orange Pi One/PC/PC2] More aggressive OPPs for CPU -+- [All] Mark one of DRM planes as a cursor plane, speeding up Xorg based desktop with modesetting driver -+- [Orange Pi One/PC/PC2] Configure on-board micro-switches to perform system power off function -+- [Orange Pi One/PC/PC2/3] HDMI audio -+- [Orange Pi 3] Ethernet -+- [TBS A711] HM5065 (back camera) / GC2145 (front camera) -+- [PinePhone] WiFi, Bluetooth, Audio, Modem power, HDMI out over USB-C, USB-C support, cameras, PMIC improvements, power management, fixes here and there -+- [PocketBook Touch Lux 3] Display and Touchscreen support -+- [Pinephone Pro] Everything -+ -+Pre-built u-boot and kernels are available at https://xff.cz/kernels/ -+ -+You may need some firmware files for some part of the functionality. Those are -+available at: https://megous.com/git/linux-firmware -+ -+If you want to reproduce my pre-built kernels exactly, you'll need to uncomment -+CONFIG_EXTRA_FIRMWARE_DIR and CONFIG_EXTRA_FIRMWARE in the defconfigs, and -+point CONFIG_EXTRA_FIRMWARE_DIR to a directory on your computer where the -+clone of https://megous.com/git/linux-firmware resides. -+ -+You can also leave those two config options commented out, and copy the contents -+of https://megous.com/git/linux-firmware to /lib/firmware/ on the target device. -+ -+You can use this kernel to run a desktop environment on Orange Pi SBCs, -+Arch Linux on your Pinephone, or to have a completely opensource OS on -+a Pocketbook e-ink book reader. -+ -+Have fun! -+ -+ -+Build instructions -+------------------ -+ -+These are rudimentary instructions and you need to understand what you're doing. -+These are just core steps required to build the ATF/u-boot/kernel. Downloading, -+verifying, renaming to correct directories is not described or mentioned. You -+should be able to infer missing necessary steps yourself for your particular needs. -+ -+Get necessary toolchains from: -+ -+- https://releases.linaro.org/components/toolchain/binaries/latest/aarch64-linux-gnu/ for 64bit Orange Pi PC2 and Orange Pi 3, PinePhone -+- https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/ for 32bit Orange Pis, Pocketbook, TBS tablet -+ -+Extract toolchains and prepare the environment: -+ -+ CWD=`pwd` -+ OUT=$CWD/builds -+ SRC=$CWD/u-boot -+ export PATH="$PATH:$CWD/Toolchains/arm/bin:$CWD/Toolchains/aarch64/bin" -+ -+For Orange Pi PC2, Orange Pi 3 or PinePhone: -+ -+ export CROSS_COMPILE=aarch64-linux-gnu- -+ export KBUILD_OUTPUT=$OUT/.tmp/uboot-pc2 -+ rm -rf "$KBUILD_OUTPUT" -+ mkdir -p $KBUILD_OUTPUT $OUT/pc2 -+ -+Get and build ATF from https://github.com/ARM-software/arm-trusted-firmware: -+ -+ make -C "$CWD/arm-trusted-firmware" PLAT=sun50i_a64 DEBUG=1 bl31 -+ cp "$CWD/arm-trusted-firmware/build/sun50i_a64/debug/bl31.bin" "$KBUILD_OUTPUT" -+ -+Use sun50i_a64 for Orange Pi PC2 or PinePhone and sun50i_h6 for Orange Pi 3. -+ -+Build u-boot from https://megous.com/git/u-boot/ (opi-v2020.04 branch) with appropriate -+defconfig (orangepi_one_defconfig, orangepi_pc2_defconfig, orangepi_pc_defconfig, orangepi_3_defconfig, tbs_a711_defconfig, pinephone_defconfig). -+ -+My u-boot branch already has all the necessary patches integrated and is configured for quick u-boot/kernel startup. -+ -+ make -C u-boot orangepi_pc2_defconfig -+ make -C u-boot -j5 -+ -+ cp $KBUILD_OUTPUT/.config $OUT/pc2/uboot.config -+ cat $KBUILD_OUTPUT/{spl/sunxi-spl.bin,u-boot.itb} > $OUT/pc2/uboot.bin -+ -+Get kernel from this repository and checkout the latest orange-pi-5.18 branch. -+ -+Build the kernel for 64-bit boards: -+ -+ export ARCH=arm64 -+ export CROSS_COMPILE=aarch64-linux-gnu- -+ export KBUILD_OUTPUT=$OUT/.tmp/linux-arm64 -+ mkdir -p $KBUILD_OUTPUT $OUT/pc2 -+ -+ make -C linux orangepi_defconfig -+ # or make -C linux pocketbook_touch_lux_3_defconfig -+ # or make -C linux tbs_a711_defconfig -+ make -C linux -j5 clean -+ make -C linux -j5 Image dtbs -+ -+ cp -f $KBUILD_OUTPUT/arch/arm64/boot/Image $OUT/pc2/ -+ cp -f $KBUILD_OUTPUT/.config $OUT/pc2/linux.config -+ cp -f $KBUILD_OUTPUT/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dtb $OUT/pc2/board.dtb -+ -+Build the kernel for 32-bit boards: -+ -+ export ARCH=arm -+ export CROSS_COMPILE=arm-linux-gnueabihf- -+ export KBUILD_OUTPUT=$OUT/.tmp/linux-arm -+ mkdir -p $KBUILD_OUTPUT $OUT/pc -+ -+ make orangepi_defconfig -+ # or make pinephone_defconfig -+ make -C linux orangepi_defconfig -+ make -C linux -j5 clean -+ make -C linux -j5 zImage dtbs -+ -+ cp -f $KBUILD_OUTPUT/arch/arm/boot/zImage $OUT/pc/ -+ cp -f $KBUILD_OUTPUT/.config $OUT/pc/linux.config -+ cp -f $KBUILD_OUTPUT/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dtb $OUT/pc/board.dtb -+ # Or use sun8i-h3-orangepi-one.dtb for Orange Pi One -+ -+ -+PinePhone -+--------- -+ -+I don't run u-boot on PinePhone, so my pre-built kernel packages don't come -+with u-boot built for PinePhone. -+ -+ -+Kernel lockup issues -+-------------------- -+ -+*If you're getting lockups on boot or later during thermal regulation, -+you're missing an u-boot patch.* -+ -+This patch is necessary to run this kernel! -+ -+These lockups are caused by improper NKMP clock factors selection -+in u-boot for PLL_CPUX. (M divider should not be used. P divider -+should be used only for frequencies below 240MHz.) -+ -+This patch for u-boot fixes it: -+ -+ 0001-sunxi-h3-Fix-PLL1-setup-to-never-use-dividers.patch -+ -+Kernel side is already fixed in this kernel tree. --- -2.51.0 - diff --git a/patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk3399-s-Add-DMC-table.patch b/patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk3399-s-Add-DMC-table.patch deleted file mode 100644 index 9a076d69b..000000000 --- a/patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk3399-s-Add-DMC-table.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e95ac8b6eaba41268ad0082de8b96b7a8ed5fb63 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 28 Nov 2024 11:16:31 +0100 -Subject: arm64: dts: rockchip: rk3399-s: Add DMC table - -This is used by Pinephone Pro. - -Signed-off-by: Ondrej Jirman ---- - arch/arm64/boot/dts/rockchip/rk3399-s.dtsi | 29 ++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-s.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-s.dtsi -index e54f451af9f3..82b941720294 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-s.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-s.dtsi -@@ -92,6 +92,31 @@ opp05 { - opp-microvolt = <1100000 1100000 1150000>; - }; - }; -+ -+ dmc_opp_table: opp-table-3 { -+ compatible = "operating-points-v2"; -+ -+ opp00 { -+ opp-hz = /bits/ 64 <328000000>; -+ opp-microvolt = <900000>; -+ }; -+ opp01 { -+ opp-hz = /bits/ 64 <416000000>; -+ opp-microvolt = <900000>; -+ }; -+ opp02 { -+ opp-hz = /bits/ 64 <666000000>; -+ opp-microvolt = <900000>; -+ }; -+ opp03 { -+ opp-hz = /bits/ 64 <856000000>; -+ opp-microvolt = <900000>; -+ }; -+ opp04 { -+ opp-hz = /bits/ 64 <928000000>; -+ opp-microvolt = <925000>; -+ }; -+ }; - }; - - &cpu_l0 { -@@ -118,6 +143,10 @@ &cpu_b1 { - operating-points-v2 = <&cluster1_opp>; - }; - -+&dmc { -+ operating-points-v2 = <&dmc_opp_table>; -+}; -+ - &gpu { - operating-points-v2 = <&gpu_opp_table>; - }; --- -2.51.0 - diff --git a/patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk356x-Fix-PCIe-register-map-and-ranges.patch b/patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk356x-Fix-PCIe-register-map-and-ranges.patch deleted file mode 100644 index 9843854b2..000000000 --- a/patch/kernel/archive/sunxi-6.16/patches.megous/arm64-dts-rockchip-rk356x-Fix-PCIe-register-map-and-ranges.patch +++ /dev/null @@ -1,47 +0,0 @@ -From fb9e2ab89fa45ece10369840291cb8ac2813c5d9 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 24 Sep 2022 21:59:07 +0200 -Subject: arm64: dts: rockchip: rk356x: Fix PCIe register map and ranges - -I have two Realtek PCIe wifi cards connected over the 4 port PCIe bridge -to Quartz64-A. The cards fail to work, when nvme SSD is connected at the -same time to the bridge. Without nvme connected, cards work fine. The -issue seems to be related to mixed use of devices which make use of I/O -ranges and memory ranges. - -This patch changes I/O, MEM and config mappings so that config and I/O -mappings use the 0xf4000000 outbound address space, and MEM range uses -the whole 0x300000000 outbound space. - -These values were suggested by pgwipeout: - - https://lore.kernel.org/lkml/875ygbsrf3.fsf@bloch.sibelius.xs4all.nl/T/#m84b5f6992cc26dffe0d3783c0d8c9c86e5e10c10 - -This is identical to how BSP does the mappings. - -This change to the regs/ranges makes the issue go away and both nvme and -wifi cards work when connected at the same time to the bridge. I tested -the nvme with large amount of reads/writes, both behind the PCIe bridge -and when directly connected to Quartz64-A board. - -Signed-off-by: Ondrej Jirman ---- - arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi -index fd2214b6fad4..53d7bd65f9e6 100644 ---- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi -@@ -966,7 +966,7 @@ pcie2x1: pcie@fe260000 { - <0 0 0 4 &pcie_intc 3>; - linux,pci-domain = <0>; - num-ib-windows = <6>; -- num-ob-windows = <2>; -+ num-ob-windows = <8>; - max-link-speed = <2>; - msi-map = <0x0 &its 0x0 0x1000>; - num-lanes = <1>; --- -2.51.0 - diff --git a/patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch b/patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch deleted file mode 100644 index f143a8377..000000000 --- a/patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ff22f72f419fe6c380163bdb2dea17d14124f209 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 24 Sep 2022 21:54:23 +0200 -Subject: drm: rockchip: Fix panic on reboot when DRM device fails to bind - -When DRM device is freed, we need to clear the drvdata pointer, because -it now points to invalid memory. - -Signed-off-by: Ondrej Jirman ---- - drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -index 180fad5d49ad..04e829553c14 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -@@ -206,6 +206,7 @@ static int rockchip_drm_bind(struct device *dev) - component_unbind_all(dev, drm_dev); - err_free: - drm_dev_put(drm_dev); -+ dev_set_drvdata(dev, NULL); - return ret; - } - -@@ -222,6 +223,7 @@ static void rockchip_drm_unbind(struct device *dev) - rockchip_iommu_cleanup(drm_dev); - - drm_dev_put(drm_dev); -+ dev_set_drvdata(dev, NULL); - } - - DEFINE_DRM_GEM_FOPS(rockchip_drm_driver_fops); --- -2.51.0 - diff --git a/patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-dw-mipi-dsi-rockchip-Fix-ISP1-PHY-initialization.patch b/patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-dw-mipi-dsi-rockchip-Fix-ISP1-PHY-initialization.patch deleted file mode 100644 index d46f5a8fa..000000000 --- a/patch/kernel/archive/sunxi-6.16/patches.megous/drm-rockchip-dw-mipi-dsi-rockchip-Fix-ISP1-PHY-initialization.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 9042a5cbaf6b0019b22424518c6972d33a3ae5f6 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 9 Jun 2024 14:30:12 +0200 -Subject: drm: rockchip: dw-mipi-dsi-rockchip: Fix ISP1 PHY initialization - -After suspend/resume cycle, ISP1 would stop receiving data. -Re-initializing DPHY during PHY power on fixes the issue. - -Signed-off-by: Ondrej Jirman ---- - drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c -index 3398160ad75e..471851879947 100644 ---- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c -+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c -@@ -1245,6 +1245,14 @@ static int dw_mipi_dsi_dphy_power_on(struct phy *phy) - goto err_phy_cfg_clk; - } - -+ if (dsi->cdata->dphy_rx_init) { -+ ret = dsi->cdata->dphy_rx_init(phy); -+ if (ret < 0) { -+ DRM_DEV_ERROR(dsi->dev, "hardware-specific phy init failed: %d\n", ret); -+ goto err_pwr_on; -+ } -+ } -+ - /* do soc-variant specific init */ - if (dsi->cdata->dphy_rx_power_on) { - ret = dsi->cdata->dphy_rx_power_on(phy); --- -2.51.0 - diff --git a/patch/kernel/archive/sunxi-6.16/patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch b/patch/kernel/archive/sunxi-6.16/patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch deleted file mode 100644 index 98409f32f..000000000 --- a/patch/kernel/archive/sunxi-6.16/patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 1138dde32ed97f554dbfb6ea2e0bc556518fe889 Mon Sep 17 00:00:00 2001 -From: Peter Geis -Date: Sat, 22 Jan 2022 20:35:39 +0000 -Subject: mmc: dw-mmc-rockchip: fix sdmmc after soft reboot - -During shutdown the dw-mmc driver shuts down the vqmmc regulator. -This leads to situations where the sdmmc is unavailable after a soft -reboot. -Fix this by ensuring the vqmmc regulator is powered up on kernel -shutdown. - -Signed-off-by: Peter Geis ---- - drivers/mmc/host/dw_mmc-rockchip.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c -index baa23b517731..42edf219623b 100644 ---- a/drivers/mmc/host/dw_mmc-rockchip.c -+++ b/drivers/mmc/host/dw_mmc-rockchip.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - - #include "dw_mmc.h" -@@ -575,9 +576,20 @@ static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = { - NULL) - }; - -+static void dw_mci_rockchip_shutdown(struct platform_device *pdev) -+{ -+ struct dw_mci *host = dev_get_drvdata(&pdev->dev); -+ struct mmc_host *mmc = host->slot->mmc; -+ -+ if (!IS_ERR(mmc->supply.vqmmc) && !(host->vqmmc_enabled)) -+ if(!regulator_enable(mmc->supply.vqmmc)) -+ host->vqmmc_enabled = true; -+} -+ - static struct platform_driver dw_mci_rockchip_pltfm_driver = { - .probe = dw_mci_rockchip_probe, - .remove = dw_mci_rockchip_remove, -+ .shutdown = dw_mci_rockchip_shutdown, - .driver = { - .name = "dwmmc_rockchip", - .probe_type = PROBE_PREFER_ASYNCHRONOUS, --- -2.51.0 - diff --git a/patch/kernel/archive/sunxi-6.16/series.conf b/patch/kernel/archive/sunxi-6.16/series.conf index 014485fd9..5a5491d14 100644 --- a/patch/kernel/archive/sunxi-6.16/series.conf +++ b/patch/kernel/archive/sunxi-6.16/series.conf @@ -161,25 +161,19 @@ patches.megous/arm64-dts-sun50i-h5-Add-missing-GPU-trip-point.patch patches.megous/arm64-dts-allwinner-a64-Fix-LRADC-compatible.patch patches.megous/media-cedrus-Fix-failure-to-clean-up-hardware-on-probe-failure.patch - patches.megous/ASoC-rockchip-Fix-doubling-of-playback-speed-after-system-sleep.patch patches.megous/usb-musb-sunxi-Avoid-enabling-host-side-code-on-SoCs-where-it-s.patch patches.megous/arm64-dts-allwinner-Enforce-consistent-MMC-numbering.patch patches.megous/ARM-dts-sunxi-Add-aliases-for-MMC.patch - patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch patches.megous/usb-gadget-Fix-dangling-pointer-in-netdev-private-data.patch - patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch patches.megous/Revert-drm-sun4i-lvds-Invert-the-LVDS-polarity.patch patches.megous/of-property-fw_devlink-Support-allwinner-sram-links.patch patches.megous/Fix-broken-allwinner-sram-dependency-on-h616-h618.patch - patches.megous/arm64-dts-rockchip-rk356x-Fix-PCIe-register-map-and-ranges.patch patches.megous/Fix-intptr_t-typedef.patch patches.megous/mmc-sunxi-mmc-Remove-runtime-PM.patch patches.megous/pci-Workaround-ITS-timeouts-on-poweroff-reboot-on-Orange-Pi-5-P.patch patches.megous/usb-serial-option-add-reset_resume-callback-for-WWAN-devices.patch patches.megous/media-ov5648-Fix-call-to-pm_runtime_set_suspended.patch - patches.megous/drm-rockchip-dw-mipi-dsi-rockchip-Fix-ISP1-PHY-initialization.patch patches.megous/arm64-dts-rk3399-Add-dmc_opp_table.patch - patches.megous/arm64-dts-rockchip-rk3399-s-Add-DMC-table.patch patches.megous/bluetooth-h5-Don-t-re-initialize-rtl8723cs-on-resume.patch patches.megous/drm-sun4i-Mark-one-of-the-UI-planes-as-a-cursor-one.patch patches.megous/drm-sun4i-Implement-gamma-correction.patch @@ -244,5 +238,4 @@ patches.megous/Add-support-for-my-private-Sapomat-device.patch patches.megous/ARM-dts-sun8i-h3-orange-pi-one-Enable-all-gpio-header-UARTs.patch patches.megous/mtd-spi-nor-Add-Alliance-memory-support.patch -- patches.megous/Add-README.md-with-information-and-u-boot-patches.patch patches.megous/Defconfigs-for-all-my-devices.patch diff --git a/patch/kernel/archive/sunxi-6.16/series.megous b/patch/kernel/archive/sunxi-6.16/series.megous index fa0276309..f3ce3e3d1 100644 --- a/patch/kernel/archive/sunxi-6.16/series.megous +++ b/patch/kernel/archive/sunxi-6.16/series.megous @@ -160,25 +160,19 @@ patches.megous/arm64-dts-sun50i-h5-Add-missing-GPU-trip-point.patch patches.megous/arm64-dts-allwinner-a64-Fix-LRADC-compatible.patch patches.megous/media-cedrus-Fix-failure-to-clean-up-hardware-on-probe-failure.patch - patches.megous/ASoC-rockchip-Fix-doubling-of-playback-speed-after-system-sleep.patch patches.megous/usb-musb-sunxi-Avoid-enabling-host-side-code-on-SoCs-where-it-s.patch patches.megous/arm64-dts-allwinner-Enforce-consistent-MMC-numbering.patch patches.megous/ARM-dts-sunxi-Add-aliases-for-MMC.patch - patches.megous/drm-rockchip-Fix-panic-on-reboot-when-DRM-device-fails-to-bind.patch patches.megous/usb-gadget-Fix-dangling-pointer-in-netdev-private-data.patch - patches.megous/mmc-dw-mmc-rockchip-fix-sdmmc-after-soft-reboot.patch patches.megous/Revert-drm-sun4i-lvds-Invert-the-LVDS-polarity.patch patches.megous/of-property-fw_devlink-Support-allwinner-sram-links.patch patches.megous/Fix-broken-allwinner-sram-dependency-on-h616-h618.patch - patches.megous/arm64-dts-rockchip-rk356x-Fix-PCIe-register-map-and-ranges.patch patches.megous/Fix-intptr_t-typedef.patch patches.megous/mmc-sunxi-mmc-Remove-runtime-PM.patch patches.megous/pci-Workaround-ITS-timeouts-on-poweroff-reboot-on-Orange-Pi-5-P.patch patches.megous/usb-serial-option-add-reset_resume-callback-for-WWAN-devices.patch patches.megous/media-ov5648-Fix-call-to-pm_runtime_set_suspended.patch - patches.megous/drm-rockchip-dw-mipi-dsi-rockchip-Fix-ISP1-PHY-initialization.patch patches.megous/arm64-dts-rk3399-Add-dmc_opp_table.patch - patches.megous/arm64-dts-rockchip-rk3399-s-Add-DMC-table.patch patches.megous/bluetooth-h5-Don-t-re-initialize-rtl8723cs-on-resume.patch patches.megous/drm-sun4i-Mark-one-of-the-UI-planes-as-a-cursor-one.patch patches.megous/drm-sun4i-Implement-gamma-correction.patch @@ -243,5 +237,4 @@ patches.megous/Add-support-for-my-private-Sapomat-device.patch patches.megous/ARM-dts-sun8i-h3-orange-pi-one-Enable-all-gpio-header-UARTs.patch patches.megous/mtd-spi-nor-Add-Alliance-memory-support.patch - patches.megous/Add-README.md-with-information-and-u-boot-patches.patch patches.megous/Defconfigs-for-all-my-devices.patch