0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009
0010 #include <drm/drm_atomic_state_helper.h>
0011 #include <drm/drm_bridge.h>
0012 #include <drm/drm_bridge_connector.h>
0013 #include <drm/drm_connector.h>
0014 #include <drm/drm_device.h>
0015 #include <drm/drm_edid.h>
0016 #include <drm/drm_modeset_helper_vtables.h>
0017 #include <drm/drm_probe_helper.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 struct drm_bridge_connector {
0049
0050
0051
0052 struct drm_connector base;
0053
0054
0055
0056
0057
0058 struct drm_encoder *encoder;
0059
0060
0061
0062
0063
0064
0065 struct drm_bridge *bridge_edid;
0066
0067
0068
0069
0070
0071
0072 struct drm_bridge *bridge_hpd;
0073
0074
0075
0076
0077
0078
0079 struct drm_bridge *bridge_detect;
0080
0081
0082
0083
0084
0085
0086 struct drm_bridge *bridge_modes;
0087 };
0088
0089 #define to_drm_bridge_connector(x) \
0090 container_of(x, struct drm_bridge_connector, base)
0091
0092
0093
0094
0095
0096 static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
0097 enum drm_connector_status status)
0098 {
0099 struct drm_bridge_connector *bridge_connector =
0100 to_drm_bridge_connector(connector);
0101 struct drm_bridge *bridge;
0102
0103
0104 drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) {
0105 if (bridge->funcs->hpd_notify)
0106 bridge->funcs->hpd_notify(bridge, status);
0107 }
0108 }
0109
0110 static void drm_bridge_connector_hpd_cb(void *cb_data,
0111 enum drm_connector_status status)
0112 {
0113 struct drm_bridge_connector *drm_bridge_connector = cb_data;
0114 struct drm_connector *connector = &drm_bridge_connector->base;
0115 struct drm_device *dev = connector->dev;
0116 enum drm_connector_status old_status;
0117
0118 mutex_lock(&dev->mode_config.mutex);
0119 old_status = connector->status;
0120 connector->status = status;
0121 mutex_unlock(&dev->mode_config.mutex);
0122
0123 if (old_status == status)
0124 return;
0125
0126 drm_bridge_connector_hpd_notify(connector, status);
0127
0128 drm_kms_helper_hotplug_event(dev);
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138 void drm_bridge_connector_enable_hpd(struct drm_connector *connector)
0139 {
0140 struct drm_bridge_connector *bridge_connector =
0141 to_drm_bridge_connector(connector);
0142 struct drm_bridge *hpd = bridge_connector->bridge_hpd;
0143
0144 if (hpd)
0145 drm_bridge_hpd_enable(hpd, drm_bridge_connector_hpd_cb,
0146 bridge_connector);
0147 }
0148 EXPORT_SYMBOL_GPL(drm_bridge_connector_enable_hpd);
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 void drm_bridge_connector_disable_hpd(struct drm_connector *connector)
0159 {
0160 struct drm_bridge_connector *bridge_connector =
0161 to_drm_bridge_connector(connector);
0162 struct drm_bridge *hpd = bridge_connector->bridge_hpd;
0163
0164 if (hpd)
0165 drm_bridge_hpd_disable(hpd);
0166 }
0167 EXPORT_SYMBOL_GPL(drm_bridge_connector_disable_hpd);
0168
0169
0170
0171
0172
0173 static enum drm_connector_status
0174 drm_bridge_connector_detect(struct drm_connector *connector, bool force)
0175 {
0176 struct drm_bridge_connector *bridge_connector =
0177 to_drm_bridge_connector(connector);
0178 struct drm_bridge *detect = bridge_connector->bridge_detect;
0179 enum drm_connector_status status;
0180
0181 if (detect) {
0182 status = detect->funcs->detect(detect);
0183
0184 drm_bridge_connector_hpd_notify(connector, status);
0185 } else {
0186 switch (connector->connector_type) {
0187 case DRM_MODE_CONNECTOR_DPI:
0188 case DRM_MODE_CONNECTOR_LVDS:
0189 case DRM_MODE_CONNECTOR_DSI:
0190 case DRM_MODE_CONNECTOR_eDP:
0191 status = connector_status_connected;
0192 break;
0193 default:
0194 status = connector_status_unknown;
0195 break;
0196 }
0197 }
0198
0199 return status;
0200 }
0201
0202 static void drm_bridge_connector_destroy(struct drm_connector *connector)
0203 {
0204 struct drm_bridge_connector *bridge_connector =
0205 to_drm_bridge_connector(connector);
0206
0207 if (bridge_connector->bridge_hpd) {
0208 struct drm_bridge *hpd = bridge_connector->bridge_hpd;
0209
0210 drm_bridge_hpd_disable(hpd);
0211 }
0212
0213 drm_connector_unregister(connector);
0214 drm_connector_cleanup(connector);
0215
0216 kfree(bridge_connector);
0217 }
0218
0219 static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
0220 struct dentry *root)
0221 {
0222 struct drm_bridge_connector *bridge_connector =
0223 to_drm_bridge_connector(connector);
0224 struct drm_encoder *encoder = bridge_connector->encoder;
0225 struct drm_bridge *bridge;
0226
0227 list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) {
0228 if (bridge->funcs->debugfs_init)
0229 bridge->funcs->debugfs_init(bridge, root);
0230 }
0231 }
0232
0233 static const struct drm_connector_funcs drm_bridge_connector_funcs = {
0234 .reset = drm_atomic_helper_connector_reset,
0235 .detect = drm_bridge_connector_detect,
0236 .fill_modes = drm_helper_probe_single_connector_modes,
0237 .destroy = drm_bridge_connector_destroy,
0238 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0239 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0240 .debugfs_init = drm_bridge_connector_debugfs_init,
0241 };
0242
0243
0244
0245
0246
0247 static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector,
0248 struct drm_bridge *bridge)
0249 {
0250 enum drm_connector_status status;
0251 struct edid *edid;
0252 int n;
0253
0254 status = drm_bridge_connector_detect(connector, false);
0255 if (status != connector_status_connected)
0256 goto no_edid;
0257
0258 edid = bridge->funcs->get_edid(bridge, connector);
0259 if (!drm_edid_is_valid(edid)) {
0260 kfree(edid);
0261 goto no_edid;
0262 }
0263
0264 drm_connector_update_edid_property(connector, edid);
0265 n = drm_add_edid_modes(connector, edid);
0266
0267 kfree(edid);
0268 return n;
0269
0270 no_edid:
0271 drm_connector_update_edid_property(connector, NULL);
0272 return 0;
0273 }
0274
0275 static int drm_bridge_connector_get_modes(struct drm_connector *connector)
0276 {
0277 struct drm_bridge_connector *bridge_connector =
0278 to_drm_bridge_connector(connector);
0279 struct drm_bridge *bridge;
0280
0281
0282
0283
0284
0285 bridge = bridge_connector->bridge_edid;
0286 if (bridge)
0287 return drm_bridge_connector_get_modes_edid(connector, bridge);
0288
0289
0290
0291
0292
0293 bridge = bridge_connector->bridge_modes;
0294 if (bridge)
0295 return bridge->funcs->get_modes(bridge, connector);
0296
0297
0298
0299
0300
0301
0302 return 0;
0303 }
0304
0305 static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs = {
0306 .get_modes = drm_bridge_connector_get_modes,
0307
0308 };
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
0329 struct drm_encoder *encoder)
0330 {
0331 struct drm_bridge_connector *bridge_connector;
0332 struct drm_connector *connector;
0333 struct i2c_adapter *ddc = NULL;
0334 struct drm_bridge *bridge, *panel_bridge = NULL;
0335 int connector_type;
0336
0337 bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL);
0338 if (!bridge_connector)
0339 return ERR_PTR(-ENOMEM);
0340
0341 bridge_connector->encoder = encoder;
0342
0343
0344
0345
0346
0347 connector = &bridge_connector->base;
0348 connector->interlace_allowed = true;
0349
0350
0351
0352
0353
0354
0355
0356
0357 connector_type = DRM_MODE_CONNECTOR_Unknown;
0358 drm_for_each_bridge_in_chain(encoder, bridge) {
0359 if (!bridge->interlace_allowed)
0360 connector->interlace_allowed = false;
0361
0362 if (bridge->ops & DRM_BRIDGE_OP_EDID)
0363 bridge_connector->bridge_edid = bridge;
0364 if (bridge->ops & DRM_BRIDGE_OP_HPD)
0365 bridge_connector->bridge_hpd = bridge;
0366 if (bridge->ops & DRM_BRIDGE_OP_DETECT)
0367 bridge_connector->bridge_detect = bridge;
0368 if (bridge->ops & DRM_BRIDGE_OP_MODES)
0369 bridge_connector->bridge_modes = bridge;
0370
0371 if (!drm_bridge_get_next_bridge(bridge))
0372 connector_type = bridge->type;
0373
0374 if (bridge->ddc)
0375 ddc = bridge->ddc;
0376
0377 if (drm_bridge_is_panel(bridge))
0378 panel_bridge = bridge;
0379 }
0380
0381 if (connector_type == DRM_MODE_CONNECTOR_Unknown) {
0382 kfree(bridge_connector);
0383 return ERR_PTR(-EINVAL);
0384 }
0385
0386 drm_connector_init_with_ddc(drm, connector, &drm_bridge_connector_funcs,
0387 connector_type, ddc);
0388 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
0389
0390 if (bridge_connector->bridge_hpd) {
0391 connector->polled = DRM_CONNECTOR_POLL_HPD;
0392 drm_bridge_connector_enable_hpd(connector);
0393 }
0394 else if (bridge_connector->bridge_detect)
0395 connector->polled = DRM_CONNECTOR_POLL_CONNECT
0396 | DRM_CONNECTOR_POLL_DISCONNECT;
0397
0398 if (panel_bridge)
0399 drm_panel_bridge_set_orientation(connector, panel_bridge);
0400
0401 return connector;
0402 }
0403 EXPORT_SYMBOL_GPL(drm_bridge_connector_init);