Skip to content

Commit c2b8a19

Browse files
popcornmixmripard
authored andcommitted
kms/vc4_hdmi: Refuse 4096x2160@60 hdmi modes
These are no reliable without overclocking. See: raspberrypi/linux#5034 Signed-off-by: Dom Cobley <[email protected]>
1 parent bf84409 commit c2b8a19

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,12 @@ struct vc4_hvs {
342342
struct drm_mm_node mitchell_netravali_filter;
343343

344344
struct debugfs_regset32 regset;
345+
346+
/*
347+
* 4096x2160@60 requires a core overclock to work, so register
348+
* whether that is sufficient.
349+
*/
350+
bool vc5_hdmi_enable_4096by2160;
345351
};
346352

347353
struct vc4_plane {

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,7 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
20892089
struct drm_crtc_state *crtc_state,
20902090
struct drm_connector_state *conn_state)
20912091
{
2092+
struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
20922093
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
20932094
struct drm_connector *connector = &vc4_hdmi->connector;
20942095
struct drm_connector_state *old_conn_state =
@@ -2121,6 +2122,12 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
21212122
return -EINVAL;
21222123
}
21232124

2125+
/* 4096x2160@60 is not reliable without overclocking core */
2126+
if (mode->hdisplay > 3840 && mode->vdisplay >= 2160 &&
2127+
drm_mode_vrefresh(mode) >= 50 &&
2128+
!vc4->hvs->vc5_hdmi_enable_4096by2160)
2129+
return -EINVAL;
2130+
21242131
/*
21252132
* The 1440p@60 pixel rate is in the same range than the first
21262133
* WiFi channel (between 2.4GHz and 2.422GHz with 22MHz
@@ -2152,13 +2159,20 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
21522159
const struct drm_display_mode *mode)
21532160
{
21542161
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
2162+
const struct drm_connector *connector = &vc4_hdmi->connector;
2163+
struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
21552164

21562165
if (vc4_hdmi->variant->unsupported_odd_h_timings &&
21572166
!(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
21582167
((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
21592168
(mode->hsync_end % 2) || (mode->htotal % 2)))
21602169
return MODE_H_ILLEGAL;
21612170

2171+
if (mode->hdisplay > 3840 && mode->vdisplay >= 2160 &&
2172+
drm_mode_vrefresh(mode) >= 50 &&
2173+
!vc4->hvs->vc5_hdmi_enable_4096by2160)
2174+
return MODE_CLOCK_HIGH;
2175+
21622176
return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode->clock * 1000);
21632177
}
21642178

drivers/gpu/drm/vc4/vc4_hvs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,12 +1022,18 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
10221022
hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
10231023

10241024
if (vc4->is_vc5) {
1025+
unsigned long min_rate;
1026+
10251027
hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
10261028
if (IS_ERR(hvs->core_clk)) {
10271029
dev_err(&pdev->dev, "Couldn't get core clock\n");
10281030
return PTR_ERR(hvs->core_clk);
10291031
}
10301032

1033+
min_rate = rpi_firmware_clk_get_min_rate(hvs->core_clk);
1034+
if (min_rate >= 600000000)
1035+
hvs->vc5_hdmi_enable_4096by2160 = true;
1036+
10311037
ret = clk_prepare_enable(hvs->core_clk);
10321038
if (ret) {
10331039
dev_err(&pdev->dev, "Couldn't enable the core clock\n");

0 commit comments

Comments
 (0)