struct drm_connector *connector = &vc4_hdmi->connector;
struct drm_connector_state *old_conn_state = drm_atomic_get_old_connector_state(conn_state->state, connector);
struct vc4_hdmi_connector_state *old_vc4_state = conn_state_to_vc4_hdmi_conn_state(old_conn_state);
+ struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
unsigned long long pixel_rate = mode->clock * 1000;
unsigned long long tmds_rate;
int ret;
return -EINVAL;
}
+ /* 4096x2160@60 is not reliable without overclocking core */
+ if (mode->hdisplay > 3840 && mode->vdisplay >= 2160 &&
+ drm_mode_vrefresh(mode) >= 50 &&
+ !vc4->hvs->vc5_hdmi_enable_4096by2160)
+ return -EINVAL;
+
/*
* The 1440p@60 pixel rate is in the same range than the first
* WiFi channel (between 2.4GHz and 2.422GHz with 22MHz
const struct drm_display_mode *mode)
{
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+ const struct drm_connector *connector = &vc4_hdmi->connector;
+ struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
if (vc4_hdmi->variant->unsupported_odd_h_timings &&
!(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
(mode->hsync_end % 2) || (mode->htotal % 2)))
return MODE_H_ILLEGAL;
+ if (mode->hdisplay > 3840 && mode->vdisplay >= 2160 &&
+ drm_mode_vrefresh(mode) >= 50 &&
+ !vc4->hvs->vc5_hdmi_enable_4096by2160)
+ return MODE_CLOCK_HIGH;
+
return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode->clock * 1000);
}
hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
if (vc4->is_vc5) {
+ unsigned long min_rate;
unsigned long max_rate;
hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
if (max_rate >= 550000000)
hvs->vc5_hdmi_enable_scrambling = true;
+ min_rate = clk_get_min_rate(hvs->core_clk);
+ if (min_rate >= 600000000)
+ hvs->vc5_hdmi_enable_4096by2160 = true;
+
ret = clk_prepare_enable(hvs->core_clk);
if (ret) {
dev_err(&pdev->dev, "Couldn't enable the core clock\n");