1 From bb968f8f963e28d00fff213c62a2449c45ff19f4 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Thu, 6 May 2021 17:15:57 +0200
4 Subject: [PATCH] drm/vc4: crtc: Lookup the encoder from the register
7 At boot, we can't rely on the vc4_get_crtc_encoder since we don't have a
8 state yet and thus will not be able to figure out which connector is
11 However, we have a muxing bit in the CRTC register we can use to get the
12 encoder currently connected to the pixelvalve. We can thus read that
13 register, lookup the associated register through the vc4_pv_data
14 structure, and then pass it to vc4_crtc_disable so that we can perform
15 the proper operations.
17 Fixes: 875a4d536842 ("drm/vc4: drv: Disable the CRTC at boot time")
18 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
20 drivers/gpu/drm/vc4/vc4_crtc.c | 38 ++++++++++++++++++++++++++++++----
21 1 file changed, 34 insertions(+), 4 deletions(-)
23 --- a/drivers/gpu/drm/vc4/vc4_crtc.c
24 +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
25 @@ -431,11 +431,10 @@ static void require_hvs_enabled(struct d
28 static int vc4_crtc_disable(struct drm_crtc *crtc,
29 + struct drm_encoder *encoder,
30 struct drm_atomic_state *state,
33 - struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state,
34 - drm_atomic_get_old_connector_state);
35 struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
36 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
37 struct drm_device *dev = crtc->dev;
38 @@ -476,10 +475,29 @@ static int vc4_crtc_disable(struct drm_c
42 +static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc *crtc,
43 + enum vc4_encoder_type type)
45 + struct drm_encoder *encoder;
47 + drm_for_each_encoder(encoder, crtc->dev) {
48 + struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
50 + if (vc4_encoder->type == type)
57 int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
59 struct drm_device *drm = crtc->dev;
60 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
61 + enum vc4_encoder_type encoder_type;
62 + const struct vc4_pv_data *pv_data;
63 + struct drm_encoder *encoder;
64 + unsigned encoder_sel;
67 if (!(of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
68 @@ -498,7 +516,17 @@ int vc4_crtc_disable_at_boot(struct drm_
72 - return vc4_crtc_disable(crtc, NULL, channel);
73 + encoder_sel = VC4_GET_FIELD(CRTC_READ(PV_CONTROL), PV_CONTROL_CLK_SELECT);
74 + if (WARN_ON(encoder_sel != 0))
77 + pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
78 + encoder_type = pv_data->encoder_types[encoder_sel];
79 + encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type);
80 + if (WARN_ON(!encoder))
83 + return vc4_crtc_disable(crtc, encoder, NULL, channel);
86 static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
87 @@ -507,6 +535,8 @@ static void vc4_crtc_atomic_disable(stru
88 struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
90 struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state);
91 + struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state,
92 + drm_atomic_get_old_connector_state);
93 struct drm_device *dev = crtc->dev;
95 require_hvs_enabled(dev);
96 @@ -514,7 +544,7 @@ static void vc4_crtc_atomic_disable(stru
97 /* Disable vblank irq handling before crtc is disabled. */
98 drm_crtc_vblank_off(crtc);
100 - vc4_crtc_disable(crtc, state, old_vc4_state->assigned_channel);
101 + vc4_crtc_disable(crtc, encoder, state, old_vc4_state->assigned_channel);
104 * Make sure we issue a vblank event after disabling the CRTC if