Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/connector: hdmi: Calculate TMDS character rate

Most HDMI drivers have some code to calculate the TMDS character rate,
usually to adjust an internal clock to match what the mode requires.

Since the TMDS character rates mostly depends on the resolution, whether
we need to repeat pixels or not, the bpc count and the format, we can
now derive it from the HDMI connector state that stores all those infos
and remove the duplication from drivers.

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-11-c5af16c3aae2@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>

+76
+67
drivers/gpu/drm/display/drm_hdmi_state_helper.c
··· 3 3 #include <drm/drm_atomic.h> 4 4 #include <drm/drm_connector.h> 5 5 6 + #include <drm/display/drm_hdmi_helper.h> 6 7 #include <drm/display/drm_hdmi_state_helper.h> 7 8 8 9 /** ··· 26 25 } 27 26 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); 28 27 28 + static const struct drm_display_mode * 29 + connector_state_get_mode(const struct drm_connector_state *conn_state) 30 + { 31 + struct drm_atomic_state *state; 32 + struct drm_crtc_state *crtc_state; 33 + struct drm_crtc *crtc; 34 + 35 + state = conn_state->state; 36 + if (!state) 37 + return NULL; 38 + 39 + crtc = conn_state->crtc; 40 + if (!crtc) 41 + return NULL; 42 + 43 + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 44 + if (!crtc_state) 45 + return NULL; 46 + 47 + return &crtc_state->mode; 48 + } 49 + 50 + static enum drm_mode_status 51 + hdmi_clock_valid(const struct drm_connector *connector, 52 + const struct drm_display_mode *mode, 53 + unsigned long long clock) 54 + { 55 + const struct drm_display_info *info = &connector->display_info; 56 + 57 + if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000) 58 + return MODE_CLOCK_HIGH; 59 + 60 + return MODE_OK; 61 + } 62 + 63 + static int 64 + hdmi_compute_clock(const struct drm_connector *connector, 65 + struct drm_connector_state *conn_state, 66 + const struct drm_display_mode *mode, 67 + unsigned int bpc, enum hdmi_colorspace fmt) 68 + { 69 + enum drm_mode_status status; 70 + unsigned long long clock; 71 + 72 + clock = drm_hdmi_compute_mode_clock(mode, bpc, fmt); 73 + if (!clock) 74 + return -EINVAL; 75 + 76 + status = hdmi_clock_valid(connector, mode, clock); 77 + if (status != MODE_OK) 78 + return -EINVAL; 79 + 80 + conn_state->hdmi.tmds_char_rate = clock; 81 + 82 + return 0; 83 + } 84 + 29 85 /** 30 86 * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state 31 87 * @connector: DRM Connector ··· 102 44 drm_atomic_get_old_connector_state(state, connector); 103 45 struct drm_connector_state *new_conn_state = 104 46 drm_atomic_get_new_connector_state(state, connector); 47 + const struct drm_display_mode *mode = 48 + connector_state_get_mode(new_conn_state); 49 + int ret; 50 + 51 + ret = hdmi_compute_clock(connector, new_conn_state, mode, 52 + new_conn_state->hdmi.output_bpc, 53 + new_conn_state->hdmi.output_format); 54 + if (ret) 55 + return ret; 105 56 106 57 if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc || 107 58 old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) {
+1
drivers/gpu/drm/drm_atomic.c
··· 1148 1148 drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); 1149 1149 drm_printf(p, "\toutput_format=%s\n", 1150 1150 drm_hdmi_connector_get_output_format_name(state->hdmi.output_format)); 1151 + drm_printf(p, "\ttmds_char_rate=%llu\n", state->hdmi.tmds_char_rate); 1151 1152 } 1152 1153 1153 1154 if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+3
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
··· 72 72 conn_state = drm_atomic_get_connector_state(state, connector); 73 73 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 74 74 75 + conn_state->hdmi.output_bpc = connector->max_bpc; 76 + conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB; 77 + 75 78 ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); 76 79 KUNIT_EXPECT_EQ(test, ret, 0); 77 80
+5
include/drm/drm_connector.h
··· 1049 1049 * @output_format: Pixel format to output in. 1050 1050 */ 1051 1051 enum hdmi_colorspace output_format; 1052 + 1053 + /** 1054 + * @tmds_char_rate: TMDS Character Rate, in Hz. 1055 + */ 1056 + unsigned long long tmds_char_rate; 1052 1057 } hdmi; 1053 1058 }; 1054 1059