diff options
-rw-r--r-- | drivers/gpu/drm/drm_of.c | 61 | ||||
-rw-r--r-- | include/drm/drm_of.h | 20 |
2 files changed, 81 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 9a2cfab3a177..2c1ee601f1d8 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -430,3 +430,64 @@ int drm_of_lvds_get_data_mapping(const struct device_node *port) return -EINVAL; } EXPORT_SYMBOL_GPL(drm_of_lvds_get_data_mapping); + +/** + * drm_of_get_data_lanes_count - Get DSI/(e)DP data lane count + * @endpoint: DT endpoint node of the DSI/(e)DP source or sink + * @min: minimum supported number of data lanes + * @max: maximum supported number of data lanes + * + * Count DT "data-lanes" property elements and check for validity. + * + * Return: + * * min..max - positive integer count of "data-lanes" elements + * * -ve - the "data-lanes" property is missing or invalid + * * -EINVAL - the "data-lanes" property is unsupported + */ +int drm_of_get_data_lanes_count(const struct device_node *endpoint, + const unsigned int min, const unsigned int max) +{ + int ret; + + ret = of_property_count_u32_elems(endpoint, "data-lanes"); + if (ret < 0) + return ret; + + if (ret < min || ret > max) + return -EINVAL; + + return ret; +} +EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count); + +/** + * drm_of_get_data_lanes_count_ep - Get DSI/(e)DP data lane count by endpoint + * @port: DT port node of the DSI/(e)DP source or sink + * @port_reg: identifier (value of reg property) of the parent port node + * @reg: identifier (value of reg property) of the endpoint node + * @min: minimum supported number of data lanes + * @max: maximum supported number of data lanes + * + * Count DT "data-lanes" property elements and check for validity. + * This variant uses endpoint specifier. + * + * Return: + * * min..max - positive integer count of "data-lanes" elements + * * -EINVAL - the "data-mapping" property is unsupported + * * -ENODEV - the "data-mapping" property is missing + */ +int drm_of_get_data_lanes_count_ep(const struct device_node *port, + int port_reg, int reg, + const unsigned int min, + const unsigned int max) +{ + struct device_node *endpoint; + int ret; + + endpoint = of_graph_get_endpoint_by_regs(port, port_reg, reg); + ret = drm_of_get_data_lanes_count(endpoint, min, max); + of_node_put(endpoint); + + return ret; +} +EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep); diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 99f79ac8b4cd..92387eabcb6f 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -50,6 +50,12 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1, const struct device_node *port2); int drm_of_lvds_get_data_mapping(const struct device_node *port); +int drm_of_get_data_lanes_count(const struct device_node *endpoint, + const unsigned int min, const unsigned int max); +int drm_of_get_data_lanes_count_ep(const struct device_node *port, + int port_reg, int reg, + const unsigned int min, + const unsigned int max); #else static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev, struct device_node *port) @@ -105,6 +111,20 @@ drm_of_lvds_get_data_mapping(const struct device_node *port) { return -EINVAL; } + +int drm_of_get_data_lanes_count(const struct device_node *endpoint, + const unsigned int min, const unsigned int max) +{ + return -EINVAL; +} + +int drm_of_get_data_lanes_count_ep(const struct device_node *port, + int port_reg, int reg + const unsigned int min, + const unsigned int max) +{ + return -EINVAL; +} #endif /* |