ebeadd64f636b982d65f39ca24c5a57fa53bc322
[openwrt/staging/linusw.git] /
1 From 1dd22d945a99fa35e387e01101c758ae7be3d9a4 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Tue, 15 Dec 2020 16:42:40 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Store pixel frequency in the connector
5 state
6
7 The pixel rate is for now quite simple to compute, but with more features
8 (30 and 36 bits output, YUV output, etc.) will depend on a bunch of
9 connectors properties.
10
11 Let's store the rate we have to run the pixel clock at in our custom
12 connector state, and compute it in atomic_check.
13
14 Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
15 Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
16 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
17 ---
18 drivers/gpu/drm/vc4/vc4_hdmi.c | 26 +++++++++++++++++++++++++-
19 drivers/gpu/drm/vc4/vc4_hdmi.h | 1 +
20 2 files changed, 26 insertions(+), 1 deletion(-)
21
22 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
23 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
24 @@ -242,6 +242,7 @@ vc4_hdmi_connector_duplicate_state(struc
25 if (!new_state)
26 return NULL;
27
28 + new_state->pixel_rate = vc4_state->pixel_rate;
29 __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
30
31 return &new_state->base;
32 @@ -668,9 +669,29 @@ static void vc4_hdmi_recenter_fifo(struc
33 "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
34 }
35
36 +static struct drm_connector_state *
37 +vc4_hdmi_encoder_get_connector_state(struct drm_encoder *encoder,
38 + struct drm_atomic_state *state)
39 +{
40 + struct drm_connector_state *conn_state;
41 + struct drm_connector *connector;
42 + unsigned int i;
43 +
44 + for_each_new_connector_in_state(state, connector, conn_state, i) {
45 + if (conn_state->best_encoder == encoder)
46 + return conn_state;
47 + }
48 +
49 + return NULL;
50 +}
51 +
52 static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
53 struct drm_atomic_state *state)
54 {
55 + struct drm_connector_state *conn_state =
56 + vc4_hdmi_encoder_get_connector_state(encoder, state);
57 + struct vc4_hdmi_connector_state *vc4_conn_state =
58 + conn_state_to_vc4_hdmi_conn_state(conn_state);
59 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
60 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
61 unsigned long pixel_rate, hsm_rate;
62 @@ -682,7 +703,7 @@ static void vc4_hdmi_encoder_pre_crtc_co
63 return;
64 }
65
66 - pixel_rate = mode->clock * 1000 * ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1);
67 + pixel_rate = vc4_conn_state->pixel_rate;
68 ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
69 if (ret) {
70 DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
71 @@ -844,6 +865,7 @@ static int vc4_hdmi_encoder_atomic_check
72 struct drm_crtc_state *crtc_state,
73 struct drm_connector_state *conn_state)
74 {
75 + struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
76 struct drm_display_mode *mode = &crtc_state->adjusted_mode;
77 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
78 unsigned long long pixel_rate = mode->clock * 1000;
79 @@ -874,6 +896,8 @@ static int vc4_hdmi_encoder_atomic_check
80 if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
81 return -EINVAL;
82
83 + vc4_state->pixel_rate = pixel_rate;
84 +
85 return 0;
86 }
87
88 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
89 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
90 @@ -189,6 +189,7 @@ encoder_to_vc4_hdmi(struct drm_encoder *
91
92 struct vc4_hdmi_connector_state {
93 struct drm_connector_state base;
94 + unsigned long long pixel_rate;
95 };
96
97 static inline struct vc4_hdmi_connector_state *