Merge back cpufreq updates for v5.11.
[linux-2.6-microblaze.git] / drivers / gpu / drm / imx / parallel-display.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * i.MX drm driver - parallel display implementation
4  *
5  * Copyright (C) 2012 Sascha Hauer, Pengutronix
6  */
7
8 #include <linux/component.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/videodev2.h>
12
13 #include <video/of_display_timing.h>
14
15 #include <drm/drm_atomic_helper.h>
16 #include <drm/drm_bridge.h>
17 #include <drm/drm_fb_helper.h>
18 #include <drm/drm_of.h>
19 #include <drm/drm_panel.h>
20 #include <drm/drm_probe_helper.h>
21 #include <drm/drm_simple_kms_helper.h>
22
23 #include "imx-drm.h"
24
25 struct imx_parallel_display {
26         struct drm_connector connector;
27         struct drm_encoder encoder;
28         struct drm_bridge bridge;
29         struct device *dev;
30         void *edid;
31         u32 bus_format;
32         u32 bus_flags;
33         struct drm_display_mode mode;
34         struct drm_panel *panel;
35         struct drm_bridge *next_bridge;
36 };
37
38 static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c)
39 {
40         return container_of(c, struct imx_parallel_display, connector);
41 }
42
43 static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge *b)
44 {
45         return container_of(b, struct imx_parallel_display, bridge);
46 }
47
48 static int imx_pd_connector_get_modes(struct drm_connector *connector)
49 {
50         struct imx_parallel_display *imxpd = con_to_imxpd(connector);
51         struct device_node *np = imxpd->dev->of_node;
52         int num_modes;
53
54         num_modes = drm_panel_get_modes(imxpd->panel, connector);
55         if (num_modes > 0)
56                 return num_modes;
57
58         if (imxpd->edid) {
59                 drm_connector_update_edid_property(connector, imxpd->edid);
60                 num_modes = drm_add_edid_modes(connector, imxpd->edid);
61         }
62
63         if (np) {
64                 struct drm_display_mode *mode = drm_mode_create(connector->dev);
65                 int ret;
66
67                 if (!mode)
68                         return -EINVAL;
69
70                 ret = of_get_drm_display_mode(np, &imxpd->mode,
71                                               &imxpd->bus_flags,
72                                               OF_USE_NATIVE_MODE);
73                 if (ret)
74                         return ret;
75
76                 drm_mode_copy(mode, &imxpd->mode);
77                 mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
78                 drm_mode_probed_add(connector, mode);
79                 num_modes++;
80         }
81
82         return num_modes;
83 }
84
85 static void imx_pd_bridge_enable(struct drm_bridge *bridge)
86 {
87         struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
88
89         drm_panel_prepare(imxpd->panel);
90         drm_panel_enable(imxpd->panel);
91 }
92
93 static void imx_pd_bridge_disable(struct drm_bridge *bridge)
94 {
95         struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
96
97         drm_panel_disable(imxpd->panel);
98         drm_panel_unprepare(imxpd->panel);
99 }
100
101 static const u32 imx_pd_bus_fmts[] = {
102         MEDIA_BUS_FMT_RGB888_1X24,
103         MEDIA_BUS_FMT_BGR888_1X24,
104         MEDIA_BUS_FMT_GBR888_1X24,
105         MEDIA_BUS_FMT_RGB666_1X18,
106         MEDIA_BUS_FMT_RGB666_1X24_CPADHI,
107         MEDIA_BUS_FMT_RGB565_1X16,
108 };
109
110 static u32 *
111 imx_pd_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
112                                          struct drm_bridge_state *bridge_state,
113                                          struct drm_crtc_state *crtc_state,
114                                          struct drm_connector_state *conn_state,
115                                          unsigned int *num_output_fmts)
116 {
117         struct drm_display_info *di = &conn_state->connector->display_info;
118         struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
119         u32 *output_fmts;
120
121         if (!imxpd->bus_format && !di->num_bus_formats) {
122                 *num_output_fmts = ARRAY_SIZE(imx_pd_bus_fmts);
123                 return kmemdup(imx_pd_bus_fmts, sizeof(imx_pd_bus_fmts),
124                                GFP_KERNEL);
125         }
126
127         *num_output_fmts = 1;
128         output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
129         if (!output_fmts)
130                 return NULL;
131
132         if (!imxpd->bus_format && di->num_bus_formats)
133                 output_fmts[0] = di->bus_formats[0];
134         else
135                 output_fmts[0] = imxpd->bus_format;
136
137         return output_fmts;
138 }
139
140 static bool imx_pd_format_supported(u32 output_fmt)
141 {
142         unsigned int i;
143
144         for (i = 0; i < ARRAY_SIZE(imx_pd_bus_fmts); i++) {
145                 if (imx_pd_bus_fmts[i] == output_fmt)
146                         return true;
147         }
148
149         return false;
150 }
151
152 static u32 *
153 imx_pd_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
154                                         struct drm_bridge_state *bridge_state,
155                                         struct drm_crtc_state *crtc_state,
156                                         struct drm_connector_state *conn_state,
157                                         u32 output_fmt,
158                                         unsigned int *num_input_fmts)
159 {
160         struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
161         u32 *input_fmts;
162
163         /*
164          * If the next bridge does not support bus format negotiation, let's
165          * use the static bus format definition (imxpd->bus_format) if it's
166          * specified, RGB888 when it's not.
167          */
168         if (output_fmt == MEDIA_BUS_FMT_FIXED)
169                 output_fmt = imxpd->bus_format ? : MEDIA_BUS_FMT_RGB888_1X24;
170
171         /* Now make sure the requested output format is supported. */
172         if ((imxpd->bus_format && imxpd->bus_format != output_fmt) ||
173             !imx_pd_format_supported(output_fmt)) {
174                 *num_input_fmts = 0;
175                 return NULL;
176         }
177
178         *num_input_fmts = 1;
179         input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
180         if (!input_fmts)
181                 return NULL;
182
183         input_fmts[0] = output_fmt;
184         return input_fmts;
185 }
186
187 static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge,
188                                       struct drm_bridge_state *bridge_state,
189                                       struct drm_crtc_state *crtc_state,
190                                       struct drm_connector_state *conn_state)
191 {
192         struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
193         struct drm_display_info *di = &conn_state->connector->display_info;
194         struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
195         struct drm_bridge_state *next_bridge_state = NULL;
196         struct drm_bridge *next_bridge;
197         u32 bus_flags, bus_fmt;
198
199         next_bridge = drm_bridge_get_next_bridge(bridge);
200         if (next_bridge)
201                 next_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
202                                                                     next_bridge);
203
204         if (next_bridge_state)
205                 bus_flags = next_bridge_state->input_bus_cfg.flags;
206         else if (di->num_bus_formats)
207                 bus_flags = di->bus_flags;
208         else
209                 bus_flags = imxpd->bus_flags;
210
211         bus_fmt = bridge_state->input_bus_cfg.format;
212         if (!imx_pd_format_supported(bus_fmt))
213                 return -EINVAL;
214
215         if (bus_flags &
216             ~(DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_DE_HIGH |
217               DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE |
218               DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)) {
219                 dev_warn(imxpd->dev, "invalid bus_flags (%x)\n", bus_flags);
220                 return -EINVAL;
221         }
222
223         bridge_state->output_bus_cfg.flags = bus_flags;
224         bridge_state->input_bus_cfg.flags = bus_flags;
225         imx_crtc_state->bus_flags = bus_flags;
226         imx_crtc_state->bus_format = bridge_state->input_bus_cfg.format;
227         imx_crtc_state->di_hsync_pin = 2;
228         imx_crtc_state->di_vsync_pin = 3;
229
230         return 0;
231 }
232
233 static const struct drm_connector_funcs imx_pd_connector_funcs = {
234         .fill_modes = drm_helper_probe_single_connector_modes,
235         .destroy = imx_drm_connector_destroy,
236         .reset = drm_atomic_helper_connector_reset,
237         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
238         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
239 };
240
241 static const struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
242         .get_modes = imx_pd_connector_get_modes,
243 };
244
245 static const struct drm_bridge_funcs imx_pd_bridge_funcs = {
246         .enable = imx_pd_bridge_enable,
247         .disable = imx_pd_bridge_disable,
248         .atomic_reset = drm_atomic_helper_bridge_reset,
249         .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
250         .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
251         .atomic_check = imx_pd_bridge_atomic_check,
252         .atomic_get_input_bus_fmts = imx_pd_bridge_atomic_get_input_bus_fmts,
253         .atomic_get_output_bus_fmts = imx_pd_bridge_atomic_get_output_bus_fmts,
254 };
255
256 static int imx_pd_register(struct drm_device *drm,
257         struct imx_parallel_display *imxpd)
258 {
259         struct drm_encoder *encoder = &imxpd->encoder;
260         int ret;
261
262         ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);
263         if (ret)
264                 return ret;
265
266         /* set the connector's dpms to OFF so that
267          * drm_helper_connector_dpms() won't return
268          * immediately since the current state is ON
269          * at this point.
270          */
271         imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
272
273         drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
274
275         imxpd->bridge.funcs = &imx_pd_bridge_funcs;
276         drm_bridge_attach(encoder, &imxpd->bridge, NULL, 0);
277
278         if (!imxpd->next_bridge) {
279                 drm_connector_helper_add(&imxpd->connector,
280                                 &imx_pd_connector_helper_funcs);
281                 drm_connector_init(drm, &imxpd->connector,
282                                    &imx_pd_connector_funcs,
283                                    DRM_MODE_CONNECTOR_DPI);
284         }
285
286         if (imxpd->next_bridge) {
287                 ret = drm_bridge_attach(encoder, imxpd->next_bridge,
288                                         &imxpd->bridge, 0);
289                 if (ret < 0) {
290                         dev_err(imxpd->dev, "failed to attach bridge: %d\n",
291                                 ret);
292                         return ret;
293                 }
294         } else {
295                 drm_connector_attach_encoder(&imxpd->connector, encoder);
296         }
297
298         return 0;
299 }
300
301 static int imx_pd_bind(struct device *dev, struct device *master, void *data)
302 {
303         struct drm_device *drm = data;
304         struct device_node *np = dev->of_node;
305         const u8 *edidp;
306         struct imx_parallel_display *imxpd;
307         int edid_len;
308         int ret;
309         u32 bus_format = 0;
310         const char *fmt;
311
312         imxpd = dev_get_drvdata(dev);
313         memset(imxpd, 0, sizeof(*imxpd));
314
315         /* port@1 is the output port */
316         ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel,
317                                           &imxpd->next_bridge);
318         if (ret && ret != -ENODEV)
319                 return ret;
320
321         edidp = of_get_property(np, "edid", &edid_len);
322         if (edidp)
323                 imxpd->edid = devm_kmemdup(dev, edidp, edid_len, GFP_KERNEL);
324
325         ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
326         if (!ret) {
327                 if (!strcmp(fmt, "rgb24"))
328                         bus_format = MEDIA_BUS_FMT_RGB888_1X24;
329                 else if (!strcmp(fmt, "rgb565"))
330                         bus_format = MEDIA_BUS_FMT_RGB565_1X16;
331                 else if (!strcmp(fmt, "bgr666"))
332                         bus_format = MEDIA_BUS_FMT_RGB666_1X18;
333                 else if (!strcmp(fmt, "lvds666"))
334                         bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
335         }
336         imxpd->bus_format = bus_format;
337
338         imxpd->dev = dev;
339
340         ret = imx_pd_register(drm, imxpd);
341         if (ret)
342                 return ret;
343
344         return 0;
345 }
346
347 static const struct component_ops imx_pd_ops = {
348         .bind   = imx_pd_bind,
349 };
350
351 static int imx_pd_probe(struct platform_device *pdev)
352 {
353         struct imx_parallel_display *imxpd;
354
355         imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL);
356         if (!imxpd)
357                 return -ENOMEM;
358
359         platform_set_drvdata(pdev, imxpd);
360
361         return component_add(&pdev->dev, &imx_pd_ops);
362 }
363
364 static int imx_pd_remove(struct platform_device *pdev)
365 {
366         component_del(&pdev->dev, &imx_pd_ops);
367
368         return 0;
369 }
370
371 static const struct of_device_id imx_pd_dt_ids[] = {
372         { .compatible = "fsl,imx-parallel-display", },
373         { /* sentinel */ }
374 };
375 MODULE_DEVICE_TABLE(of, imx_pd_dt_ids);
376
377 static struct platform_driver imx_pd_driver = {
378         .probe          = imx_pd_probe,
379         .remove         = imx_pd_remove,
380         .driver         = {
381                 .of_match_table = imx_pd_dt_ids,
382                 .name   = "imx-parallel-display",
383         },
384 };
385
386 module_platform_driver(imx_pd_driver);
387
388 MODULE_DESCRIPTION("i.MX parallel display driver");
389 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
390 MODULE_LICENSE("GPL");
391 MODULE_ALIAS("platform:imx-parallel-display");