[PATCH v6 11/18] drm/bridge: inno-hdmi: Add .mode_valid platform operation
Michal Wilczynski
m.wilczynski at samsung.com
Thu Oct 29 00:53:45 PDT 2026
inno_hdmi_bridge_mode_valid() validates the pixel clock against
hdmi->refclk, but that clock is optional and is only present on
platforms that describe a "ref" clock. Platforms where the pixel clock
is produced by a separate device - such as the StarFive JH7110, whose
PHY is both the clock and the PHY provider - have no "ref" clock, so
the check is skipped entirely and every mode is reported as valid.
A mode the platform cannot generate is then advertised to userspace.
The subsequent modeset appears to succeed, since the atomic enable path
cannot fail, and the display silently stays blank.
Add a .mode_valid platform operation so platforms can reject modes they
are unable to drive. Platforms that do not implement it are unaffected.
Reviewed-by: Joshua Peisach <jpeisach at ubuntu.com>
Tested-by: Byron Stanoszek <gandalf at winds.org>
Tested-by: OOHehir <oo.hehir at gmail.com>
Signed-off-by: Michal Wilczynski <m.wilczynski at samsung.com>
---
drivers/gpu/drm/bridge/inno-hdmi.c | 9 +++++++++
include/drm/bridge/inno_hdmi.h | 5 ++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/inno-hdmi.c b/drivers/gpu/drm/bridge/inno-hdmi.c
index 708d4c03f8880429f99680abd0c92e150312237b..2684a3cc5667ce133357dccb8d214806db27f863 100644
--- a/drivers/gpu/drm/bridge/inno-hdmi.c
+++ b/drivers/gpu/drm/bridge/inno-hdmi.c
@@ -823,6 +823,7 @@ static enum drm_mode_status inno_hdmi_bridge_mode_valid(struct drm_bridge *bridg
const struct drm_display_mode *mode)
{
struct inno_hdmi *hdmi = bridge_to_inno_hdmi(bridge);
+ const struct inno_hdmi_plat_ops *plat_ops = hdmi->plat_data->ops;
unsigned long mpixelclk, max_tolerance;
long rounded_refclk;
@@ -838,6 +839,14 @@ static enum drm_mode_status inno_hdmi_bridge_mode_valid(struct drm_bridge *bridg
if (inno_hdmi_find_phy_config(hdmi, mpixelclk) < 0)
return MODE_CLOCK_HIGH;
+ if (plat_ops && plat_ops->mode_valid) {
+ enum drm_mode_status status;
+
+ status = plat_ops->mode_valid(hdmi->dev, mode);
+ if (status != MODE_OK)
+ return status;
+ }
+
if (hdmi->refclk) {
rounded_refclk = clk_round_rate(hdmi->refclk, mpixelclk);
if (rounded_refclk < 0)
diff --git a/include/drm/bridge/inno_hdmi.h b/include/drm/bridge/inno_hdmi.h
index 0864f0d8862a4325821a84db6d04f14011d9aa78..790633fcea97a6b9840da7b19a0c0b0d7271fb83 100644
--- a/include/drm/bridge/inno_hdmi.h
+++ b/include/drm/bridge/inno_hdmi.h
@@ -8,15 +8,18 @@
#include <linux/types.h>
+#include <drm/drm_modes.h>
+
struct device;
struct drm_encoder;
-struct drm_display_mode;
struct inno_hdmi;
struct platform_device;
struct inno_hdmi_plat_ops {
void (*enable)(struct device *pdev, struct drm_display_mode *mode);
void (*disable)(struct device *pdev);
+ enum drm_mode_status (*mode_valid)(struct device *pdev,
+ const struct drm_display_mode *mode);
};
struct inno_hdmi_phy_config {
--
2.34.1
More information about the linux-arm-kernel
mailing list