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