1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Freescale i.MX drm driver
4 *
5 * bridge driver for legacy DT bindings, utilizing display-timings node
6 */
7
8 #include <linux/export.h>
9
10 #include <drm/drm_bridge.h>
11 #include <drm/drm_modes.h>
12 #include <drm/drm_probe_helper.h>
13 #include <drm/bridge/imx.h>
14
15 #include <video/of_display_timing.h>
16 #include <video/of_videomode.h>
17
18 struct imx_legacy_bridge {
19 struct drm_bridge base;
20
21 struct drm_display_mode mode;
22 u32 bus_flags;
23 };
24
25 #define to_imx_legacy_bridge(bridge) container_of(bridge, struct imx_legacy_bridge, base)
26
imx_legacy_bridge_attach(struct drm_bridge * bridge,struct drm_encoder * encoder,enum drm_bridge_attach_flags flags)27 static int imx_legacy_bridge_attach(struct drm_bridge *bridge,
28 struct drm_encoder *encoder,
29 enum drm_bridge_attach_flags flags)
30 {
31 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
32 return -EINVAL;
33
34 return 0;
35 }
36
imx_legacy_bridge_get_modes(struct drm_bridge * bridge,struct drm_connector * connector)37 static int imx_legacy_bridge_get_modes(struct drm_bridge *bridge,
38 struct drm_connector *connector)
39 {
40 struct imx_legacy_bridge *imx_bridge = to_imx_legacy_bridge(bridge);
41 int ret;
42
43 ret = drm_connector_helper_get_modes_fixed(connector, &imx_bridge->mode);
44 if (ret)
45 return ret;
46
47 connector->display_info.bus_flags = imx_bridge->bus_flags;
48
49 return 0;
50 }
51
52 struct drm_bridge_funcs imx_legacy_bridge_funcs = {
53 .attach = imx_legacy_bridge_attach,
54 .get_modes = imx_legacy_bridge_get_modes,
55 };
56
devm_imx_drm_legacy_bridge(struct device * dev,struct device_node * np,int type)57 struct drm_bridge *devm_imx_drm_legacy_bridge(struct device *dev,
58 struct device_node *np,
59 int type)
60 {
61 struct imx_legacy_bridge *imx_bridge;
62 int ret;
63
64 imx_bridge = devm_drm_bridge_alloc(dev, struct imx_legacy_bridge,
65 base, &imx_legacy_bridge_funcs);
66 if (IS_ERR(imx_bridge))
67 return ERR_CAST(imx_bridge);
68
69 ret = of_get_drm_display_mode(np,
70 &imx_bridge->mode,
71 &imx_bridge->bus_flags,
72 OF_USE_NATIVE_MODE);
73 if (ret)
74 return ERR_PTR(ret);
75
76 imx_bridge->mode.type |= DRM_MODE_TYPE_DRIVER;
77
78 imx_bridge->base.of_node = np;
79 imx_bridge->base.ops = DRM_BRIDGE_OP_MODES;
80 imx_bridge->base.type = type;
81
82 ret = devm_drm_bridge_add(dev, &imx_bridge->base);
83 if (ret)
84 return ERR_PTR(ret);
85
86 return &imx_bridge->base;
87 }
88 EXPORT_SYMBOL_GPL(devm_imx_drm_legacy_bridge);
89
90 MODULE_LICENSE("GPL");
91 MODULE_DESCRIPTION("Freescale i.MX DRM bridge driver for legacy DT bindings");
92