31ffe4d5d477b05759034275817dc512c8f0001f
[openwrt/staging/jow.git] / target / linux / bcm27xx / patches-5.10 / 950-0414-drm-vc4-hdmi-Create-a-custom-connector-state.patch
1 From e072b2d845ff91716d630f4d2a105bf63698cfe1 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Tue, 15 Dec 2020 16:42:39 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Create a custom connector state
5
6 When run with a higher bpc than 8, the clock of the HDMI controller needs
7 to be adjusted. Let's create a connector state that will be used at
8 atomic_check and atomic_enable to compute and store the clock rate
9 associated to the state.
10
11 Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
12 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
13 Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
14 ---
15 drivers/gpu/drm/vc4/vc4_hdmi.c | 33 ++++++++++++++++++++++++++++++---
16 drivers/gpu/drm/vc4/vc4_hdmi.h | 10 ++++++++++
17 2 files changed, 40 insertions(+), 3 deletions(-)
18
19 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
20 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
21 @@ -214,10 +214,37 @@ static int vc4_hdmi_connector_get_modes(
22
23 static void vc4_hdmi_connector_reset(struct drm_connector *connector)
24 {
25 - drm_atomic_helper_connector_reset(connector);
26 + struct vc4_hdmi_connector_state *old_state =
27 + conn_state_to_vc4_hdmi_conn_state(connector->state);
28 + struct vc4_hdmi_connector_state *new_state =
29 + kzalloc(sizeof(*new_state), GFP_KERNEL);
30
31 if (connector->state)
32 - drm_atomic_helper_connector_tv_reset(connector);
33 + __drm_atomic_helper_connector_destroy_state(connector->state);
34 +
35 + kfree(old_state);
36 + __drm_atomic_helper_connector_reset(connector, &new_state->base);
37 +
38 + if (!new_state)
39 + return;
40 +
41 + drm_atomic_helper_connector_tv_reset(connector);
42 +}
43 +
44 +static struct drm_connector_state *
45 +vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
46 +{
47 + struct drm_connector_state *conn_state = connector->state;
48 + struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
49 + struct vc4_hdmi_connector_state *new_state;
50 +
51 + new_state = kzalloc(sizeof(*new_state), GFP_KERNEL);
52 + if (!new_state)
53 + return NULL;
54 +
55 + __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
56 +
57 + return &new_state->base;
58 }
59
60 static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
61 @@ -225,7 +252,7 @@ static const struct drm_connector_funcs
62 .fill_modes = drm_helper_probe_single_connector_modes,
63 .destroy = vc4_hdmi_connector_destroy,
64 .reset = vc4_hdmi_connector_reset,
65 - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
66 + .atomic_duplicate_state = vc4_hdmi_connector_duplicate_state,
67 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
68 };
69
70 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
71 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
72 @@ -187,6 +187,16 @@ encoder_to_vc4_hdmi(struct drm_encoder *
73 return container_of(_encoder, struct vc4_hdmi, encoder);
74 }
75
76 +struct vc4_hdmi_connector_state {
77 + struct drm_connector_state base;
78 +};
79 +
80 +static inline struct vc4_hdmi_connector_state *
81 +conn_state_to_vc4_hdmi_conn_state(struct drm_connector_state *conn_state)
82 +{
83 + return container_of(conn_state, struct vc4_hdmi_connector_state, base);
84 +}
85 +
86 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
87 struct drm_display_mode *mode);
88 void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);