1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
6 #include <drm/drm_atomic_helper.h>
7 #include <drm/drm_atomic.h>
8 #include <drm/drm_bridge.h>
9 #include <drm/drm_bridge_connector.h>
10 #include <drm/drm_crtc.h>
17 * dp_bridge_detect - callback to determine if connector is connected
18 * @bridge: Pointer to drm bridge structure
19 * Returns: Bridge's 'is connected' status
21 static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
25 dp = to_dp_bridge(bridge)->dp_display;
27 drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
28 (dp->is_connected) ? "true" : "false");
30 return (dp->is_connected) ? connector_status_connected :
31 connector_status_disconnected;
35 * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
36 * @bridge: Poiner to drm bridge
37 * @connector: Pointer to drm connector structure
38 * Returns: Number of modes added
40 static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
48 dp = to_dp_bridge(bridge)->dp_display;
50 /* pluggable case assumes EDID is read when HPD */
51 if (dp->is_connected) {
52 rc = dp_display_get_modes(dp);
54 DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc);
58 drm_dbg_dp(connector->dev, "No sink connected\n");
63 static const struct drm_bridge_funcs dp_bridge_ops = {
64 .enable = dp_bridge_enable,
65 .disable = dp_bridge_disable,
66 .post_disable = dp_bridge_post_disable,
67 .mode_set = dp_bridge_mode_set,
68 .mode_valid = dp_bridge_mode_valid,
69 .get_modes = dp_bridge_get_modes,
70 .detect = dp_bridge_detect,
73 struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
74 struct drm_encoder *encoder)
77 struct msm_dp_bridge *dp_bridge;
78 struct drm_bridge *bridge;
80 dp_bridge = devm_kzalloc(dev->dev, sizeof(*dp_bridge), GFP_KERNEL);
82 return ERR_PTR(-ENOMEM);
84 dp_bridge->dp_display = dp_display;
86 bridge = &dp_bridge->bridge;
87 bridge->funcs = &dp_bridge_ops;
88 bridge->type = dp_display->connector_type;
91 * Many ops only make sense for DP. Why?
92 * - Detect/HPD are used by DRM to know if a display is _physically_
93 * there, not whether the display is powered on / finished initting.
94 * On eDP we assume the display is always there because you can't
95 * know until power is applied. If we don't implement the ops DRM will
96 * assume our display is always there.
97 * - Currently eDP mode reading is driven by the panel driver. This
98 * allows the panel driver to properly power itself on to read the
101 if (!dp_display->is_edp) {
103 DRM_BRIDGE_OP_DETECT |
108 drm_bridge_add(bridge);
110 rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
112 DRM_ERROR("failed to attach bridge, rc=%d\n", rc);
113 drm_bridge_remove(bridge);
118 if (dp_display->next_bridge) {
119 rc = drm_bridge_attach(encoder,
120 dp_display->next_bridge, bridge,
121 DRM_BRIDGE_ATTACH_NO_CONNECTOR);
123 DRM_ERROR("failed to attach panel bridge: %d\n", rc);
124 drm_bridge_remove(bridge);
132 /* connector initialization */
133 struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder)
135 struct drm_connector *connector = NULL;
137 connector = drm_bridge_connector_init(dp_display->drm_dev, encoder);
138 if (IS_ERR(connector))
141 drm_connector_attach_encoder(connector, encoder);