* [PATCH v5 00/15] Support 10-bit YUV422 and 8/10-bit YUV420 color format on DW HDMI QP
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Krzysztof Kozlowski, Sashiko,
Igor Paunovic, Sebastian Reichel
This series extends the output color format support of the Rockchip DW
HDMI QP controller to cover 10-bit YUV 4:2:2 and 8/10-bit YUV 4:2:0.
Patches 1, 7 & 15 improve VOP2 robustness on RK3588, helping recover
from exceptions and preventing random display output glitches observed
when switching modes that also change the color format, e.g. from RGB to
YUV 4:2:0 and vice versa.
Patch 8 avoids an incorrect DCLK source switch for 10-bit YUV 4:2:2 by
forcing 8 bpc in the bandwidth check.
Patches 2-6 address a few vop2 related issues reported by Sashiko, while
9-12 are additional cleanups/improvements.
Patch 13 adds MEDIA_BUS_FMT_UYVY10_1X20 for 10-bit YUV 4:2:2 output,
configuring the PHY with 8 bpc. YUV 4:2:2 always transmits two 12-bit
components per pixel regardless of color depth, so from a clock-rate
perspective it is equivalent to three 8-bit RGB components.
Patch 14 advertises YUV 4:2:0 output, now that the bus-format and VOP2
support are in place.
Tested on Radxa's boards ROCK 5B (RK3588) and ROCK 4D (RK3576).
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
Changes in v5:
- Rebased onto latest drm-misc-next and fixed the conflicts introduced
by the recent addition of HDMI 2.0 support to the DRM infrastructure
- Updated patch "drm/rockchip: vop2: Reset AXI and DCLK to improve
robustness" to also assert the AXI reset in the bind path, fixing DSI
panel support on RK3588 EVB1 (Sebastian Reichel)
- Added new patch "drm/rockchip: dw_hdmi_qp: Do not mask error code in
atomic_check()" to fix a pre-existing issue reported by Sashiko
- Link to v4: https://patch.msgid.link/20260903-dw-hdmi-qp-yuv-v4-0-fb45bf4147eb@collabora.com
Changes in v4:
- Collected T-b tags from Igor
- Rebased onto the latest drm-misc-next, which now contains the HDPTX
PHY driver fixes, so the runtime dependency has been dropped
- Link to v3: https://patch.msgid.link/20260709-dw-hdmi-qp-yuv-v3-0-a4a982a9f2e7@collabora.com
Changes in v3:
- Updated patch 3 to skip any hardware programming in the callbacks
gated by drm_atomic_helper_commit_planes() after powering down VOP2 on
an atomic_enable() error (Sashiko)
- Ensured VBLANK events are sent immediately when atomic_enable() fails,
hence preventing userspace processes waiting for the page flip
completion to hang indefinitely (new patch 4, Sashiko)
- Rebased onto latest drm-misc-next
- Link to v2: https://patch.msgid.link/20260706-dw-hdmi-qp-yuv-v2-0-b91beb33dedf@collabora.com
Changes in v2:
- Collected R-b from Krzysztof on the binding patch, while also fixed
the property ordering in the example
- Renamed vop2_clk_reset() to vop2_reset_assert_deassert() and used to
devm_reset_control_get_optional_exclusive() in patch 6 (Philipp Zabel)
- Addressed several issues reported by Sashiko
* Reset AXI before detaching the IOMMU domain, to close a theoretical
window where stale or in-flight DMA transactions could fault or
access memory untranslated after the domain is detached (patch 6)
* Fixed resource leak on vop2_enable() error path (new patch 2)
* Balance state on atomic_enable error paths (new patch 3)
* Avoided division by zero when computing max_dclk (new path 4)
* Fixed VOP2_MAX_DCLK_RATE overflow on 32-bit (new patch 5)
- Rebased onto latest drm-misc-next
- Link to v1: https://patch.msgid.link/20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com
---
Cristian Ciocaltea (15):
dt-bindings: display: vop2: Add missing reset properties
drm/rockchip: vop2: Fix resource leak on vop2_enable() error path
drm/rockchip: vop2: Balance state on atomic_enable() error paths
drm/rockchip: vop2: Send pending event when atomic_enable() fails
drm/rockchip: vop2: Avoid division by zero when computing max_dclk
drm/rockchip: vop2: Fix VOP2_MAX_DCLK_RATE overflow on 32-bit
drm/rockchip: vop2: Reset AXI and DCLK to improve robustness
drm/rockchip: vop2: Avoid DCLK source switch for 10-bit YUV422 output
drm/rockchip: vop2: Consolidate HDMI PHY PLL clock parent switch
drm/rockchip: vop2: Switch to enum vop_csc_format
drm/bridge: dw-hdmi-qp: Log resolution and refresh rate in atomic_enable()
drm/rockchip: dw_hdmi_qp: Do not mask error code in atomic_check()
drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format
drm/rockchip: dw_hdmi_qp: Enable YUV420 output format
arm64: dts: rockchip: Add RK3588 VOP2 resets
.../bindings/display/rockchip/rockchip-vop2.yaml | 46 ++++-
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 12 ++
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 10 +-
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 15 +-
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 217 +++++++++++++++------
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 10 +
6 files changed, 247 insertions(+), 63 deletions(-)
---
base-commit: 3e32932d3626d0279f9b3531bd648f8c0a16cb08
change-id: 20260617-dw-hdmi-qp-yuv-2b0f7bb5ba81
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 35+ messages in thread* [PATCH v5 01/15] dt-bindings: display: vop2: Add missing reset properties
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Krzysztof Kozlowski
Document the VOP2 resets corresponding to the AXI, AHB and DCLK_VP0..2
clocks, which are common to all supported SoCs, plus DCLK_VP3 which is
provided only on RK3588.
While at it, move 'iommus' in the example up into the expected position
to keep the properties in alphabetical order.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
.../bindings/display/rockchip/rockchip-vop2.yaml | 46 +++++++++++++++++++++-
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index 93da1fb9adc4..f993cef0323b 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -82,6 +82,20 @@ properties:
- {}
- {}
+ resets:
+ minItems: 5
+ maxItems: 6
+
+ reset-names:
+ minItems: 5
+ items:
+ - const: axi
+ - const: ahb
+ - const: dclk_vp0
+ - const: dclk_vp1
+ - const: dclk_vp2
+ - const: dclk_vp3
+
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
@@ -148,6 +162,12 @@ allOf:
clock-names:
maxItems: 5
+ resets:
+ maxItems: 5
+
+ reset-names:
+ maxItems: 5
+
interrupts:
maxItems: 1
@@ -194,6 +214,12 @@ allOf:
- {}
- const: pll_hdmiphy0
+ resets:
+ maxItems: 5
+
+ reset-names:
+ maxItems: 5
+
interrupts:
minItems: 4
@@ -246,6 +272,12 @@ allOf:
- const: pll_hdmiphy0
- const: pll_hdmiphy1
+ resets:
+ minItems: 6
+
+ reset-names:
+ minItems: 6
+
interrupts:
maxItems: 1
@@ -289,9 +321,19 @@ examples:
"dclk_vp0",
"dclk_vp1",
"dclk_vp2";
- power-domains = <&power RK3568_PD_VO>;
- rockchip,grf = <&grf>;
iommus = <&vop_mmu>;
+ power-domains = <&power RK3568_PD_VO>;
+ resets = <&cru SRST_A_VOP>,
+ <&cru SRST_H_VOP>,
+ <&cru SRST_VOP0>,
+ <&cru SRST_VOP1>,
+ <&cru SRST_VOP2>;
+ reset-names = "axi",
+ "ahb",
+ "dclk_vp0",
+ "dclk_vp1",
+ "dclk_vp2";
+ rockchip,grf = <&grf>;
vop_out: ports {
#address-cells = <1>;
#size-cells = <0>;
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 01/15] dt-bindings: display: vop2: Add missing reset properties
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Krzysztof Kozlowski
Document the VOP2 resets corresponding to the AXI, AHB and DCLK_VP0..2
clocks, which are common to all supported SoCs, plus DCLK_VP3 which is
provided only on RK3588.
While at it, move 'iommus' in the example up into the expected position
to keep the properties in alphabetical order.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
.../bindings/display/rockchip/rockchip-vop2.yaml | 46 +++++++++++++++++++++-
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index 93da1fb9adc4..f993cef0323b 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -82,6 +82,20 @@ properties:
- {}
- {}
+ resets:
+ minItems: 5
+ maxItems: 6
+
+ reset-names:
+ minItems: 5
+ items:
+ - const: axi
+ - const: ahb
+ - const: dclk_vp0
+ - const: dclk_vp1
+ - const: dclk_vp2
+ - const: dclk_vp3
+
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
@@ -148,6 +162,12 @@ allOf:
clock-names:
maxItems: 5
+ resets:
+ maxItems: 5
+
+ reset-names:
+ maxItems: 5
+
interrupts:
maxItems: 1
@@ -194,6 +214,12 @@ allOf:
- {}
- const: pll_hdmiphy0
+ resets:
+ maxItems: 5
+
+ reset-names:
+ maxItems: 5
+
interrupts:
minItems: 4
@@ -246,6 +272,12 @@ allOf:
- const: pll_hdmiphy0
- const: pll_hdmiphy1
+ resets:
+ minItems: 6
+
+ reset-names:
+ minItems: 6
+
interrupts:
maxItems: 1
@@ -289,9 +321,19 @@ examples:
"dclk_vp0",
"dclk_vp1",
"dclk_vp2";
- power-domains = <&power RK3568_PD_VO>;
- rockchip,grf = <&grf>;
iommus = <&vop_mmu>;
+ power-domains = <&power RK3568_PD_VO>;
+ resets = <&cru SRST_A_VOP>,
+ <&cru SRST_H_VOP>,
+ <&cru SRST_VOP0>,
+ <&cru SRST_VOP1>,
+ <&cru SRST_VOP2>;
+ reset-names = "axi",
+ "ahb",
+ "dclk_vp0",
+ "dclk_vp1",
+ "dclk_vp2";
+ rockchip,grf = <&grf>;
vop_out: ports {
#address-cells = <1>;
#size-cells = <0>;
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 02/15] drm/rockchip: vop2: Fix resource leak on vop2_enable() error path
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
vop2_enable() returns void, so callers cannot tell whether powering up
the VOP2 succeeded.
Additionally, if rockchip_drm_dma_attach_device() fails, vop2_enable()
returns without disabling the core clocks or dropping the runtime PM
reference taken earlier, leaking both.
Make vop2_enable() return int and unwind all resources on every failure
path. As disabling the core clocks is also needed in vop2_disable(),
factor it out into a local helper used by both.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 39 +++++++++++++++++++---------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index bfb384142568..e0caea93a896 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -860,6 +860,13 @@ static int vop2_core_clks_prepare_enable(struct vop2 *vop2)
return ret;
}
+static void vop2_core_clks_disable_unprepare(struct vop2 *vop2)
+{
+ clk_disable_unprepare(vop2->pclk);
+ clk_disable_unprepare(vop2->aclk);
+ clk_disable_unprepare(vop2->hclk);
+}
+
static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
{
u32 pd;
@@ -871,7 +878,7 @@ static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
vop2_writel(vop2, RK3588_SYS_PD_CTRL, pd);
}
-static void vop2_enable(struct vop2 *vop2)
+static int vop2_enable(struct vop2 *vop2)
{
int ret;
u32 version;
@@ -879,25 +886,24 @@ static void vop2_enable(struct vop2 *vop2)
ret = pm_runtime_resume_and_get(vop2->dev);
if (ret < 0) {
drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
- return;
+ return ret;
}
ret = vop2_core_clks_prepare_enable(vop2);
- if (ret) {
- pm_runtime_put_sync(vop2->dev);
- return;
- }
+ if (ret)
+ goto err_put_pm;
ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev);
if (ret) {
- drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret);
- return;
+ drm_err(vop2->drm, "failed to attach dma mapping: %d\n", ret);
+ goto err_disable_clks;
}
version = vop2_readl(vop2, RK3568_VERSION_INFO);
if (version != vop2->version) {
drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
- return;
+ ret = -EINVAL;
+ goto err_detach_dma;
}
/*
@@ -932,6 +938,17 @@ static void vop2_enable(struct vop2 *vop2)
VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
vop2_writel(vop2, RK3568_SYS1_INT_EN,
VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
+
+ return 0;
+
+err_detach_dma:
+ rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
+err_disable_clks:
+ vop2_core_clks_disable_unprepare(vop2);
+err_put_pm:
+ pm_runtime_put_sync(vop2->dev);
+
+ return ret;
}
static void vop2_disable(struct vop2 *vop2)
@@ -942,9 +959,7 @@ static void vop2_disable(struct vop2 *vop2)
regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
- clk_disable_unprepare(vop2->pclk);
- clk_disable_unprepare(vop2->aclk);
- clk_disable_unprepare(vop2->hclk);
+ vop2_core_clks_disable_unprepare(vop2);
}
static bool vop2_vp_dsp_lut_is_enabled(struct vop2_video_port *vp)
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 02/15] drm/rockchip: vop2: Fix resource leak on vop2_enable() error path
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
vop2_enable() returns void, so callers cannot tell whether powering up
the VOP2 succeeded.
Additionally, if rockchip_drm_dma_attach_device() fails, vop2_enable()
returns without disabling the core clocks or dropping the runtime PM
reference taken earlier, leaking both.
Make vop2_enable() return int and unwind all resources on every failure
path. As disabling the core clocks is also needed in vop2_disable(),
factor it out into a local helper used by both.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 39 +++++++++++++++++++---------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index bfb384142568..e0caea93a896 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -860,6 +860,13 @@ static int vop2_core_clks_prepare_enable(struct vop2 *vop2)
return ret;
}
+static void vop2_core_clks_disable_unprepare(struct vop2 *vop2)
+{
+ clk_disable_unprepare(vop2->pclk);
+ clk_disable_unprepare(vop2->aclk);
+ clk_disable_unprepare(vop2->hclk);
+}
+
static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
{
u32 pd;
@@ -871,7 +878,7 @@ static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
vop2_writel(vop2, RK3588_SYS_PD_CTRL, pd);
}
-static void vop2_enable(struct vop2 *vop2)
+static int vop2_enable(struct vop2 *vop2)
{
int ret;
u32 version;
@@ -879,25 +886,24 @@ static void vop2_enable(struct vop2 *vop2)
ret = pm_runtime_resume_and_get(vop2->dev);
if (ret < 0) {
drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
- return;
+ return ret;
}
ret = vop2_core_clks_prepare_enable(vop2);
- if (ret) {
- pm_runtime_put_sync(vop2->dev);
- return;
- }
+ if (ret)
+ goto err_put_pm;
ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev);
if (ret) {
- drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret);
- return;
+ drm_err(vop2->drm, "failed to attach dma mapping: %d\n", ret);
+ goto err_disable_clks;
}
version = vop2_readl(vop2, RK3568_VERSION_INFO);
if (version != vop2->version) {
drm_err(vop2->drm, "Hardware version(0x%08x) mismatch\n", version);
- return;
+ ret = -EINVAL;
+ goto err_detach_dma;
}
/*
@@ -932,6 +938,17 @@ static void vop2_enable(struct vop2 *vop2)
VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
vop2_writel(vop2, RK3568_SYS1_INT_EN,
VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
+
+ return 0;
+
+err_detach_dma:
+ rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
+err_disable_clks:
+ vop2_core_clks_disable_unprepare(vop2);
+err_put_pm:
+ pm_runtime_put_sync(vop2->dev);
+
+ return ret;
}
static void vop2_disable(struct vop2 *vop2)
@@ -942,9 +959,7 @@ static void vop2_disable(struct vop2 *vop2)
regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
- clk_disable_unprepare(vop2->pclk);
- clk_disable_unprepare(vop2->aclk);
- clk_disable_unprepare(vop2->hclk);
+ vop2_core_clks_disable_unprepare(vop2);
}
static bool vop2_vp_dsp_lut_is_enabled(struct vop2_video_port *vp)
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 03/15] drm/rockchip: vop2: Balance state on atomic_enable() error paths
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
vop2_crtc_atomic_enable() prepares vp->dclk and, for the first CRTC,
calls vop2_enable(), incrementing the shared vop2->enable_count before
programming VOP2 registers. Two later failure points return early with
only vop2_unlock(), leaking the dclk prepare, the enable_count
increment, and the core clocks / PM runtime reference from
vop2_enable().
Since the disable path decrements enable_count unconditionally, the
leaked increment skews the count, causing an underflow or premature
shutdown of core clocks and PM runtime while another CRTC is active.
Moreover, cleaning up on the enable error paths alone is insufficient.
A CRTC whose atomic_enable() bailed is still committed as active, so
vop2_crtc_atomic_disable() still runs its full teardown, releasing the
same dclk prepare and enable_count a second time, thus underflowing both
counts and, where vop2_enable() ran, touching VOP registers with core
clocks gated.
Fix this by reverting exactly what was set up on failure, and track the
per-VP bring-up state so atomic_disable() skips teardown when
atomic_enable() never completed. Additionally, ensure any further
hardware programming is also skipped within the affected RPM commit
tail, i.e. in the callbacks gated by drm_atomic_helper_commit_planes():
vop2_crtc_atomic_begin(), vop2_plane_atomic_update{update|disable}() and
vop2_crtc_atomic_flush().
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 68 ++++++++++++++++++++++------
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 6 +++
2 files changed, 59 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index e0caea93a896..36384f029ef7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1033,6 +1033,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
vop2_lock(vop2);
+ if (!vp->enabled)
+ goto out_unlock;
+
old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
@@ -1063,11 +1066,14 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
clk_disable_unprepare(vp->dclk);
+ vp->enabled = false;
+
vop2->enable_count--;
if (!vop2->enable_count)
vop2_disable(vop2);
+out_unlock:
vop2_unlock(vop2);
if (crtc->state->event && !crtc->state->active) {
@@ -1197,13 +1203,21 @@ static void vop2_plane_atomic_disable(struct drm_plane *plane,
struct drm_plane_state *old_pstate = NULL;
struct vop2_win *win = to_vop2_win(plane);
struct vop2 *vop2 = win->vop2;
+ struct vop2_video_port *vp;
drm_dbg(vop2->drm, "%s disable\n", win->data->name);
if (state)
old_pstate = drm_atomic_get_old_plane_state(state, plane);
- if (old_pstate && !old_pstate->crtc)
- return;
+
+ if (old_pstate) {
+ if (!old_pstate->crtc)
+ return;
+
+ vp = to_vop2_video_port(old_pstate->crtc);
+ if (!vp->enabled)
+ return;
+ }
vop2_win_disable(win);
vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0);
@@ -1298,6 +1312,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
if (WARN_ON(!crtc))
return;
+ if (!vp->enabled)
+ return;
+
if (!pstate->visible) {
vop2_plane_atomic_disable(plane, state);
return;
@@ -1803,8 +1820,11 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
return;
}
- if (!vop2->enable_count)
- vop2_enable(vop2);
+ if (!vop2->enable_count) {
+ ret = vop2_enable(vop2);
+ if (ret)
+ goto err_unprepare_dclk;
+ }
vop2->enable_count++;
@@ -1831,10 +1851,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
}
- if (!clock) {
- vop2_unlock(vop2);
- return;
- }
+ if (!clock)
+ goto err_put_enable_count;
if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
!(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))
@@ -1852,8 +1870,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
default:
drm_err(vop2->drm, "Unknown DRM_MODE_CONNECTOR %d\n",
vcstate->output_type);
- vop2_unlock(vop2);
- return;
+ goto err_put_enable_count;
}
else
out_mode = vcstate->output_mode;
@@ -1965,6 +1982,18 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
drm_crtc_vblank_on(crtc);
+ vp->enabled = true;
+
+ vop2_unlock(vop2);
+
+ return;
+
+err_put_enable_count:
+ if (!--vop2->enable_count)
+ vop2_disable(vop2);
+
+err_unprepare_dclk:
+ clk_disable_unprepare(vp->dclk);
vop2_unlock(vop2);
}
@@ -2023,6 +2052,9 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
+ if (!vp->enabled)
+ return;
+
vop2->ops->setup_overlay(vp);
}
@@ -2034,13 +2066,19 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
- /* In case of modeset, gamma lut update already happened in atomic enable */
- if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed)
- vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
+ if (vp->enabled) {
+ /*
+ * In case of modeset, gamma lut update already happened
+ * in atomic enable.
+ */
+ if (!drm_atomic_crtc_needs_modeset(crtc_state) &&
+ crtc_state->color_mgmt_changed)
+ vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
- vop2_post_config(crtc, false, crtc_state, old_crtc_state);
+ vop2_post_config(crtc, false, crtc_state, old_crtc_state);
- vop2_cfg_done(vp);
+ vop2_cfg_done(vp);
+ }
spin_lock_irq(&crtc->dev->event_lock);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index ffcb39c130aa..b209b2d5b96d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -243,6 +243,12 @@ struct vop2_video_port {
struct completion dsp_hold_completion;
+ /**
+ * @enabled: CRTC fully brought up by atomic_enable(); allows
+ * atomic_disable() to skip teardown after a failed enable.
+ */
+ bool enabled;
+
/**
* @win_mask: Bitmask of windows attached to the video port;
*/
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 03/15] drm/rockchip: vop2: Balance state on atomic_enable() error paths
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
vop2_crtc_atomic_enable() prepares vp->dclk and, for the first CRTC,
calls vop2_enable(), incrementing the shared vop2->enable_count before
programming VOP2 registers. Two later failure points return early with
only vop2_unlock(), leaking the dclk prepare, the enable_count
increment, and the core clocks / PM runtime reference from
vop2_enable().
Since the disable path decrements enable_count unconditionally, the
leaked increment skews the count, causing an underflow or premature
shutdown of core clocks and PM runtime while another CRTC is active.
Moreover, cleaning up on the enable error paths alone is insufficient.
A CRTC whose atomic_enable() bailed is still committed as active, so
vop2_crtc_atomic_disable() still runs its full teardown, releasing the
same dclk prepare and enable_count a second time, thus underflowing both
counts and, where vop2_enable() ran, touching VOP registers with core
clocks gated.
Fix this by reverting exactly what was set up on failure, and track the
per-VP bring-up state so atomic_disable() skips teardown when
atomic_enable() never completed. Additionally, ensure any further
hardware programming is also skipped within the affected RPM commit
tail, i.e. in the callbacks gated by drm_atomic_helper_commit_planes():
vop2_crtc_atomic_begin(), vop2_plane_atomic_update{update|disable}() and
vop2_crtc_atomic_flush().
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623202043.8BFE21F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 68 ++++++++++++++++++++++------
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 6 +++
2 files changed, 59 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index e0caea93a896..36384f029ef7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1033,6 +1033,9 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
vop2_lock(vop2);
+ if (!vp->enabled)
+ goto out_unlock;
+
old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
@@ -1063,11 +1066,14 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
clk_disable_unprepare(vp->dclk);
+ vp->enabled = false;
+
vop2->enable_count--;
if (!vop2->enable_count)
vop2_disable(vop2);
+out_unlock:
vop2_unlock(vop2);
if (crtc->state->event && !crtc->state->active) {
@@ -1197,13 +1203,21 @@ static void vop2_plane_atomic_disable(struct drm_plane *plane,
struct drm_plane_state *old_pstate = NULL;
struct vop2_win *win = to_vop2_win(plane);
struct vop2 *vop2 = win->vop2;
+ struct vop2_video_port *vp;
drm_dbg(vop2->drm, "%s disable\n", win->data->name);
if (state)
old_pstate = drm_atomic_get_old_plane_state(state, plane);
- if (old_pstate && !old_pstate->crtc)
- return;
+
+ if (old_pstate) {
+ if (!old_pstate->crtc)
+ return;
+
+ vp = to_vop2_video_port(old_pstate->crtc);
+ if (!vp->enabled)
+ return;
+ }
vop2_win_disable(win);
vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0);
@@ -1298,6 +1312,9 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
if (WARN_ON(!crtc))
return;
+ if (!vp->enabled)
+ return;
+
if (!pstate->visible) {
vop2_plane_atomic_disable(plane, state);
return;
@@ -1803,8 +1820,11 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
return;
}
- if (!vop2->enable_count)
- vop2_enable(vop2);
+ if (!vop2->enable_count) {
+ ret = vop2_enable(vop2);
+ if (ret)
+ goto err_unprepare_dclk;
+ }
vop2->enable_count++;
@@ -1831,10 +1851,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
clock = vop2->ops->setup_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
}
- if (!clock) {
- vop2_unlock(vop2);
- return;
- }
+ if (!clock)
+ goto err_put_enable_count;
if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
!(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))
@@ -1852,8 +1870,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
default:
drm_err(vop2->drm, "Unknown DRM_MODE_CONNECTOR %d\n",
vcstate->output_type);
- vop2_unlock(vop2);
- return;
+ goto err_put_enable_count;
}
else
out_mode = vcstate->output_mode;
@@ -1965,6 +1982,18 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
drm_crtc_vblank_on(crtc);
+ vp->enabled = true;
+
+ vop2_unlock(vop2);
+
+ return;
+
+err_put_enable_count:
+ if (!--vop2->enable_count)
+ vop2_disable(vop2);
+
+err_unprepare_dclk:
+ clk_disable_unprepare(vp->dclk);
vop2_unlock(vop2);
}
@@ -2023,6 +2052,9 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
+ if (!vp->enabled)
+ return;
+
vop2->ops->setup_overlay(vp);
}
@@ -2034,13 +2066,19 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
- /* In case of modeset, gamma lut update already happened in atomic enable */
- if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed)
- vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
+ if (vp->enabled) {
+ /*
+ * In case of modeset, gamma lut update already happened
+ * in atomic enable.
+ */
+ if (!drm_atomic_crtc_needs_modeset(crtc_state) &&
+ crtc_state->color_mgmt_changed)
+ vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
- vop2_post_config(crtc, false, crtc_state, old_crtc_state);
+ vop2_post_config(crtc, false, crtc_state, old_crtc_state);
- vop2_cfg_done(vp);
+ vop2_cfg_done(vp);
+ }
spin_lock_irq(&crtc->dev->event_lock);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index ffcb39c130aa..b209b2d5b96d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -243,6 +243,12 @@ struct vop2_video_port {
struct completion dsp_hold_completion;
+ /**
+ * @enabled: CRTC fully brought up by atomic_enable(); allows
+ * atomic_disable() to skip teardown after a failed enable.
+ */
+ bool enabled;
+
/**
* @win_mask: Bitmask of windows attached to the video port;
*/
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 04/15] drm/rockchip: vop2: Send pending event when atomic_enable() fails
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
vop2_crtc_atomic_flush() stashes the CRTC completion event in vp->event
and relies on the frame start interrupt (VP_INT_FS_FIELD) to deliver it
later via drm_crtc_send_vblank_event(). Since atomic_enable() runs
before atomic_flush(), bailing on an error path makes it skip
drm_crtc_vblank_on() and leave the video port disabled. atomic_flush()
still traps the event in vp->event, but since the port never scans out,
the frame start interrupt does not fire and the event is not delivered.
Userspace waiting for the flip completion then blocks indefinitely.
Note the event cannot be flushed from atomic_disable(), as userspace
waits for the completion before committing the next state, so the
disable does not arrive and draining it there would deadlock.
Use the newly added vp->enabled flag to detect this in atomic_flush()
and send the event immediately when the port did not come up, rather
than deferring it to an interrupt that will never occur. This also
avoids the spurious drm_crtc_vblank_get() WARN previously hit on the
failed enable path, where the vblank is not on.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260706194935.AC7601F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 36384f029ef7..3bbbe365b5f1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2083,8 +2083,19 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
spin_lock_irq(&crtc->dev->event_lock);
if (crtc->state->event) {
- WARN_ON(drm_crtc_vblank_get(crtc));
- vp->event = crtc->state->event;
+ /*
+ * A failed atomic_enable() leaves the video port disabled with
+ * no scanout, so the frame start interrupt that normally
+ * delivers vp->event never fires. Send the event right away in
+ * that case to avoid stalling the flip completion.
+ */
+ if (vp->enabled) {
+ WARN_ON(drm_crtc_vblank_get(crtc));
+ vp->event = crtc->state->event;
+ } else {
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ }
+
crtc->state->event = NULL;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 04/15] drm/rockchip: vop2: Send pending event when atomic_enable() fails
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
vop2_crtc_atomic_flush() stashes the CRTC completion event in vp->event
and relies on the frame start interrupt (VP_INT_FS_FIELD) to deliver it
later via drm_crtc_send_vblank_event(). Since atomic_enable() runs
before atomic_flush(), bailing on an error path makes it skip
drm_crtc_vblank_on() and leave the video port disabled. atomic_flush()
still traps the event in vp->event, but since the port never scans out,
the frame start interrupt does not fire and the event is not delivered.
Userspace waiting for the flip completion then blocks indefinitely.
Note the event cannot be flushed from atomic_disable(), as userspace
waits for the completion before committing the next state, so the
disable does not arrive and draining it there would deadlock.
Use the newly added vp->enabled flag to detect this in atomic_flush()
and send the event immediately when the port did not come up, rather
than deferring it to an interrupt that will never occur. This also
avoids the spurious drm_crtc_vblank_get() WARN previously hit on the
failed enable path, where the vblank is not on.
Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260706194935.AC7601F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 36384f029ef7..3bbbe365b5f1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2083,8 +2083,19 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
spin_lock_irq(&crtc->dev->event_lock);
if (crtc->state->event) {
- WARN_ON(drm_crtc_vblank_get(crtc));
- vp->event = crtc->state->event;
+ /*
+ * A failed atomic_enable() leaves the video port disabled with
+ * no scanout, so the frame start interrupt that normally
+ * delivers vp->event never fires. Send the event right away in
+ * that case to avoid stalling the flip completion.
+ */
+ if (vp->enabled) {
+ WARN_ON(drm_crtc_vblank_get(crtc));
+ vp->event = crtc->state->event;
+ } else {
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ }
+
crtc->state->event = NULL;
}
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 05/15] drm/rockchip: vop2: Avoid division by zero when computing max_dclk
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
The DCLK reparenting logic in vop2_crtc_atomic_enable() is gated only on
the presence of an HDMI PHY PLL on the SoC.
This condition is true on any board that wires up an HDMI PHY, even when
the CRTC is currently driving a non-HDMI output such as DSI or LVDS.
Those encoders do not set vcstate->output_bpc, so it stays 0, hence the
subsequent DIV_ROUND_CLOSEST_ULL() then divides by zero.
Note this division happens before the drm_for_each_encoder_mask() loop
that would establish whether the pipe is actually driven by HDMI, so the
loop provides no protection.
Default bpc to 8 when it would otherwise be 0. The resulting max_dclk
value is a don't-care on the non-HDMI paths that trigger this, since the
encoder loop will not select the PHY PLL as the DCLK source there.
Fixes: b0362c45c401 ("drm/rockchip: vop2: Check bpc before switching DCLK source")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 3bbbe365b5f1..5a870a843dae 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1931,8 +1931,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
* to 4K@60Hz, if available, otherwise keep using the system CRU.
*/
if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) {
- unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8,
- vcstate->output_bpc);
+ unsigned int bpc = vcstate->output_bpc ?: 8;
+ unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 05/15] drm/rockchip: vop2: Avoid division by zero when computing max_dclk
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
The DCLK reparenting logic in vop2_crtc_atomic_enable() is gated only on
the presence of an HDMI PHY PLL on the SoC.
This condition is true on any board that wires up an HDMI PHY, even when
the CRTC is currently driving a non-HDMI output such as DSI or LVDS.
Those encoders do not set vcstate->output_bpc, so it stays 0, hence the
subsequent DIV_ROUND_CLOSEST_ULL() then divides by zero.
Note this division happens before the drm_for_each_encoder_mask() loop
that would establish whether the pipe is actually driven by HDMI, so the
loop provides no protection.
Default bpc to 8 when it would otherwise be 0. The resulting max_dclk
value is a don't-care on the non-HDMI paths that trigger this, since the
encoder loop will not select the PHY PLL as the DCLK source there.
Fixes: b0362c45c401 ("drm/rockchip: vop2: Check bpc before switching DCLK source")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 3bbbe365b5f1..5a870a843dae 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1931,8 +1931,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
* to 4K@60Hz, if available, otherwise keep using the system CRU.
*/
if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) {
- unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8,
- vcstate->output_bpc);
+ unsigned int bpc = vcstate->output_bpc ?: 8;
+ unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 06/15] drm/rockchip: vop2: Fix VOP2_MAX_DCLK_RATE overflow on 32-bit
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
VOP2_MAX_DCLK_RATE is defined as an unsigned long and is used scaled by
the color-depth ratio when computing the maximum DCLK the HDMI PHY PLL
can source.
On architectures where unsigned long is 32-bit, VOP2_MAX_DCLK_RATE * 8
is evaluated in 32-bit arithmetic and overflows: 4800000000 wraps to
505032704 before it is promoted to the 64-bit argument of
DIV_ROUND_CLOSEST_ULL(). At 8 bpc this collapses max_dclk from the
intended 600 MHz down to roughly 63 MHz.
As a result, low-resolution modes (e.g. 640x480 or 720x480, whose pixel
clocks are well under 30 MHz) still pass the clock <= max_dclk check and
are reparented to the HDMI PHY PLL as expected, but higher-resolution
modes such as 1280x720 (~74 MHz), 1920x1080 (~148 MHz) and above are
wrongly rejected and fall back to the system CRU as the DCLK source.
Define the constant as unsigned long long so that every expression using
it is evaluated in 64-bit arithmetic, independent of the width of
unsigned long. This future-proofs any additional users of the macro as
well.
Fixes: b0362c45c401 ("drm/rockchip: vop2: Check bpc before switching DCLK source")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 5a870a843dae..14c073f61c64 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -102,7 +102,7 @@ enum vop2_afbc_format {
VOP2_AFBC_FMT_INVALID = -1,
};
-#define VOP2_MAX_DCLK_RATE 600000000UL
+#define VOP2_MAX_DCLK_RATE 600000000ULL
/*
* bus-format types.
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 06/15] drm/rockchip: vop2: Fix VOP2_MAX_DCLK_RATE overflow on 32-bit
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko, Igor Paunovic
VOP2_MAX_DCLK_RATE is defined as an unsigned long and is used scaled by
the color-depth ratio when computing the maximum DCLK the HDMI PHY PLL
can source.
On architectures where unsigned long is 32-bit, VOP2_MAX_DCLK_RATE * 8
is evaluated in 32-bit arithmetic and overflows: 4800000000 wraps to
505032704 before it is promoted to the 64-bit argument of
DIV_ROUND_CLOSEST_ULL(). At 8 bpc this collapses max_dclk from the
intended 600 MHz down to roughly 63 MHz.
As a result, low-resolution modes (e.g. 640x480 or 720x480, whose pixel
clocks are well under 30 MHz) still pass the clock <= max_dclk check and
are reparented to the HDMI PHY PLL as expected, but higher-resolution
modes such as 1280x720 (~74 MHz), 1920x1080 (~148 MHz) and above are
wrongly rejected and fall back to the system CRU as the DCLK source.
Define the constant as unsigned long long so that every expression using
it is evaluated in 64-bit arithmetic, independent of the width of
unsigned long. This future-proofs any additional users of the macro as
well.
Fixes: b0362c45c401 ("drm/rockchip: vop2: Check bpc before switching DCLK source")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/all/20260623203310.9F8C81F000E9@smtp.kernel.org/
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 5a870a843dae..14c073f61c64 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -102,7 +102,7 @@ enum vop2_afbc_format {
VOP2_AFBC_FMT_INVALID = -1,
};
-#define VOP2_MAX_DCLK_RATE 600000000UL
+#define VOP2_MAX_DCLK_RATE 600000000ULL
/*
* bus-format types.
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 07/15] drm/rockchip: vop2: Reset AXI and DCLK to improve robustness
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sebastian Reichel, Igor Paunovic
Assert the AXI reset in the bind and CRTC disable paths, and the VP DCLK
reset in the enable path.
These resets are intended to leave the hardware in a clean state for the
next use, helping recover from exceptions such as IOMMU page faults, as
well as to prevent random display output glitches, such as a blank
image, observed when switching modes that also change the color format,
e.g. from RGB to YUV420 and vice versa. Moreover, this is also expected
to fix the DSI panel support on RK3588 EVB1.
For now this seems to affect only the RK3588, hence the resets are
optional and will be provided in the device tree for this SoC only.
Co-developed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Co-developed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 38 ++++++++++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 +++
2 files changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 14c073f61c64..afa4bc6cbcc4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/swab.h>
#include <drm/drm.h>
@@ -867,6 +868,26 @@ static void vop2_core_clks_disable_unprepare(struct vop2 *vop2)
clk_disable_unprepare(vop2->hclk);
}
+static void vop2_reset_assert_deassert(struct vop2 *vop2, struct reset_control *rstc)
+{
+ int ret;
+
+ if (!rstc)
+ return;
+
+ ret = reset_control_assert(rstc);
+ if (ret < 0) {
+ drm_warn(vop2->drm, "failed to assert reset: %d\n", ret);
+ return;
+ }
+
+ udelay(10);
+
+ ret = reset_control_deassert(rstc);
+ if (ret < 0)
+ drm_err(vop2->drm, "failed to deassert reset: %d\n", ret);
+}
+
static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
{
u32 pd;
@@ -953,6 +974,8 @@ static int vop2_enable(struct vop2 *vop2)
static void vop2_disable(struct vop2 *vop2)
{
+ vop2_reset_assert_deassert(vop2, vop2->axi_rst);
+
rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
pm_runtime_put_sync(vop2->dev);
@@ -1981,6 +2004,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
vop2_crtc_atomic_try_set_gamma(vop2, vp, crtc, crtc_state);
+ vop2_reset_assert_deassert(vop2, vp->dclk_rst);
+
drm_crtc_vblank_on(crtc);
vp->enabled = true;
@@ -2596,6 +2621,12 @@ static int vop2_create_crtcs(struct vop2 *vop2)
return dev_err_probe(drm->dev, PTR_ERR(vp->dclk),
"failed to get %s\n", dclk_name);
+ vp->dclk_rst = devm_reset_control_get_optional_exclusive(vop2->dev,
+ dclk_name);
+ if (IS_ERR(vp->dclk_rst))
+ return dev_err_probe(drm->dev, PTR_ERR(vp->dclk_rst),
+ "failed to get %s reset\n", dclk_name);
+
np = of_graph_get_remote_node(dev->of_node, i, -1);
if (!np) {
drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i);
@@ -2955,6 +2986,13 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy1),
"failed to get pll_hdmiphy1\n");
+ vop2->axi_rst = devm_reset_control_get_optional_exclusive(vop2->dev, "axi");
+ if (IS_ERR(vop2->axi_rst))
+ return dev_err_probe(drm->dev, PTR_ERR(vop2->axi_rst),
+ "failed to get axi reset\n");
+
+ vop2_reset_assert_deassert(vop2, vop2->axi_rst);
+
vop2->irq = platform_get_irq(pdev, 0);
if (vop2->irq < 0)
return dev_err_probe(drm->dev, vop2->irq, "cannot find irq for vop2\n");
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index b209b2d5b96d..1c2d7d97a6c2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -165,6 +165,8 @@ enum vop2_win_regs {
VOP2_WIN_MAX_REG,
};
+struct reset_control;
+
struct vop2_regs_dump {
const char *name;
u32 base;
@@ -238,6 +240,7 @@ struct vop2_video_port {
struct vop2 *vop2;
struct clk *dclk;
struct clk *dclk_src;
+ struct reset_control *dclk_rst;
unsigned int id;
const struct vop2_video_port_data *data;
@@ -335,6 +338,7 @@ struct vop2 {
struct clk *pclk;
struct clk *pll_hdmiphy0;
struct clk *pll_hdmiphy1;
+ struct reset_control *axi_rst;
/* optional internal rgb encoder */
struct rockchip_rgb *rgb;
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 07/15] drm/rockchip: vop2: Reset AXI and DCLK to improve robustness
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sebastian Reichel, Igor Paunovic
Assert the AXI reset in the bind and CRTC disable paths, and the VP DCLK
reset in the enable path.
These resets are intended to leave the hardware in a clean state for the
next use, helping recover from exceptions such as IOMMU page faults, as
well as to prevent random display output glitches, such as a blank
image, observed when switching modes that also change the color format,
e.g. from RGB to YUV420 and vice versa. Moreover, this is also expected
to fix the DSI panel support on RK3588 EVB1.
For now this seems to affect only the RK3588, hence the resets are
optional and will be provided in the device tree for this SoC only.
Co-developed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Co-developed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 38 ++++++++++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 +++
2 files changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 14c073f61c64..afa4bc6cbcc4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/swab.h>
#include <drm/drm.h>
@@ -867,6 +868,26 @@ static void vop2_core_clks_disable_unprepare(struct vop2 *vop2)
clk_disable_unprepare(vop2->hclk);
}
+static void vop2_reset_assert_deassert(struct vop2 *vop2, struct reset_control *rstc)
+{
+ int ret;
+
+ if (!rstc)
+ return;
+
+ ret = reset_control_assert(rstc);
+ if (ret < 0) {
+ drm_warn(vop2->drm, "failed to assert reset: %d\n", ret);
+ return;
+ }
+
+ udelay(10);
+
+ ret = reset_control_deassert(rstc);
+ if (ret < 0)
+ drm_err(vop2->drm, "failed to deassert reset: %d\n", ret);
+}
+
static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
{
u32 pd;
@@ -953,6 +974,8 @@ static int vop2_enable(struct vop2 *vop2)
static void vop2_disable(struct vop2 *vop2)
{
+ vop2_reset_assert_deassert(vop2, vop2->axi_rst);
+
rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
pm_runtime_put_sync(vop2->dev);
@@ -1981,6 +2004,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
vop2_crtc_atomic_try_set_gamma(vop2, vp, crtc, crtc_state);
+ vop2_reset_assert_deassert(vop2, vp->dclk_rst);
+
drm_crtc_vblank_on(crtc);
vp->enabled = true;
@@ -2596,6 +2621,12 @@ static int vop2_create_crtcs(struct vop2 *vop2)
return dev_err_probe(drm->dev, PTR_ERR(vp->dclk),
"failed to get %s\n", dclk_name);
+ vp->dclk_rst = devm_reset_control_get_optional_exclusive(vop2->dev,
+ dclk_name);
+ if (IS_ERR(vp->dclk_rst))
+ return dev_err_probe(drm->dev, PTR_ERR(vp->dclk_rst),
+ "failed to get %s reset\n", dclk_name);
+
np = of_graph_get_remote_node(dev->of_node, i, -1);
if (!np) {
drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i);
@@ -2955,6 +2986,13 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy1),
"failed to get pll_hdmiphy1\n");
+ vop2->axi_rst = devm_reset_control_get_optional_exclusive(vop2->dev, "axi");
+ if (IS_ERR(vop2->axi_rst))
+ return dev_err_probe(drm->dev, PTR_ERR(vop2->axi_rst),
+ "failed to get axi reset\n");
+
+ vop2_reset_assert_deassert(vop2, vop2->axi_rst);
+
vop2->irq = platform_get_irq(pdev, 0);
if (vop2->irq < 0)
return dev_err_probe(drm->dev, vop2->irq, "cannot find irq for vop2\n");
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index b209b2d5b96d..1c2d7d97a6c2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -165,6 +165,8 @@ enum vop2_win_regs {
VOP2_WIN_MAX_REG,
};
+struct reset_control;
+
struct vop2_regs_dump {
const char *name;
u32 base;
@@ -238,6 +240,7 @@ struct vop2_video_port {
struct vop2 *vop2;
struct clk *dclk;
struct clk *dclk_src;
+ struct reset_control *dclk_rst;
unsigned int id;
const struct vop2_video_port_data *data;
@@ -335,6 +338,7 @@ struct vop2 {
struct clk *pclk;
struct clk *pll_hdmiphy0;
struct clk *pll_hdmiphy1;
+ struct reset_control *axi_rst;
/* optional internal rgb encoder */
struct rockchip_rgb *rgb;
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH v5 07/15] drm/rockchip: vop2: Reset AXI and DCLK to improve robustness
2026-10-13 22:51 ` Cristian Ciocaltea
(?)
@ 2026-10-13 23:07 ` sashiko-bot
-1 siblings, 0 replies; 35+ messages in thread
From: sashiko-bot @ 2026-10-13 23:07 UTC (permalink / raw)
To: Cristian Ciocaltea; +Cc: dri-devel, devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] devm_reset_control_get_optional_exclusive in component bind causes -EBUSY on rebind
- [Medium] drm/rockchip: vop2: AXI reset is ineffective if clocks are gated during bind
- [Medium] drm/rockchip: asymmetrical teardown disables PM runtime before core clocks
--
commit e900afe14d3a61065ef92e05c15c885d78bc0d20
Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
drm/rockchip: vop2: Reset AXI and DCLK to improve robustness
Assert the AXI reset in the bind and CRTC disable paths, and the VP DCLK
reset in the enable path. These resets are intended to leave the hardware
in a clean state for the next use.
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index 14c073f61c646..afa4bc6cbcc4d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
[ ... ]
> @@ -953,6 +974,8 @@ static int vop2_enable(struct vop2 *vop2)
>
> static void vop2_disable(struct vop2 *vop2)
> {
> + vop2_reset_assert_deassert(vop2, vop2->axi_rst);
> +
> rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
>
> pm_runtime_put_sync(vop2->dev);
[Severity: Medium]
This problem wasn't introduced by this patch, but does the hardware
support having the PM runtime domain disabled before the core clocks?
In vop2_disable(), pm_runtime_put_sync() drops the device's PM reference,
which can power off the domain. However, the core clocks (pclk, aclk, hclk)
are disabled later in vop2_core_clks_disable_unprepare().
Dropping the power domain while functional clocks are still running might
violate hardware teardown sequencing and cause lockups. Since this patch
modifies the disable sequence by adding the reset, could the asymmetry be
corrected here as well?
[ ... ]
> @@ -2596,6 +2621,12 @@ static int vop2_create_crtcs(struct vop2 *vop2)
> return dev_err_probe(drm->dev, PTR_ERR(vp->dclk),
> "failed to get %s\n", dclk_name);
>
> + vp->dclk_rst = devm_reset_control_get_optional_exclusive(vop2->dev,
> + dclk_name);
[Severity: High]
Will this leak the exclusive reset handle if the DRM master is unbound
and later rebound?
Since devm_reset_control_get_optional_exclusive() is tied to the component
device (vop2->dev) rather than the aggregate DRM master device, the devres
allocation won't be released when the component unbind callback executes
because the component device itself isn't removed.
Upon rebind, a second call to this function will find the reset line
already exclusively acquired. This triggers a WARN_ON() in the reset core
and fails the bind with -EBUSY, breaking the driver after an unbind cycle.
[ ... ]
> @@ -2955,6 +2986,13 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
> return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy1),
> "failed to get pll_hdmiphy1\n");
>
> + vop2->axi_rst = devm_reset_control_get_optional_exclusive(vop2->dev, "axi");
[Severity: High]
Similar to the dclk_rst allocation in vop2_create_crtcs(), will allocating
this device-managed resource here in the component bind path cause an
-EBUSY failure on rebind?
> + if (IS_ERR(vop2->axi_rst))
> + return dev_err_probe(drm->dev, PTR_ERR(vop2->axi_rst),
> + "failed to get axi reset\n");
> +
> + vop2_reset_assert_deassert(vop2, vop2->axi_rst);
[Severity: Medium]
Will this synchronous reset be effective if the AXI and AHB clocks are
gated at this point?
The reset pulse is sent immediately after acquiring the handle in
vop2_bind(), but this happens before pm_runtime_enable() is called and
before the core clocks are explicitly prepared and enabled.
If the driver is loaded as a module or probed late, the kernel's unused
clock framework may have already gated the clocks. Pulsing a synchronous
reset while the IP block's clocks are gated usually acts as a silent
no-op. When vop2_enable() later powers on the domain, the hardware might
wake up with its previous dirty state, defeating the purpose of the reset.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-dw-hdmi-qp-yuv-v5-0-6fab0fe43a9b@collabora.com?part=7
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v5 08/15] drm/rockchip: vop2: Avoid DCLK source switch for 10-bit YUV422 output
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Currently the color depth is always factored into the DCLK source
decision for HDMI output, which can break certain modes when operating
with depths greater than 8 bpc.
When the required transmission rate exceeds the 600 MHz limit of the
HDMI PHY PLL, e.g. for 4K@60Hz 10-bit RGB output, VOP2 will normally
fall back to using the less accurate system CRU as a DCLK source,
assuming HDMI 2.1 FRL is supported by the pipeline, otherwise the mode
will be rejected. For YUV420 output format this never happens, as it
uses half of the RGB bandwidth, hence the rate remains within the PHY
PLL limits.
On the other hand, YUV422 always transmits two 12-bit components per
clock cycle, regardless of the color depth, which from a clock-rate
perspective is equivalent to three 8-bit RGB components. For example,
4K@60Hz 10-bit YUV422 requires the same bandwidth as 4K@60Hz 8-bit RGB,
typically 594 MHz. However, VOP2 wrongly assumes it needs 742.5 MHz
(594 * 10 / 8) and ends up switching the DCLK source.
As a consequence, the modes requiring uncommon pixel clocks, such as
those corresponding to fractional refresh rates, will fail. An example
is 3840x2160@59.94Hz, which would likely rely on the 593.407 MHz clock
rate unsupported by the system CRU.
Note this only affects YUV422 with color depths greater than 8 bpc; for
8-bit YUV422 the 8/bpc factor is unity and the bandwidth check is
already correct.
Prevent the incorrect switches of DCLK source to system CRU for YUV422
output format by forcing 8 bpc when checking the bandwidth.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index afa4bc6cbcc4..2fa27028892c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1954,7 +1954,15 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
* to 4K@60Hz, if available, otherwise keep using the system CRU.
*/
if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) {
- unsigned int bpc = vcstate->output_bpc ?: 8;
+ /*
+ * YUV422 always transmits two 12-bit components per clock
+ * cycle, regardless of the color depth, which from a rate
+ * perspective is equivalent to three 8-bit RGB components.
+ * Force 8 bpc here so the bandwidth check reflects the actual
+ * TMDS rate and avoids an unnecessary DCLK source switch.
+ */
+ unsigned int bpc = vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
+ 8 : (vcstate->output_bpc ?: 8);
unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
if (clock <= max_dclk) {
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 08/15] drm/rockchip: vop2: Avoid DCLK source switch for 10-bit YUV422 output
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Currently the color depth is always factored into the DCLK source
decision for HDMI output, which can break certain modes when operating
with depths greater than 8 bpc.
When the required transmission rate exceeds the 600 MHz limit of the
HDMI PHY PLL, e.g. for 4K@60Hz 10-bit RGB output, VOP2 will normally
fall back to using the less accurate system CRU as a DCLK source,
assuming HDMI 2.1 FRL is supported by the pipeline, otherwise the mode
will be rejected. For YUV420 output format this never happens, as it
uses half of the RGB bandwidth, hence the rate remains within the PHY
PLL limits.
On the other hand, YUV422 always transmits two 12-bit components per
clock cycle, regardless of the color depth, which from a clock-rate
perspective is equivalent to three 8-bit RGB components. For example,
4K@60Hz 10-bit YUV422 requires the same bandwidth as 4K@60Hz 8-bit RGB,
typically 594 MHz. However, VOP2 wrongly assumes it needs 742.5 MHz
(594 * 10 / 8) and ends up switching the DCLK source.
As a consequence, the modes requiring uncommon pixel clocks, such as
those corresponding to fractional refresh rates, will fail. An example
is 3840x2160@59.94Hz, which would likely rely on the 593.407 MHz clock
rate unsupported by the system CRU.
Note this only affects YUV422 with color depths greater than 8 bpc; for
8-bit YUV422 the 8/bpc factor is unity and the bandwidth check is
already correct.
Prevent the incorrect switches of DCLK source to system CRU for YUV422
output format by forcing 8 bpc when checking the bandwidth.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index afa4bc6cbcc4..2fa27028892c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1954,7 +1954,15 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
* to 4K@60Hz, if available, otherwise keep using the system CRU.
*/
if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) {
- unsigned int bpc = vcstate->output_bpc ?: 8;
+ /*
+ * YUV422 always transmits two 12-bit components per clock
+ * cycle, regardless of the color depth, which from a rate
+ * perspective is equivalent to three 8-bit RGB components.
+ * Force 8 bpc here so the bandwidth check reflects the actual
+ * TMDS rate and avoids an unnecessary DCLK source switch.
+ */
+ unsigned int bpc = vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
+ 8 : (vcstate->output_bpc ?: 8);
unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
if (clock <= max_dclk) {
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 09/15] drm/rockchip: vop2: Consolidate HDMI PHY PLL clock parent switch
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
The DCLK parent switch logic for HDMI0 and HDMI1 PHY PLLs was
duplicated, with each endpoint repeating the same clk_get_parent(),
clk_set_parent() and error handling calls.
Refactor this by first selecting the appropriate PHY PLL clock handle
based on the active HDMI endpoint, then performing the parent switch in
a single shared code path.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 36 +++++++++++-----------------
1 file changed, 14 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 2fa27028892c..45f3acbfa634 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1964,42 +1964,34 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
unsigned int bpc = vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
8 : (vcstate->output_bpc ?: 8);
unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+ struct clk *pll_hdmiphy = NULL;
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
- if (!vop2->pll_hdmiphy0)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI0 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy0;
break;
}
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI1) {
- if (!vop2->pll_hdmiphy1)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy1);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI1 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy1;
break;
}
}
}
+
+ if (pll_hdmiphy) {
+ if (!vp->dclk_src)
+ vp->dclk_src = clk_get_parent(vp->dclk);
+
+ ret = clk_set_parent(vp->dclk, pll_hdmiphy);
+ if (ret < 0)
+ drm_warn(vop2->drm,
+ "Failed to switch DCLK to HDMI PHY PLL: %d\n",
+ ret);
+ }
}
clk_set_rate(vp->dclk, clock);
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 09/15] drm/rockchip: vop2: Consolidate HDMI PHY PLL clock parent switch
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
The DCLK parent switch logic for HDMI0 and HDMI1 PHY PLLs was
duplicated, with each endpoint repeating the same clk_get_parent(),
clk_set_parent() and error handling calls.
Refactor this by first selecting the appropriate PHY PLL clock handle
based on the active HDMI endpoint, then performing the parent switch in
a single shared code path.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 36 +++++++++++-----------------
1 file changed, 14 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 2fa27028892c..45f3acbfa634 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1964,42 +1964,34 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
unsigned int bpc = vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
8 : (vcstate->output_bpc ?: 8);
unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+ struct clk *pll_hdmiphy = NULL;
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
- if (!vop2->pll_hdmiphy0)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI0 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy0;
break;
}
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI1) {
- if (!vop2->pll_hdmiphy1)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy1);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI1 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy1;
break;
}
}
}
+
+ if (pll_hdmiphy) {
+ if (!vp->dclk_src)
+ vp->dclk_src = clk_get_parent(vp->dclk);
+
+ ret = clk_set_parent(vp->dclk, pll_hdmiphy);
+ if (ret < 0)
+ drm_warn(vop2->drm,
+ "Failed to switch DCLK to HDMI PHY PLL: %d\n",
+ ret);
+ }
}
clk_set_rate(vp->dclk, clock);
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 10/15] drm/rockchip: vop2: Switch to enum vop_csc_format
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Improve code readability in vop2_setup_csc_mode() by using enum
vop_csc_format for the csc_mode variable, as well as for the return type
of the vop2_convert_csc_mode() helper, which already returns CSC_*
enumerators.
While at it, replace the nonsensical 'csc_mode = false' assignment in
the no-conversion branch with the equivalent CSC_BT601L, which carries
the same value (0) but is type-correct.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 45f3acbfa634..1b0f72958763 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -648,7 +648,7 @@ static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win,
}
}
-static int vop2_convert_csc_mode(int csc_mode)
+static enum vop_csc_format vop2_convert_csc_mode(int csc_mode)
{
switch (csc_mode) {
case V4L2_COLORSPACE_SMPTE170M:
@@ -711,7 +711,7 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
int input_csc = V4L2_COLORSPACE_DEFAULT;
int output_csc = vcstate->color_space;
bool r2y_en, y2r_en;
- int csc_mode;
+ enum vop_csc_format csc_mode;
if (is_input_yuv && !is_output_yuv) {
y2r_en = true;
@@ -724,7 +724,7 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
} else {
y2r_en = false;
r2y_en = false;
- csc_mode = false;
+ csc_mode = CSC_BT601L;
}
vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en);
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 10/15] drm/rockchip: vop2: Switch to enum vop_csc_format
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Improve code readability in vop2_setup_csc_mode() by using enum
vop_csc_format for the csc_mode variable, as well as for the return type
of the vop2_convert_csc_mode() helper, which already returns CSC_*
enumerators.
While at it, replace the nonsensical 'csc_mode = false' assignment in
the no-conversion branch with the equivalent CSC_BT601L, which carries
the same value (0) but is type-correct.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 45f3acbfa634..1b0f72958763 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -648,7 +648,7 @@ static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win,
}
}
-static int vop2_convert_csc_mode(int csc_mode)
+static enum vop_csc_format vop2_convert_csc_mode(int csc_mode)
{
switch (csc_mode) {
case V4L2_COLORSPACE_SMPTE170M:
@@ -711,7 +711,7 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
int input_csc = V4L2_COLORSPACE_DEFAULT;
int output_csc = vcstate->color_space;
bool r2y_en, y2r_en;
- int csc_mode;
+ enum vop_csc_format csc_mode;
if (is_input_yuv && !is_output_yuv) {
y2r_en = true;
@@ -724,7 +724,7 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
} else {
y2r_en = false;
r2y_en = false;
- csc_mode = false;
+ csc_mode = CSC_BT601L;
}
vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en);
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 11/15] drm/bridge: dw-hdmi-qp: Log resolution and refresh rate in atomic_enable()
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
The debug entry in the HDMI branch of dw_hdmi_qp_bridge_atomic_enable()
previously printed the literal string 'HDMI' as the mode field, giving
no information about the actual display timing being configured.
Extend it to include the active resolution and refresh rate by
retrieving the CRTC mode from the incoming atomic state:
dw_hdmi_qp_bridge_atomic_enable mode=HDMI:1920x1080@50Hz fmt=RGB rate=185625000 bpc=10
This makes the log line self-contained and directly useful when
debugging mode-setting issues, format negotiation, or TMDS rate
mismatches without having to cross-reference a separate mode dump.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index b268c9376087..c6551f4cbf93 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -539,6 +539,8 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
{
struct dw_hdmi_qp *hdmi = bridge->driver_private;
struct drm_connector_state *conn_state;
+ const struct drm_display_mode *mode;
+ struct drm_crtc_state *crtc_state;
struct drm_connector *connector;
unsigned int op_mode;
int ret;
@@ -552,6 +554,9 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
return;
if (connector->display_info.is_hdmi) {
+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+ mode = &crtc_state->mode;
+
op_mode = 0;
hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
@@ -559,7 +564,10 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
if (ret)
dev_warn(hdmi->dev, "Failed to enable scrambling: %d\n", ret);
- dev_dbg(hdmi->dev, "%s mode=HDMI %s rate=%llu bpc=%u scramb=%d\n", __func__,
+ dev_dbg(hdmi->dev,
+ "%s mode=HDMI:%ux%u@%uHz fmt=%s rate=%llu bpc=%u scramb=%d\n",
+ __func__, mode->hdisplay, mode->vdisplay,
+ drm_mode_vrefresh(mode),
drm_hdmi_connector_get_output_format_name(conn_state->hdmi.output_format),
conn_state->hdmi.tmds_char_rate, conn_state->hdmi.output_bpc,
connector->hdmi.scrambler_enabled);
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 11/15] drm/bridge: dw-hdmi-qp: Log resolution and refresh rate in atomic_enable()
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
The debug entry in the HDMI branch of dw_hdmi_qp_bridge_atomic_enable()
previously printed the literal string 'HDMI' as the mode field, giving
no information about the actual display timing being configured.
Extend it to include the active resolution and refresh rate by
retrieving the CRTC mode from the incoming atomic state:
dw_hdmi_qp_bridge_atomic_enable mode=HDMI:1920x1080@50Hz fmt=RGB rate=185625000 bpc=10
This makes the log line self-contained and directly useful when
debugging mode-setting issues, format negotiation, or TMDS rate
mismatches without having to cross-reference a separate mode dump.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index b268c9376087..c6551f4cbf93 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -539,6 +539,8 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
{
struct dw_hdmi_qp *hdmi = bridge->driver_private;
struct drm_connector_state *conn_state;
+ const struct drm_display_mode *mode;
+ struct drm_crtc_state *crtc_state;
struct drm_connector *connector;
unsigned int op_mode;
int ret;
@@ -552,6 +554,9 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
return;
if (connector->display_info.is_hdmi) {
+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+ mode = &crtc_state->mode;
+
op_mode = 0;
hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
@@ -559,7 +564,10 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
if (ret)
dev_warn(hdmi->dev, "Failed to enable scrambling: %d\n", ret);
- dev_dbg(hdmi->dev, "%s mode=HDMI %s rate=%llu bpc=%u scramb=%d\n", __func__,
+ dev_dbg(hdmi->dev,
+ "%s mode=HDMI:%ux%u@%uHz fmt=%s rate=%llu bpc=%u scramb=%d\n",
+ __func__, mode->hdisplay, mode->vdisplay,
+ drm_mode_vrefresh(mode),
drm_hdmi_connector_get_output_format_name(conn_state->hdmi.output_format),
conn_state->hdmi.tmds_char_rate, conn_state->hdmi.output_bpc,
connector->hdmi.scrambler_enabled);
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 12/15] drm/rockchip: dw_hdmi_qp: Do not mask error code in atomic_check()
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko
dw_hdmi_qp_rockchip_get_vop_format() calls
drm_atomic_get_bridge_state(), which takes the bridge private object
lock through the atomic state's ww acquire context and may therefore
fail with -EDEADLK when the lock is contended.
The DRM core expects -EDEADLK to be propagated up from atomic_check()
so it can drop all held locks and restart the commit. Replacing it
with a hardcoded -EINVAL defeats this backoff mechanism, making
otherwise valid commits fail spuriously when multiple threads perform
atomic commits concurrently.
Propagate the error code returned by the helper instead of
unnecessarily overriding it.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260902230603.AF5C61F000E9@smtp.kernel.org/
Fixes: a18aa0dd7a0b ("drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property")
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index f2a1ea8dfefa..db1933d75ced 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -203,7 +203,7 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
ingest_fmt = dw_hdmi_qp_rockchip_get_vop_format(encoder, conn_state);
if (ingest_fmt < 0)
- return -EINVAL;
+ return ingest_fmt;
if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
s->output_bpc == conn_state->hdmi.output_bpc &&
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 12/15] drm/rockchip: dw_hdmi_qp: Do not mask error code in atomic_check()
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Sashiko
dw_hdmi_qp_rockchip_get_vop_format() calls
drm_atomic_get_bridge_state(), which takes the bridge private object
lock through the atomic state's ww acquire context and may therefore
fail with -EDEADLK when the lock is contended.
The DRM core expects -EDEADLK to be propagated up from atomic_check()
so it can drop all held locks and restart the commit. Replacing it
with a hardcoded -EINVAL defeats this backoff mechanism, making
otherwise valid commits fail spuriously when multiple threads perform
atomic commits concurrently.
Propagate the error code returned by the helper instead of
unnecessarily overriding it.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260902230603.AF5C61F000E9@smtp.kernel.org/
Fixes: a18aa0dd7a0b ("drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property")
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index f2a1ea8dfefa..db1933d75ced 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -203,7 +203,7 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
ingest_fmt = dw_hdmi_qp_rockchip_get_vop_format(encoder, conn_state);
if (ingest_fmt < 0)
- return -EINVAL;
+ return ingest_fmt;
if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
s->output_bpc == conn_state->hdmi.output_bpc &&
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH v5 12/15] drm/rockchip: dw_hdmi_qp: Do not mask error code in atomic_check()
2026-10-13 22:51 ` Cristian Ciocaltea
(?)
@ 2026-10-13 23:04 ` sashiko-bot
-1 siblings, 0 replies; 35+ messages in thread
From: sashiko-bot @ 2026-10-13 23:04 UTC (permalink / raw)
To: Cristian Ciocaltea; +Cc: dri-devel, devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] drm/rockchip: dw_hdmi_qp: state corruption in atomic_check()
--
commit af42e0a2c16e4fdcedcd0540fb2c150fc25ebb0c
Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
drm/rockchip: dw_hdmi_qp: Do not mask error code in atomic_check()
This commit changes dw_hdmi_qp_rockchip_encoder_atomic_check() to
propagate the error code returned by dw_hdmi_qp_rockchip_get_vop_format()
instead of masking it with -EINVAL. This ensures that -EDEADLK can be
propagated up to the DRM core to trigger the ww_mutex backoff mechanism.
Link: https://lore.kernel.org/all/20260902230603.AF5C61F000E9@smtp.kernel.org/
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> index f2a1ea8dfefa5..db1933d75ced5 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> @@ -203,7 +203,7 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
>
> ingest_fmt = dw_hdmi_qp_rockchip_get_vop_format(encoder, conn_state);
> if (ingest_fmt < 0)
> - return -EINVAL;
> + return ingest_fmt;
>
> if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
> s->output_bpc == conn_state->hdmi.output_bpc &&
[Severity: High]
Does this function improperly mutate hardware state during the
validation-only atomic_check phase?
The DRM atomic framework uses atomic_check for configuration validation,
which executes during TEST_ONLY commits that are never applied to hardware.
However, further down in dw_hdmi_qp_rockchip_encoder_atomic_check(), the
code calls phy_configure() and updates global driver state:
ret = phy_configure(hdmi->phy, &phy_cfg);
if (!ret) {
hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
s->output_bpc = conn_state->hdmi.output_bpc;
s->bus_format = ingest_fmt;
} else {
If userspace issues a TEST_ONLY commit with a new mode, the hardware PHY
state and driver tracking (hdmi->tmds_char_rate) are modified to reflect the
test configuration.
If the commit is then aborted, the hardware state and driver tracking become
out of sync.
Could this cause a subsequent valid commit to break display output by
incorrectly skipping the necessary configuration due to the fast-path
check shown in the diff above?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-dw-hdmi-qp-yuv-v5-0-6fab0fe43a9b@collabora.com?part=12
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v5 13/15] drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Rockchip DW HDMI QP encoder supports YUV 4:2:2 output through
ROCKCHIP_OUT_MODE_YUV422, but was limited to 8-bit depth via
MEDIA_BUS_FMT_UYVY8_1X16. Add support for its 10-bit counterpart
MEDIA_BUS_FMT_UYVY10_1X20, which carries two 10-bit components per clock
cycle on a 20-bit wide bus.
YUV 4:2:2 always transmits two 12-bit components per pixel, regardless
of the color depth. From a clock-rate perspective this is equivalent to
three 8-bit RGB components, so configure the HDMI PHY with 8 bpc when
YUV 4:2:2 is in use to keep its output clock aligned with the TMDS
character rate. Otherwise the PHY PLL output would be scaled by bpc/8
for higher color depths, producing a clock rate that confuses downstream
consumers such as the VOP2 display controller.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index db1933d75ced..380dd9ca6870 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -218,6 +218,7 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
break;
case MEDIA_BUS_FMT_UYVY8_1X16:
+ case MEDIA_BUS_FMT_UYVY10_1X20:
s->output_mode = ROCKCHIP_OUT_MODE_YUV422;
break;
case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
@@ -229,7 +230,14 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
}
phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
- phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;
+ /*
+ * YUV422 always transmits two 12-bit components per clock cycle,
+ * regardless of the color depth, which from a rate perspective is
+ * equivalent to three 8-bit RGB components. Force 8 bpc here to
+ * keep the PHY PLL output aligned with the TMDS character rate.
+ */
+ phy_cfg.hdmi.bpc = (s->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
+ 8 : conn_state->hdmi.output_bpc);
ret = phy_configure(hdmi->phy, &phy_cfg);
if (!ret) {
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 13/15] drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Rockchip DW HDMI QP encoder supports YUV 4:2:2 output through
ROCKCHIP_OUT_MODE_YUV422, but was limited to 8-bit depth via
MEDIA_BUS_FMT_UYVY8_1X16. Add support for its 10-bit counterpart
MEDIA_BUS_FMT_UYVY10_1X20, which carries two 10-bit components per clock
cycle on a 20-bit wide bus.
YUV 4:2:2 always transmits two 12-bit components per pixel, regardless
of the color depth. From a clock-rate perspective this is equivalent to
three 8-bit RGB components, so configure the HDMI PHY with 8 bpc when
YUV 4:2:2 is in use to keep its output clock aligned with the TMDS
character rate. Otherwise the PHY PLL output would be scaled by bpc/8
for higher color depths, producing a clock rate that confuses downstream
consumers such as the VOP2 display controller.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index db1933d75ced..380dd9ca6870 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -218,6 +218,7 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
break;
case MEDIA_BUS_FMT_UYVY8_1X16:
+ case MEDIA_BUS_FMT_UYVY10_1X20:
s->output_mode = ROCKCHIP_OUT_MODE_YUV422;
break;
case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
@@ -229,7 +230,14 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
}
phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
- phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;
+ /*
+ * YUV422 always transmits two 12-bit components per clock cycle,
+ * regardless of the color depth, which from a rate perspective is
+ * equivalent to three 8-bit RGB components. Force 8 bpc here to
+ * keep the PHY PLL output aligned with the TMDS character rate.
+ */
+ phy_cfg.hdmi.bpc = (s->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
+ 8 : conn_state->hdmi.output_bpc);
ret = phy_configure(hdmi->phy, &phy_cfg);
if (!ret) {
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH v5 13/15] drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format
2026-10-13 22:51 ` Cristian Ciocaltea
(?)
@ 2026-10-13 23:12 ` sashiko-bot
-1 siblings, 0 replies; 35+ messages in thread
From: sashiko-bot @ 2026-10-13 23:12 UTC (permalink / raw)
To: Cristian Ciocaltea; +Cc: dri-devel, devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] drm/rockchip: dw_hdmi_qp: state leak in atomic_check corrupts PHY bpc configuration
--
commit 197f61f0c784edd007d1f4b375c9dad379eab849
Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format
This patch adds support for 10-bit YUV 4:2:2 output to the Rockchip DW HDMI QP
encoder by using the MEDIA_BUS_FMT_UYVY10_1X20 format. It also forces 8 bpc
when YUV 4:2:2 is used to keep the PHY PLL output aligned with the TMDS
character rate.
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> index db1933d75ced5..380dd9ca6870d 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
[ ... ]
> @@ -229,7 +230,14 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
> }
>
> phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
> - phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;
> + /*
> + * YUV422 always transmits two 12-bit components per clock cycle,
> + * regardless of the color depth, which from a rate perspective is
> + * equivalent to three 8-bit RGB components. Force 8 bpc here to
> + * keep the PHY PLL output aligned with the TMDS character rate.
> + */
> + phy_cfg.hdmi.bpc = (s->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
> + 8 : conn_state->hdmi.output_bpc);
>
> ret = phy_configure(hdmi->phy, &phy_cfg);
> if (!ret) {
[Severity: High]
Does calling phy_configure() in this atomic check function leak test-only
state to the PHY driver?
Because dw_hdmi_qp_rockchip_encoder_atomic_check() executes during
DRM_MODE_ATOMIC_TEST_ONLY commits, calling phy_configure() here updates the
PHY driver's cached state (like hdmi_cfg.bpc) with test configurations. It
also mutates the global encoder state when it sets hdmi->tmds_char_rate on
success.
If a TEST_ONLY commit changes output_bpc while tmds_char_rate remains
unchanged, the new bpc is cached by the PHY.
A subsequent full modeset on the active state could then hit the early
return earlier in this function:
if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
s->output_bpc == conn_state->hdmi.output_bpc &&
s->bus_format == ingest_fmt)
return 0;
This would bypass phy_configure() and allow phy_power_on() to apply the
leaked TEST_ONLY bpc state, potentially desynchronizing the PHY PLLs and
corrupting display output.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-dw-hdmi-qp-yuv-v5-0-6fab0fe43a9b@collabora.com?part=13
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH v5 14/15] drm/rockchip: dw_hdmi_qp: Enable YUV420 output format
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Both RK3576 and RK3588 SoCs are capable of driving the YUV420 output
color format, and the required bus-format handling and VOP2 support are
already in place. Advertise it via the platform supported formats so
the HDMI core can select it.
YUV420 halves the TMDS bandwidth compared to RGB/YUV444, which enables
high-resolution modes such as 4K@60Hz on links that cannot otherwise
carry the full-bandwidth signal.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index 380dd9ca6870..7314ccc975ca 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -648,7 +648,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
plat_data.supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) |
- BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
encoder = &hdmi->encoder.encoder;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 14/15] drm/rockchip: dw_hdmi_qp: Enable YUV420 output format
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Both RK3576 and RK3588 SoCs are capable of driving the YUV420 output
color format, and the required bus-format handling and VOP2 support are
already in place. Advertise it via the platform supported formats so
the HDMI core can select it.
YUV420 halves the TMDS bandwidth compared to RGB/YUV444, which enables
high-resolution modes such as 4K@60Hz on links that cannot otherwise
carry the full-bandwidth signal.
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index 380dd9ca6870..7314ccc975ca 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -648,7 +648,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
plat_data.supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) |
- BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
encoder = &hdmi->encoder.encoder;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [PATCH v5 15/15] arm64: dts: rockchip: Add RK3588 VOP2 resets
2026-10-13 22:51 ` Cristian Ciocaltea
@ 2026-10-13 22:51 ` Cristian Ciocaltea
-1 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Add the missing reset properties to VOP2 on RK3588.
Co-developed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 376ad04e0786..574264b9cd9c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1651,6 +1651,18 @@ vop: vop@fdd90000 {
"pll_hdmiphy0";
iommus = <&vop_mmu>;
power-domains = <&power RK3588_PD_VOP>;
+ resets = <&cru SRST_A_VOP>,
+ <&cru SRST_H_VOP>,
+ <&cru SRST_D_VOP0>,
+ <&cru SRST_D_VOP1>,
+ <&cru SRST_D_VOP2>,
+ <&cru SRST_D_VOP3>;
+ reset-names = "axi",
+ "ahb",
+ "dclk_vp0",
+ "dclk_vp1",
+ "dclk_vp2",
+ "dclk_vp3";
rockchip,grf = <&sys_grf>;
rockchip,vop-grf = <&vop_grf>;
rockchip,vo1-grf = <&vo1_grf>;
--
2.55.0
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH v5 15/15] arm64: dts: rockchip: Add RK3588 VOP2 resets
@ 2026-10-13 22:51 ` Cristian Ciocaltea
0 siblings, 0 replies; 35+ messages in thread
From: Cristian Ciocaltea @ 2026-10-13 22:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Daniel Stone, Philipp Zabel, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Luca Ceresoli, Daniel Stone, Nicolas Frattaroli
Cc: kernel, Andy Yan, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, linux-kernel, Igor Paunovic
Add the missing reset properties to VOP2 on RK3588.
Co-developed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Tested-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 376ad04e0786..574264b9cd9c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1651,6 +1651,18 @@ vop: vop@fdd90000 {
"pll_hdmiphy0";
iommus = <&vop_mmu>;
power-domains = <&power RK3588_PD_VOP>;
+ resets = <&cru SRST_A_VOP>,
+ <&cru SRST_H_VOP>,
+ <&cru SRST_D_VOP0>,
+ <&cru SRST_D_VOP1>,
+ <&cru SRST_D_VOP2>,
+ <&cru SRST_D_VOP3>;
+ reset-names = "axi",
+ "ahb",
+ "dclk_vp0",
+ "dclk_vp1",
+ "dclk_vp2",
+ "dclk_vp3";
rockchip,grf = <&sys_grf>;
rockchip,vop-grf = <&vop_grf>;
rockchip,vo1-grf = <&vo1_grf>;
--
2.55.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 35+ messages in thread