|
12 | 12 | #include "msm_kms.h" |
13 | 13 | #include "dp_drm.h" |
14 | 14 |
|
| 15 | + |
| 16 | +struct msm_dp_bridge { |
| 17 | + struct drm_bridge bridge; |
| 18 | + struct msm_dp *dp_display; |
| 19 | +}; |
| 20 | + |
| 21 | +#define to_dp_display(x) container_of((x), struct msm_dp_bridge, bridge) |
| 22 | + |
15 | 23 | struct dp_connector { |
16 | 24 | struct drm_connector base; |
17 | 25 | struct msm_dp *dp_display; |
@@ -173,3 +181,71 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display) |
173 | 181 |
|
174 | 182 | return connector; |
175 | 183 | } |
| 184 | + |
| 185 | +static void dp_bridge_mode_set(struct drm_bridge *drm_bridge, |
| 186 | + const struct drm_display_mode *mode, |
| 187 | + const struct drm_display_mode *adjusted_mode) |
| 188 | +{ |
| 189 | + struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge); |
| 190 | + struct msm_dp *dp_display = dp_bridge->dp_display; |
| 191 | + |
| 192 | + msm_dp_display_mode_set(dp_display, drm_bridge->encoder, mode, adjusted_mode); |
| 193 | +} |
| 194 | + |
| 195 | +static void dp_bridge_enable(struct drm_bridge *drm_bridge) |
| 196 | +{ |
| 197 | + struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge); |
| 198 | + struct msm_dp *dp_display = dp_bridge->dp_display; |
| 199 | + |
| 200 | + msm_dp_display_enable(dp_display, drm_bridge->encoder); |
| 201 | +} |
| 202 | + |
| 203 | +static void dp_bridge_disable(struct drm_bridge *drm_bridge) |
| 204 | +{ |
| 205 | + struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge); |
| 206 | + struct msm_dp *dp_display = dp_bridge->dp_display; |
| 207 | + |
| 208 | + msm_dp_display_pre_disable(dp_display, drm_bridge->encoder); |
| 209 | +} |
| 210 | + |
| 211 | +static void dp_bridge_post_disable(struct drm_bridge *drm_bridge) |
| 212 | +{ |
| 213 | + struct msm_dp_bridge *dp_bridge = to_dp_display(drm_bridge); |
| 214 | + struct msm_dp *dp_display = dp_bridge->dp_display; |
| 215 | + |
| 216 | + msm_dp_display_disable(dp_display, drm_bridge->encoder); |
| 217 | +} |
| 218 | + |
| 219 | +static const struct drm_bridge_funcs dp_bridge_ops = { |
| 220 | + .enable = dp_bridge_enable, |
| 221 | + .disable = dp_bridge_disable, |
| 222 | + .post_disable = dp_bridge_post_disable, |
| 223 | + .mode_set = dp_bridge_mode_set, |
| 224 | +}; |
| 225 | + |
| 226 | +struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, |
| 227 | + struct drm_encoder *encoder) |
| 228 | +{ |
| 229 | + int rc; |
| 230 | + struct msm_dp_bridge *dp_bridge; |
| 231 | + struct drm_bridge *bridge; |
| 232 | + |
| 233 | + dp_bridge = devm_kzalloc(dev->dev, sizeof(*dp_bridge), GFP_KERNEL); |
| 234 | + if (!dp_bridge) |
| 235 | + return ERR_PTR(-ENOMEM); |
| 236 | + |
| 237 | + dp_bridge->dp_display = dp_display; |
| 238 | + |
| 239 | + bridge = &dp_bridge->bridge; |
| 240 | + bridge->funcs = &dp_bridge_ops; |
| 241 | + bridge->encoder = encoder; |
| 242 | + |
| 243 | + rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); |
| 244 | + if (rc) { |
| 245 | + DRM_ERROR("failed to attach bridge, rc=%d\n", rc); |
| 246 | + kfree(dp_bridge); |
| 247 | + return ERR_PTR(rc); |
| 248 | + } |
| 249 | + |
| 250 | + return bridge; |
| 251 | +} |
0 commit comments