bcm27xx: update patches from RPi foundation
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0574-drm-vc4-hdmi-rework-connectors-and-encoders.patch
1 From 50e7e810cf403c4b217c68c8ae2544d16f8063d1 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Mon, 6 Jan 2020 17:17:29 +0100
4 Subject: [PATCH] drm/vc4: hdmi: rework connectors and encoders
5
6 the vc4_hdmi driver has some custom structures to hold the data it needs to
7 associate with the drm_encoder and drm_connector structures.
8
9 However, it allocates them separately from the vc4_hdmi structure which
10 makes it more complicated than it needs to be.
11
12 Move those structures to be contained by vc4_hdmi and update the code
13 accordingly.
14
15 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
16 ---
17  drivers/gpu/drm/vc4/vc4_hdmi.c | 84 ++++++++++++++++------------------
18  drivers/gpu/drm/vc4/vc4_hdmi.h | 64 +++++++++++++-------------
19  2 files changed, 71 insertions(+), 77 deletions(-)
20
21 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
22 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
23 @@ -190,19 +190,14 @@ static const struct drm_connector_helper
24         .get_modes = vc4_hdmi_connector_get_modes,
25  };
26  
27 -static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
28 -                                                    struct drm_encoder *encoder)
29 +static int vc4_hdmi_connector_init(struct drm_device *dev,
30 +                                  struct vc4_hdmi *vc4_hdmi)
31  {
32 -       struct drm_connector *connector;
33 -       struct vc4_hdmi_connector *hdmi_connector;
34 +       struct vc4_hdmi_connector *hdmi_connector = &vc4_hdmi->connector;
35 +       struct drm_connector *connector = &hdmi_connector->base;
36 +       struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
37         int ret;
38  
39 -       hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
40 -                                     GFP_KERNEL);
41 -       if (!hdmi_connector)
42 -               return ERR_PTR(-ENOMEM);
43 -       connector = &hdmi_connector->base;
44 -
45         hdmi_connector->encoder = encoder;
46  
47         drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
48 @@ -212,7 +207,7 @@ static struct drm_connector *vc4_hdmi_co
49         /* Create and attach TV margin props to this connector. */
50         ret = drm_mode_create_tv_margin_properties(dev);
51         if (ret)
52 -               return ERR_PTR(ret);
53 +               return ret;
54  
55         drm_connector_attach_tv_margin_properties(connector);
56  
57 @@ -224,7 +219,7 @@ static struct drm_connector *vc4_hdmi_co
58  
59         drm_connector_attach_encoder(connector, encoder);
60  
61 -       return connector;
62 +       return 0;
63  }
64  
65  static void vc4_hdmi_encoder_destroy(struct drm_encoder *encoder)
66 @@ -303,21 +298,22 @@ static void vc4_hdmi_set_avi_infoframe(s
67         struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
68         struct vc4_dev *vc4 = encoder->dev->dev_private;
69         struct vc4_hdmi *hdmi = vc4->hdmi;
70 -       struct drm_connector_state *cstate = hdmi->connector->state;
71 +       struct drm_connector *connector = &hdmi->connector.base;
72 +       struct drm_connector_state *cstate = connector->state;
73         struct drm_crtc *crtc = encoder->crtc;
74         const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
75         union hdmi_infoframe frame;
76         int ret;
77  
78         ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
79 -                                                      hdmi->connector, mode);
80 +                                                      connector, mode);
81         if (ret < 0) {
82                 DRM_ERROR("couldn't fill AVI infoframe\n");
83                 return;
84         }
85  
86         drm_hdmi_avi_infoframe_quant_range(&frame.avi,
87 -                                          hdmi->connector, mode,
88 +                                          connector, mode,
89                                            vc4_encoder->limited_rgb_range ?
90                                            HDMI_QUANTIZATION_RANGE_LIMITED :
91                                            HDMI_QUANTIZATION_RANGE_FULL);
92 @@ -636,7 +632,8 @@ static const struct drm_encoder_helper_f
93  /* HDMI audio codec callbacks */
94  static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
95  {
96 -       struct drm_device *drm = hdmi->encoder->dev;
97 +       struct drm_encoder *encoder = &hdmi->encoder.base.base;
98 +       struct drm_device *drm = encoder->dev;
99         struct vc4_dev *vc4 = to_vc4_dev(drm);
100         u32 hsm_clock = clk_get_rate(hdmi->hsm_clock);
101         unsigned long n, m;
102 @@ -655,7 +652,7 @@ static void vc4_hdmi_audio_set_mai_clock
103  
104  static void vc4_hdmi_set_n_cts(struct vc4_hdmi *hdmi)
105  {
106 -       struct drm_encoder *encoder = hdmi->encoder;
107 +       struct drm_encoder *encoder = &hdmi->encoder.base.base;
108         struct drm_crtc *crtc = encoder->crtc;
109         struct drm_device *drm = encoder->dev;
110         struct vc4_dev *vc4 = to_vc4_dev(drm);
111 @@ -693,7 +690,8 @@ static int vc4_hdmi_audio_startup(struct
112                                   struct snd_soc_dai *dai)
113  {
114         struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
115 -       struct drm_encoder *encoder = hdmi->encoder;
116 +       struct drm_encoder *encoder = &hdmi->encoder.base.base;
117 +       struct drm_connector *connector = &hdmi->connector.base;
118         struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
119         int ret;
120  
121 @@ -710,8 +708,7 @@ static int vc4_hdmi_audio_startup(struct
122                                 VC4_HDMI_RAM_PACKET_ENABLE))
123                 return -ENODEV;
124  
125 -       ret = snd_pcm_hw_constraint_eld(substream->runtime,
126 -                                       hdmi->connector->eld);
127 +       ret = snd_pcm_hw_constraint_eld(substream->runtime, connector->eld);
128         if (ret)
129                 return ret;
130  
131 @@ -725,7 +722,7 @@ static int vc4_hdmi_audio_set_fmt(struct
132  
133  static void vc4_hdmi_audio_reset(struct vc4_hdmi *hdmi)
134  {
135 -       struct drm_encoder *encoder = hdmi->encoder;
136 +       struct drm_encoder *encoder = &hdmi->encoder.base.base;
137         struct drm_device *drm = encoder->dev;
138         struct device *dev = &hdmi->pdev->dev;
139         struct vc4_dev *vc4 = to_vc4_dev(drm);
140 @@ -759,7 +756,7 @@ static int vc4_hdmi_audio_hw_params(stru
141                                     struct snd_soc_dai *dai)
142  {
143         struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
144 -       struct drm_encoder *encoder = hdmi->encoder;
145 +       struct drm_encoder *encoder = &hdmi->encoder.base.base;
146         struct drm_device *drm = encoder->dev;
147         struct device *dev = &hdmi->pdev->dev;
148         struct vc4_dev *vc4 = to_vc4_dev(drm);
149 @@ -832,7 +829,7 @@ static int vc4_hdmi_audio_trigger(struct
150                                   struct snd_soc_dai *dai)
151  {
152         struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
153 -       struct drm_encoder *encoder = hdmi->encoder;
154 +       struct drm_encoder *encoder = &hdmi->encoder.base.base;
155         struct drm_device *drm = encoder->dev;
156         struct vc4_dev *vc4 = to_vc4_dev(drm);
157  
158 @@ -876,9 +873,10 @@ static int vc4_hdmi_audio_eld_ctl_info(s
159  {
160         struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
161         struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
162 +       struct drm_connector *connector = &hdmi->connector.base;
163  
164         uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
165 -       uinfo->count = sizeof(hdmi->connector->eld);
166 +       uinfo->count = sizeof(connector->eld);
167  
168         return 0;
169  }
170 @@ -888,9 +886,10 @@ static int vc4_hdmi_audio_eld_ctl_get(st
171  {
172         struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
173         struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
174 +       struct drm_connector *connector = &hdmi->connector.base;
175  
176 -       memcpy(ucontrol->value.bytes.data, hdmi->connector->eld,
177 -              sizeof(hdmi->connector->eld));
178 +       memcpy(ucontrol->value.bytes.data, connector->eld,
179 +              sizeof(connector->eld));
180  
181         return 0;
182  }
183 @@ -1230,7 +1229,7 @@ static int vc4_hdmi_bind(struct device *
184         struct drm_device *drm = dev_get_drvdata(master);
185         struct vc4_dev *vc4 = drm->dev_private;
186         struct vc4_hdmi *hdmi;
187 -       struct vc4_hdmi_encoder *vc4_hdmi_encoder;
188 +       struct drm_encoder *encoder;
189         struct device_node *ddc_node;
190         u32 value;
191         int ret;
192 @@ -1239,14 +1238,10 @@ static int vc4_hdmi_bind(struct device *
193         if (!hdmi)
194                 return -ENOMEM;
195  
196 -       vc4_hdmi_encoder = devm_kzalloc(dev, sizeof(*vc4_hdmi_encoder),
197 -                                       GFP_KERNEL);
198 -       if (!vc4_hdmi_encoder)
199 -               return -ENOMEM;
200 -       vc4_hdmi_encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
201 -       hdmi->encoder = &vc4_hdmi_encoder->base.base;
202 -
203         hdmi->pdev = pdev;
204 +       encoder = &hdmi->encoder.base.base;
205 +       encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
206 +
207         hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
208         if (IS_ERR(hdmi->hdmicore_regs))
209                 return PTR_ERR(hdmi->hdmicore_regs);
210 @@ -1332,15 +1327,14 @@ static int vc4_hdmi_bind(struct device *
211         }
212         pm_runtime_enable(dev);
213  
214 -       drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
215 +       drm_encoder_init(drm, encoder, &vc4_hdmi_encoder_funcs,
216                          DRM_MODE_ENCODER_TMDS, NULL);
217 -       drm_encoder_helper_add(hdmi->encoder, &vc4_hdmi_encoder_helper_funcs);
218 +       drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
219  
220 -       hdmi->connector = vc4_hdmi_connector_init(drm, hdmi->encoder);
221 -       if (IS_ERR(hdmi->connector)) {
222 -               ret = PTR_ERR(hdmi->connector);
223 +       ret = vc4_hdmi_connector_init(drm, hdmi);
224 +       if (ret)
225                 goto err_destroy_encoder;
226 -       }
227 +
228  #ifdef CONFIG_DRM_VC4_HDMI_CEC
229         hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
230                                               vc4, "vc4",
231 @@ -1350,7 +1344,7 @@ static int vc4_hdmi_bind(struct device *
232         if (ret < 0)
233                 goto err_destroy_conn;
234  
235 -       cec_fill_conn_info_from_drm(&conn_info, hdmi->connector);
236 +       cec_fill_conn_info_from_drm(&conn_info, &hdmi->connector.base);
237         cec_s_conn_info(hdmi->cec_adap, &conn_info);
238  
239         HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
240 @@ -1387,10 +1381,10 @@ static int vc4_hdmi_bind(struct device *
241  err_delete_cec_adap:
242         cec_delete_adapter(hdmi->cec_adap);
243  err_destroy_conn:
244 -       vc4_hdmi_connector_destroy(hdmi->connector);
245 +       vc4_hdmi_connector_destroy(&hdmi->connector.base);
246  #endif
247  err_destroy_encoder:
248 -       vc4_hdmi_encoder_destroy(hdmi->encoder);
249 +       vc4_hdmi_encoder_destroy(encoder);
250  err_unprepare_hsm:
251         clk_disable_unprepare(hdmi->hsm_clock);
252         pm_runtime_disable(dev);
253 @@ -1408,8 +1402,8 @@ static void vc4_hdmi_unbind(struct devic
254         struct vc4_hdmi *hdmi = vc4->hdmi;
255  
256         cec_unregister_adapter(hdmi->cec_adap);
257 -       vc4_hdmi_connector_destroy(hdmi->connector);
258 -       vc4_hdmi_encoder_destroy(hdmi->encoder);
259 +       vc4_hdmi_connector_destroy(&hdmi->connector.base);
260 +       vc4_hdmi_encoder_destroy(&hdmi->encoder.base.base);
261  
262         clk_disable_unprepare(hdmi->hsm_clock);
263         pm_runtime_disable(dev);
264 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
265 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
266 @@ -8,6 +8,36 @@
267  
268  #include "vc4_drv.h"
269  
270 +/* VC4 HDMI encoder KMS struct */
271 +struct vc4_hdmi_encoder {
272 +       struct vc4_encoder base;
273 +       bool hdmi_monitor;
274 +       bool limited_rgb_range;
275 +};
276 +
277 +static inline struct vc4_hdmi_encoder *
278 +to_vc4_hdmi_encoder(struct drm_encoder *encoder)
279 +{
280 +       return container_of(encoder, struct vc4_hdmi_encoder, base.base);
281 +}
282 +
283 +/* VC4 HDMI connector KMS struct */
284 +struct vc4_hdmi_connector {
285 +       struct drm_connector base;
286 +
287 +       /* Since the connector is attached to just the one encoder,
288 +        * this is the reference to it so we can do the best_encoder()
289 +        * hook.
290 +        */
291 +       struct drm_encoder *encoder;
292 +};
293 +
294 +static inline struct vc4_hdmi_connector *
295 +to_vc4_hdmi_connector(struct drm_connector *connector)
296 +{
297 +       return container_of(connector, struct vc4_hdmi_connector, base);
298 +}
299 +
300  /* HDMI audio information */
301  struct vc4_hdmi_audio {
302         struct snd_soc_card card;
303 @@ -25,8 +55,8 @@ struct vc4_hdmi_audio {
304  struct vc4_hdmi {
305         struct platform_device *pdev;
306  
307 -       struct drm_encoder *encoder;
308 -       struct drm_connector *connector;
309 +       struct vc4_hdmi_encoder encoder;
310 +       struct vc4_hdmi_connector connector;
311  
312         struct vc4_hdmi_audio audio;
313  
314 @@ -53,34 +83,4 @@ struct vc4_hdmi {
315  #define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
316  #define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
317  
318 -/* VC4 HDMI encoder KMS struct */
319 -struct vc4_hdmi_encoder {
320 -       struct vc4_encoder base;
321 -       bool hdmi_monitor;
322 -       bool limited_rgb_range;
323 -};
324 -
325 -static inline struct vc4_hdmi_encoder *
326 -to_vc4_hdmi_encoder(struct drm_encoder *encoder)
327 -{
328 -       return container_of(encoder, struct vc4_hdmi_encoder, base.base);
329 -}
330 -
331 -/* VC4 HDMI connector KMS struct */
332 -struct vc4_hdmi_connector {
333 -       struct drm_connector base;
334 -
335 -       /* Since the connector is attached to just the one encoder,
336 -        * this is the reference to it so we can do the best_encoder()
337 -        * hook.
338 -        */
339 -       struct drm_encoder *encoder;
340 -};
341 -
342 -static inline struct vc4_hdmi_connector *
343 -to_vc4_hdmi_connector(struct drm_connector *connector)
344 -{
345 -       return container_of(connector, struct vc4_hdmi_connector, base);
346 -}
347 -
348  #endif /* _VC4_HDMI_H_ */