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