0001
0002
0003
0004
0005
0006
0007 #include <drm/drm_atomic_helper.h>
0008 #include <drm/drm_bridge.h>
0009 #include <drm/drm_connector.h>
0010 #include <drm/drm_encoder.h>
0011 #include <drm/drm_modeset_helper_vtables.h>
0012 #include <drm/drm_of.h>
0013 #include <drm/drm_panel.h>
0014 #include <drm/drm_print.h>
0015 #include <drm/drm_probe_helper.h>
0016
0017 struct panel_bridge {
0018 struct drm_bridge bridge;
0019 struct drm_connector connector;
0020 struct drm_panel *panel;
0021 u32 connector_type;
0022 };
0023
0024 static inline struct panel_bridge *
0025 drm_bridge_to_panel_bridge(struct drm_bridge *bridge)
0026 {
0027 return container_of(bridge, struct panel_bridge, bridge);
0028 }
0029
0030 static inline struct panel_bridge *
0031 drm_connector_to_panel_bridge(struct drm_connector *connector)
0032 {
0033 return container_of(connector, struct panel_bridge, connector);
0034 }
0035
0036 static int panel_bridge_connector_get_modes(struct drm_connector *connector)
0037 {
0038 struct panel_bridge *panel_bridge =
0039 drm_connector_to_panel_bridge(connector);
0040
0041 return drm_panel_get_modes(panel_bridge->panel, connector);
0042 }
0043
0044 static const struct drm_connector_helper_funcs
0045 panel_bridge_connector_helper_funcs = {
0046 .get_modes = panel_bridge_connector_get_modes,
0047 };
0048
0049 static const struct drm_connector_funcs panel_bridge_connector_funcs = {
0050 .reset = drm_atomic_helper_connector_reset,
0051 .fill_modes = drm_helper_probe_single_connector_modes,
0052 .destroy = drm_connector_cleanup,
0053 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0054 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0055 };
0056
0057 static int panel_bridge_attach(struct drm_bridge *bridge,
0058 enum drm_bridge_attach_flags flags)
0059 {
0060 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0061 struct drm_connector *connector = &panel_bridge->connector;
0062 int ret;
0063
0064 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
0065 return 0;
0066
0067 if (!bridge->encoder) {
0068 DRM_ERROR("Missing encoder\n");
0069 return -ENODEV;
0070 }
0071
0072 drm_connector_helper_add(connector,
0073 &panel_bridge_connector_helper_funcs);
0074
0075 ret = drm_connector_init(bridge->dev, connector,
0076 &panel_bridge_connector_funcs,
0077 panel_bridge->connector_type);
0078 if (ret) {
0079 DRM_ERROR("Failed to initialize connector\n");
0080 return ret;
0081 }
0082
0083 drm_connector_attach_encoder(&panel_bridge->connector,
0084 bridge->encoder);
0085
0086 if (bridge->dev->registered) {
0087 if (connector->funcs->reset)
0088 connector->funcs->reset(connector);
0089 drm_connector_register(connector);
0090 }
0091
0092 return 0;
0093 }
0094
0095 static void panel_bridge_detach(struct drm_bridge *bridge)
0096 {
0097 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0098 struct drm_connector *connector = &panel_bridge->connector;
0099
0100
0101
0102
0103
0104
0105
0106
0107 if (connector->dev)
0108 drm_connector_cleanup(connector);
0109 }
0110
0111 static void panel_bridge_pre_enable(struct drm_bridge *bridge)
0112 {
0113 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0114
0115 drm_panel_prepare(panel_bridge->panel);
0116 }
0117
0118 static void panel_bridge_enable(struct drm_bridge *bridge)
0119 {
0120 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0121
0122 drm_panel_enable(panel_bridge->panel);
0123 }
0124
0125 static void panel_bridge_disable(struct drm_bridge *bridge)
0126 {
0127 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0128
0129 drm_panel_disable(panel_bridge->panel);
0130 }
0131
0132 static void panel_bridge_post_disable(struct drm_bridge *bridge)
0133 {
0134 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0135
0136 drm_panel_unprepare(panel_bridge->panel);
0137 }
0138
0139 static int panel_bridge_get_modes(struct drm_bridge *bridge,
0140 struct drm_connector *connector)
0141 {
0142 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0143
0144 return drm_panel_get_modes(panel_bridge->panel, connector);
0145 }
0146
0147 static void panel_bridge_debugfs_init(struct drm_bridge *bridge,
0148 struct dentry *root)
0149 {
0150 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
0151 struct drm_panel *panel = panel_bridge->panel;
0152
0153 root = debugfs_create_dir("panel", root);
0154 if (panel->funcs->debugfs_init)
0155 panel->funcs->debugfs_init(panel, root);
0156 }
0157
0158 static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
0159 .attach = panel_bridge_attach,
0160 .detach = panel_bridge_detach,
0161 .pre_enable = panel_bridge_pre_enable,
0162 .enable = panel_bridge_enable,
0163 .disable = panel_bridge_disable,
0164 .post_disable = panel_bridge_post_disable,
0165 .get_modes = panel_bridge_get_modes,
0166 .atomic_reset = drm_atomic_helper_bridge_reset,
0167 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
0168 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
0169 .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt,
0170 .debugfs_init = panel_bridge_debugfs_init,
0171 };
0172
0173
0174
0175
0176
0177
0178
0179
0180 bool drm_bridge_is_panel(const struct drm_bridge *bridge)
0181 {
0182 return bridge->funcs == &panel_bridge_bridge_funcs;
0183 }
0184 EXPORT_SYMBOL(drm_bridge_is_panel);
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel)
0212 {
0213 if (WARN_ON(panel->connector_type == DRM_MODE_CONNECTOR_Unknown))
0214 return ERR_PTR(-EINVAL);
0215
0216 return drm_panel_bridge_add_typed(panel, panel->connector_type);
0217 }
0218 EXPORT_SYMBOL(drm_panel_bridge_add);
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
0234 u32 connector_type)
0235 {
0236 struct panel_bridge *panel_bridge;
0237
0238 if (!panel)
0239 return ERR_PTR(-EINVAL);
0240
0241 panel_bridge = devm_kzalloc(panel->dev, sizeof(*panel_bridge),
0242 GFP_KERNEL);
0243 if (!panel_bridge)
0244 return ERR_PTR(-ENOMEM);
0245
0246 panel_bridge->connector_type = connector_type;
0247 panel_bridge->panel = panel;
0248
0249 panel_bridge->bridge.funcs = &panel_bridge_bridge_funcs;
0250 #ifdef CONFIG_OF
0251 panel_bridge->bridge.of_node = panel->dev->of_node;
0252 #endif
0253 panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES;
0254 panel_bridge->bridge.type = connector_type;
0255
0256 drm_bridge_add(&panel_bridge->bridge);
0257
0258 return &panel_bridge->bridge;
0259 }
0260 EXPORT_SYMBOL(drm_panel_bridge_add_typed);
0261
0262
0263
0264
0265
0266
0267
0268 void drm_panel_bridge_remove(struct drm_bridge *bridge)
0269 {
0270 struct panel_bridge *panel_bridge;
0271
0272 if (!bridge)
0273 return;
0274
0275 if (bridge->funcs != &panel_bridge_bridge_funcs)
0276 return;
0277
0278 panel_bridge = drm_bridge_to_panel_bridge(bridge);
0279
0280 drm_bridge_remove(bridge);
0281 devm_kfree(panel_bridge->panel->dev, bridge);
0282 }
0283 EXPORT_SYMBOL(drm_panel_bridge_remove);
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294 int drm_panel_bridge_set_orientation(struct drm_connector *connector,
0295 struct drm_bridge *bridge)
0296 {
0297 struct panel_bridge *panel_bridge;
0298
0299 panel_bridge = drm_bridge_to_panel_bridge(bridge);
0300
0301 return drm_connector_set_orientation_from_panel(connector,
0302 panel_bridge->panel);
0303 }
0304 EXPORT_SYMBOL(drm_panel_bridge_set_orientation);
0305
0306 static void devm_drm_panel_bridge_release(struct device *dev, void *res)
0307 {
0308 struct drm_bridge **bridge = res;
0309
0310 drm_panel_bridge_remove(*bridge);
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
0323 struct drm_panel *panel)
0324 {
0325 if (WARN_ON(panel->connector_type == DRM_MODE_CONNECTOR_Unknown))
0326 return ERR_PTR(-EINVAL);
0327
0328 return devm_drm_panel_bridge_add_typed(dev, panel,
0329 panel->connector_type);
0330 }
0331 EXPORT_SYMBOL(devm_drm_panel_bridge_add);
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
0348 struct drm_panel *panel,
0349 u32 connector_type)
0350 {
0351 struct drm_bridge **ptr, *bridge;
0352
0353 ptr = devres_alloc(devm_drm_panel_bridge_release, sizeof(*ptr),
0354 GFP_KERNEL);
0355 if (!ptr)
0356 return ERR_PTR(-ENOMEM);
0357
0358 bridge = drm_panel_bridge_add_typed(panel, connector_type);
0359 if (!IS_ERR(bridge)) {
0360 *ptr = bridge;
0361 devres_add(dev, ptr);
0362 } else {
0363 devres_free(ptr);
0364 }
0365
0366 return bridge;
0367 }
0368 EXPORT_SYMBOL(devm_drm_panel_bridge_add_typed);
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379 struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge)
0380 {
0381 struct panel_bridge *panel_bridge;
0382
0383 panel_bridge = drm_bridge_to_panel_bridge(bridge);
0384
0385 return &panel_bridge->connector;
0386 }
0387 EXPORT_SYMBOL(drm_panel_bridge_connector);
0388
0389 #ifdef CONFIG_OF
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
0405 struct device_node *np,
0406 u32 port, u32 endpoint)
0407 {
0408 struct drm_bridge *bridge;
0409 struct drm_panel *panel;
0410 int ret;
0411
0412 ret = drm_of_find_panel_or_bridge(np, port, endpoint,
0413 &panel, &bridge);
0414 if (ret)
0415 return ERR_PTR(ret);
0416
0417 if (panel)
0418 bridge = devm_drm_panel_bridge_add(dev, panel);
0419
0420 return bridge;
0421 }
0422 EXPORT_SYMBOL(devm_drm_of_get_bridge);
0423 #endif