1 #include <linux/component.h> 2 #include <linux/export.h> 3 #include <linux/list.h> 4 #include <linux/of_graph.h> 5 #include <drm/drmP.h> 6 #include <drm/drm_crtc.h> 7 #include <drm/drm_of.h> 8 9 static void drm_release_of(struct device *dev, void *data) 10 { 11 of_node_put(data); 12 } 13 14 /** 15 * drm_crtc_port_mask - find the mask of a registered CRTC by port OF node 16 * @dev: DRM device 17 * @port: port OF node 18 * 19 * Given a port OF node, return the possible mask of the corresponding 20 * CRTC within a device's list of CRTCs. Returns zero if not found. 21 */ 22 static uint32_t drm_crtc_port_mask(struct drm_device *dev, 23 struct device_node *port) 24 { 25 unsigned int index = 0; 26 struct drm_crtc *tmp; 27 28 drm_for_each_crtc(tmp, dev) { 29 if (tmp->port == port) 30 return 1 << index; 31 32 index++; 33 } 34 35 return 0; 36 } 37 38 /** 39 * drm_of_find_possible_crtcs - find the possible CRTCs for an encoder port 40 * @dev: DRM device 41 * @port: encoder port to scan for endpoints 42 * 43 * Scan all endpoints attached to a port, locate their attached CRTCs, 44 * and generate the DRM mask of CRTCs which may be attached to this 45 * encoder. 46 * 47 * See Documentation/devicetree/bindings/graph.txt for the bindings. 48 */ 49 uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, 50 struct device_node *port) 51 { 52 struct device_node *remote_port, *ep; 53 uint32_t possible_crtcs = 0; 54 55 for_each_endpoint_of_node(port, ep) { 56 remote_port = of_graph_get_remote_port(ep); 57 if (!remote_port) { 58 of_node_put(ep); 59 return 0; 60 } 61 62 possible_crtcs |= drm_crtc_port_mask(dev, remote_port); 63 64 of_node_put(remote_port); 65 } 66 67 return possible_crtcs; 68 } 69 EXPORT_SYMBOL(drm_of_find_possible_crtcs); 70 71 /** 72 * drm_of_component_match_add - Add a component helper OF node match rule 73 * @master: master device 74 * @matchptr: component match pointer 75 * @compare: compare function used for matching component 76 * @node: of_node 77 */ 78 void drm_of_component_match_add(struct device *master, 79 struct component_match **matchptr, 80 int (*compare)(struct device *, void *), 81 struct device_node *node) 82 { 83 of_node_get(node); 84 component_match_add_release(master, matchptr, drm_release_of, 85 compare, node); 86 } 87 EXPORT_SYMBOL_GPL(drm_of_component_match_add); 88 89 /** 90 * drm_of_component_probe - Generic probe function for a component based master 91 * @dev: master device containing the OF node 92 * @compare_of: compare function used for matching components 93 * @master_ops: component master ops to be used 94 * 95 * Parse the platform device OF node and bind all the components associated 96 * with the master. Interface ports are added before the encoders in order to 97 * satisfy their .bind requirements 98 * See Documentation/devicetree/bindings/graph.txt for the bindings. 99 * 100 * Returns zero if successful, or one of the standard error codes if it fails. 101 */ 102 int drm_of_component_probe(struct device *dev, 103 int (*compare_of)(struct device *, void *), 104 const struct component_master_ops *m_ops) 105 { 106 struct device_node *ep, *port, *remote; 107 struct component_match *match = NULL; 108 int i; 109 110 if (!dev->of_node) 111 return -EINVAL; 112 113 /* 114 * Bind the crtc's ports first, so that drm_of_find_possible_crtcs() 115 * called from encoder's .bind callbacks works as expected 116 */ 117 for (i = 0; ; i++) { 118 port = of_parse_phandle(dev->of_node, "ports", i); 119 if (!port) 120 break; 121 122 if (!of_device_is_available(port->parent)) { 123 of_node_put(port); 124 continue; 125 } 126 127 drm_of_component_match_add(dev, &match, compare_of, port); 128 of_node_put(port); 129 } 130 131 if (i == 0) { 132 dev_err(dev, "missing 'ports' property\n"); 133 return -ENODEV; 134 } 135 136 if (!match) { 137 dev_err(dev, "no available port\n"); 138 return -ENODEV; 139 } 140 141 /* 142 * For bound crtcs, bind the encoders attached to their remote endpoint 143 */ 144 for (i = 0; ; i++) { 145 port = of_parse_phandle(dev->of_node, "ports", i); 146 if (!port) 147 break; 148 149 if (!of_device_is_available(port->parent)) { 150 of_node_put(port); 151 continue; 152 } 153 154 for_each_child_of_node(port, ep) { 155 remote = of_graph_get_remote_port_parent(ep); 156 if (!remote || !of_device_is_available(remote)) { 157 of_node_put(remote); 158 continue; 159 } else if (!of_device_is_available(remote->parent)) { 160 dev_warn(dev, "parent device of %s is not available\n", 161 remote->full_name); 162 of_node_put(remote); 163 continue; 164 } 165 166 drm_of_component_match_add(dev, &match, compare_of, 167 remote); 168 of_node_put(remote); 169 } 170 of_node_put(port); 171 } 172 173 return component_master_add_with_match(dev, m_ops, match); 174 } 175 EXPORT_SYMBOL(drm_of_component_probe); 176 177 /* 178 * drm_of_encoder_active_endpoint - return the active encoder endpoint 179 * @node: device tree node containing encoder input ports 180 * @encoder: drm_encoder 181 * 182 * Given an encoder device node and a drm_encoder with a connected crtc, 183 * parse the encoder endpoint connecting to the crtc port. 184 */ 185 int drm_of_encoder_active_endpoint(struct device_node *node, 186 struct drm_encoder *encoder, 187 struct of_endpoint *endpoint) 188 { 189 struct device_node *ep; 190 struct drm_crtc *crtc = encoder->crtc; 191 struct device_node *port; 192 int ret; 193 194 if (!node || !crtc) 195 return -EINVAL; 196 197 for_each_endpoint_of_node(node, ep) { 198 port = of_graph_get_remote_port(ep); 199 of_node_put(port); 200 if (port == crtc->port) { 201 ret = of_graph_parse_endpoint(ep, endpoint); 202 of_node_put(ep); 203 return ret; 204 } 205 } 206 207 return -EINVAL; 208 } 209 EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint); 210