@@ -341,8 +341,23 @@ static int drm_of_lvds_get_remote_pixels_type(
341341 return pixels_type ;
342342}
343343
344+ static int __drm_of_lvds_get_dual_link_pixel_order (int p1_pt , int p2_pt )
345+ {
346+ /*
347+ * A valid dual-lVDS bus is found when one port is marked with
348+ * "dual-lvds-even-pixels", and the other port is marked with
349+ * "dual-lvds-odd-pixels", bail out if the markers are not right.
350+ */
351+ if (p1_pt + p2_pt != DRM_OF_LVDS_EVEN + DRM_OF_LVDS_ODD )
352+ return - EINVAL ;
353+
354+ return p1_pt == DRM_OF_LVDS_EVEN ?
355+ DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS :
356+ DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS ;
357+ }
358+
344359/**
345- * drm_of_lvds_get_dual_link_pixel_order - Get LVDS dual-link pixel order
360+ * drm_of_lvds_get_dual_link_pixel_order - Get LVDS dual-link source pixel order
346361 * @port1: First DT port node of the Dual-link LVDS source
347362 * @port2: Second DT port node of the Dual-link LVDS source
348363 *
@@ -387,19 +402,58 @@ int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
387402 if (remote_p2_pt < 0 )
388403 return remote_p2_pt ;
389404
390- /*
391- * A valid dual-lVDS bus is found when one remote port is marked with
392- * "dual-lvds-even-pixels", and the other remote port is marked with
393- * "dual-lvds-odd-pixels", bail out if the markers are not right.
394- */
395- if (remote_p1_pt + remote_p2_pt != DRM_OF_LVDS_EVEN + DRM_OF_LVDS_ODD )
405+ return __drm_of_lvds_get_dual_link_pixel_order (remote_p1_pt , remote_p2_pt );
406+ }
407+ EXPORT_SYMBOL_GPL (drm_of_lvds_get_dual_link_pixel_order );
408+
409+ /**
410+ * drm_of_lvds_get_dual_link_pixel_order_sink - Get LVDS dual-link sink pixel order
411+ * @port1: First DT port node of the Dual-link LVDS sink
412+ * @port2: Second DT port node of the Dual-link LVDS sink
413+ *
414+ * An LVDS dual-link connection is made of two links, with even pixels
415+ * transitting on one link, and odd pixels on the other link. This function
416+ * returns, for two ports of an LVDS dual-link sink, which port shall transmit
417+ * the even and odd pixels, based on the requirements of the sink.
418+ *
419+ * The pixel order is determined from the dual-lvds-even-pixels and
420+ * dual-lvds-odd-pixels properties in the sink's DT port nodes. If those
421+ * properties are not present, or if their usage is not valid, this function
422+ * returns -EINVAL.
423+ *
424+ * If either port is not connected, this function returns -EPIPE.
425+ *
426+ * @port1 and @port2 are typically DT sibling nodes, but may have different
427+ * parents when, for instance, two separate LVDS decoders receive the even and
428+ * odd pixels.
429+ *
430+ * Return:
431+ * * DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS - @port1 receives even pixels and @port2
432+ * receives odd pixels
433+ * * DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS - @port1 receives odd pixels and @port2
434+ * receives even pixels
435+ * * -EINVAL - @port1 or @port2 are NULL
436+ * * -EPIPE - when @port1 or @port2 are not connected
437+ */
438+ int drm_of_lvds_get_dual_link_pixel_order_sink (struct device_node * port1 ,
439+ struct device_node * port2 )
440+ {
441+ int sink_p1_pt , sink_p2_pt ;
442+
443+ if (!port1 || !port2 )
396444 return - EINVAL ;
397445
398- return remote_p1_pt == DRM_OF_LVDS_EVEN ?
399- DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS :
400- DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS ;
446+ sink_p1_pt = drm_of_lvds_get_port_pixels_type (port1 );
447+ if (!sink_p1_pt )
448+ return - EPIPE ;
449+
450+ sink_p2_pt = drm_of_lvds_get_port_pixels_type (port2 );
451+ if (!sink_p2_pt )
452+ return - EPIPE ;
453+
454+ return __drm_of_lvds_get_dual_link_pixel_order (sink_p1_pt , sink_p2_pt );
401455}
402- EXPORT_SYMBOL_GPL (drm_of_lvds_get_dual_link_pixel_order );
456+ EXPORT_SYMBOL_GPL (drm_of_lvds_get_dual_link_pixel_order_sink );
403457
404458/**
405459 * drm_of_lvds_get_data_mapping - Get LVDS data mapping
0 commit comments