0001
0002 #include <linux/component.h>
0003 #include <linux/export.h>
0004 #include <linux/list.h>
0005 #include <linux/media-bus-format.h>
0006 #include <linux/of.h>
0007 #include <linux/of_graph.h>
0008
0009 #include <drm/drm_bridge.h>
0010 #include <drm/drm_crtc.h>
0011 #include <drm/drm_device.h>
0012 #include <drm/drm_encoder.h>
0013 #include <drm/drm_of.h>
0014 #include <drm/drm_panel.h>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 uint32_t drm_of_crtc_port_mask(struct drm_device *dev,
0032 struct device_node *port)
0033 {
0034 unsigned int index = 0;
0035 struct drm_crtc *tmp;
0036
0037 drm_for_each_crtc(tmp, dev) {
0038 if (tmp->port == port)
0039 return 1 << index;
0040
0041 index++;
0042 }
0043
0044 return 0;
0045 }
0046 EXPORT_SYMBOL(drm_of_crtc_port_mask);
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
0060 struct device_node *port)
0061 {
0062 struct device_node *remote_port, *ep;
0063 uint32_t possible_crtcs = 0;
0064
0065 for_each_endpoint_of_node(port, ep) {
0066 remote_port = of_graph_get_remote_port(ep);
0067 if (!remote_port) {
0068 of_node_put(ep);
0069 return 0;
0070 }
0071
0072 possible_crtcs |= drm_of_crtc_port_mask(dev, remote_port);
0073
0074 of_node_put(remote_port);
0075 }
0076
0077 return possible_crtcs;
0078 }
0079 EXPORT_SYMBOL(drm_of_find_possible_crtcs);
0080
0081
0082
0083
0084
0085
0086
0087
0088 void drm_of_component_match_add(struct device *master,
0089 struct component_match **matchptr,
0090 int (*compare)(struct device *, void *),
0091 struct device_node *node)
0092 {
0093 of_node_get(node);
0094 component_match_add_release(master, matchptr, component_release_of,
0095 compare, node);
0096 }
0097 EXPORT_SYMBOL_GPL(drm_of_component_match_add);
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 int drm_of_component_probe(struct device *dev,
0113 int (*compare_of)(struct device *, void *),
0114 const struct component_master_ops *m_ops)
0115 {
0116 struct device_node *ep, *port, *remote;
0117 struct component_match *match = NULL;
0118 int i;
0119
0120 if (!dev->of_node)
0121 return -EINVAL;
0122
0123
0124
0125
0126
0127 for (i = 0; ; i++) {
0128 port = of_parse_phandle(dev->of_node, "ports", i);
0129 if (!port)
0130 break;
0131
0132 if (of_device_is_available(port->parent))
0133 drm_of_component_match_add(dev, &match, compare_of,
0134 port);
0135
0136 of_node_put(port);
0137 }
0138
0139 if (i == 0) {
0140 dev_err(dev, "missing 'ports' property\n");
0141 return -ENODEV;
0142 }
0143
0144 if (!match) {
0145 dev_err(dev, "no available port\n");
0146 return -ENODEV;
0147 }
0148
0149
0150
0151
0152 for (i = 0; ; i++) {
0153 port = of_parse_phandle(dev->of_node, "ports", i);
0154 if (!port)
0155 break;
0156
0157 if (!of_device_is_available(port->parent)) {
0158 of_node_put(port);
0159 continue;
0160 }
0161
0162 for_each_child_of_node(port, ep) {
0163 remote = of_graph_get_remote_port_parent(ep);
0164 if (!remote || !of_device_is_available(remote)) {
0165 of_node_put(remote);
0166 continue;
0167 } else if (!of_device_is_available(remote->parent)) {
0168 dev_warn(dev, "parent device of %pOF is not available\n",
0169 remote);
0170 of_node_put(remote);
0171 continue;
0172 }
0173
0174 drm_of_component_match_add(dev, &match, compare_of,
0175 remote);
0176 of_node_put(remote);
0177 }
0178 of_node_put(port);
0179 }
0180
0181 return component_master_add_with_match(dev, m_ops, match);
0182 }
0183 EXPORT_SYMBOL(drm_of_component_probe);
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 int drm_of_encoder_active_endpoint(struct device_node *node,
0194 struct drm_encoder *encoder,
0195 struct of_endpoint *endpoint)
0196 {
0197 struct device_node *ep;
0198 struct drm_crtc *crtc = encoder->crtc;
0199 struct device_node *port;
0200 int ret;
0201
0202 if (!node || !crtc)
0203 return -EINVAL;
0204
0205 for_each_endpoint_of_node(node, ep) {
0206 port = of_graph_get_remote_port(ep);
0207 of_node_put(port);
0208 if (port == crtc->port) {
0209 ret = of_graph_parse_endpoint(ep, endpoint);
0210 of_node_put(ep);
0211 return ret;
0212 }
0213 }
0214
0215 return -EINVAL;
0216 }
0217 EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236 int drm_of_find_panel_or_bridge(const struct device_node *np,
0237 int port, int endpoint,
0238 struct drm_panel **panel,
0239 struct drm_bridge **bridge)
0240 {
0241 int ret = -EPROBE_DEFER;
0242 struct device_node *remote;
0243
0244 if (!panel && !bridge)
0245 return -EINVAL;
0246 if (panel)
0247 *panel = NULL;
0248
0249
0250
0251
0252
0253
0254
0255 if (!of_graph_is_present(np))
0256 return -ENODEV;
0257
0258 remote = of_graph_get_remote_node(np, port, endpoint);
0259 if (!remote)
0260 return -ENODEV;
0261
0262 if (panel) {
0263 *panel = of_drm_find_panel(remote);
0264 if (!IS_ERR(*panel))
0265 ret = 0;
0266 else
0267 *panel = NULL;
0268 }
0269
0270
0271 if (bridge) {
0272 if (ret) {
0273 *bridge = of_drm_find_bridge(remote);
0274 if (*bridge)
0275 ret = 0;
0276 } else {
0277 *bridge = NULL;
0278 }
0279
0280 }
0281
0282 of_node_put(remote);
0283 return ret;
0284 }
0285 EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
0286
0287 enum drm_of_lvds_pixels {
0288 DRM_OF_LVDS_EVEN = BIT(0),
0289 DRM_OF_LVDS_ODD = BIT(1),
0290 };
0291
0292 static int drm_of_lvds_get_port_pixels_type(struct device_node *port_node)
0293 {
0294 bool even_pixels =
0295 of_property_read_bool(port_node, "dual-lvds-even-pixels");
0296 bool odd_pixels =
0297 of_property_read_bool(port_node, "dual-lvds-odd-pixels");
0298
0299 return (even_pixels ? DRM_OF_LVDS_EVEN : 0) |
0300 (odd_pixels ? DRM_OF_LVDS_ODD : 0);
0301 }
0302
0303 static int drm_of_lvds_get_remote_pixels_type(
0304 const struct device_node *port_node)
0305 {
0306 struct device_node *endpoint = NULL;
0307 int pixels_type = -EPIPE;
0308
0309 for_each_child_of_node(port_node, endpoint) {
0310 struct device_node *remote_port;
0311 int current_pt;
0312
0313 if (!of_node_name_eq(endpoint, "endpoint"))
0314 continue;
0315
0316 remote_port = of_graph_get_remote_port(endpoint);
0317 if (!remote_port) {
0318 of_node_put(endpoint);
0319 return -EPIPE;
0320 }
0321
0322 current_pt = drm_of_lvds_get_port_pixels_type(remote_port);
0323 of_node_put(remote_port);
0324 if (pixels_type < 0)
0325 pixels_type = current_pt;
0326
0327
0328
0329
0330
0331
0332
0333
0334 if (!current_pt || pixels_type != current_pt) {
0335 of_node_put(endpoint);
0336 return -EINVAL;
0337 }
0338 }
0339
0340 return pixels_type;
0341 }
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373 int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
0374 const struct device_node *port2)
0375 {
0376 int remote_p1_pt, remote_p2_pt;
0377
0378 if (!port1 || !port2)
0379 return -EINVAL;
0380
0381 remote_p1_pt = drm_of_lvds_get_remote_pixels_type(port1);
0382 if (remote_p1_pt < 0)
0383 return remote_p1_pt;
0384
0385 remote_p2_pt = drm_of_lvds_get_remote_pixels_type(port2);
0386 if (remote_p2_pt < 0)
0387 return remote_p2_pt;
0388
0389
0390
0391
0392
0393
0394 if (remote_p1_pt + remote_p2_pt != DRM_OF_LVDS_EVEN + DRM_OF_LVDS_ODD)
0395 return -EINVAL;
0396
0397 return remote_p1_pt == DRM_OF_LVDS_EVEN ?
0398 DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS :
0399 DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
0400 }
0401 EXPORT_SYMBOL_GPL(drm_of_lvds_get_dual_link_pixel_order);
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416 int drm_of_lvds_get_data_mapping(const struct device_node *port)
0417 {
0418 const char *mapping;
0419 int ret;
0420
0421 ret = of_property_read_string(port, "data-mapping", &mapping);
0422 if (ret < 0)
0423 return -ENODEV;
0424
0425 if (!strcmp(mapping, "jeida-18"))
0426 return MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
0427 if (!strcmp(mapping, "jeida-24"))
0428 return MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
0429 if (!strcmp(mapping, "vesa-24"))
0430 return MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
0431
0432 return -EINVAL;
0433 }
0434 EXPORT_SYMBOL_GPL(drm_of_lvds_get_data_mapping);
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 int drm_of_get_data_lanes_count(const struct device_node *endpoint,
0450 const unsigned int min, const unsigned int max)
0451 {
0452 int ret;
0453
0454 ret = of_property_count_u32_elems(endpoint, "data-lanes");
0455 if (ret < 0)
0456 return ret;
0457
0458 if (ret < min || ret > max)
0459 return -EINVAL;
0460
0461 return ret;
0462 }
0463 EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count);
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 int drm_of_get_data_lanes_count_ep(const struct device_node *port,
0482 int port_reg, int reg,
0483 const unsigned int min,
0484 const unsigned int max)
0485 {
0486 struct device_node *endpoint;
0487 int ret;
0488
0489 endpoint = of_graph_get_endpoint_by_regs(port, port_reg, reg);
0490 ret = drm_of_get_data_lanes_count(endpoint, min, max);
0491 of_node_put(endpoint);
0492
0493 return ret;
0494 }
0495 EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep);