All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC] drm: Add a new connector atomic property for link status
@ 2016-11-23  1:30 Manasi Navare
  2016-11-23  1:45 ` ✗ Fi.CI.BAT: warning for " Patchwork
                   ` (5 more replies)
  0 siblings, 6 replies; 27+ messages in thread
From: Manasi Navare @ 2016-11-23  1:30 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Manasi Navare, Daniel Vetter

This is RFC patch for adding a connector link-status property
and making it atomic by adding it to the drm_connector_state.
This is to make sure its wired properly in drm_atomic_connector_set_property
and drm_atomic_connector_get_property functions.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/drm_atomic.c    |  5 ++++
 drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
 include/drm/drm_connector.h     | 12 +++++++-
 include/drm/drm_mode_config.h   |  5 ++++
 include/uapi/drm/drm_mode.h     |  4 +++
 5 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 89737e4..644d19f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
 		 * now?) atomic writes to DPMS property:
 		 */
 		return -EINVAL;
+	} else if (property == config->link_status_property) {
+		state->link_status = val;
+		return 0;
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 		*val = (state->crtc) ? state->crtc->base.id : 0;
 	} else if (property == config->dpms_property) {
 		*val = connector->dpms;
+	} else if (property == config->link_status_property) {
+		*val = state->link_status;
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 5a45262..4576c9f 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
 	drm_object_attach_property(&connector->base,
 				      config->dpms_property, 0);
 
+	drm_object_attach_property(&connector->base,
+				   config->link_status_property,
+				   0);
+
 	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
 	}
@@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
 };
 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
 
+static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
+	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
+	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
+};
+DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
+
 /**
  * drm_display_info_set_bus_formats - set the supported bus formats
  * @info: display info to store bus formats in
@@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
  * 	path property the MST manager created. Userspace cannot change this
  * 	property.
  * TILE:
- * 	Connector tile group property to indicate how a set of DRM connector
+ *      Connector tile group property to indicate how a set of DRM connector
  * 	compose together into one logical screen. This is used by both high-res
  * 	external screens (often only using a single cable, but exposing multiple
  * 	DP MST sinks), or high-res integrated panels (like dual-link DSI) which
@@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
  * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
  * 	should update this value using drm_mode_connector_set_tile_property().
  * 	Userspace cannot change this property.
- *
+ * link-status:
+ *      Connector link-status property to indicate the status of link during
+ *      the modeset. The default value of link-status is "GOOD". If something
+ *      fails during modeset, the kernel driver can set this to "BAD", prune
+ *      the mode list based on new link parameters and send a hotplug uevent
+ *      to notify userspace to re-check the valid modes through GET_CONNECTOR
+ *      IOCTL and redo a modeset. Drivers should update this value using
+ *      drm_mode_connector_set_link_status_property().
  * Connectors also have one standardized atomic property:
  *
  * CRTC_ID:
@@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
 		return -ENOMEM;
 	dev->mode_config.tile_property = prop;
 
+	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
+					drm_link_status_enum_list,
+					ARRAY_SIZE(drm_link_status_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.link_status_property = prop;
+
 	return 0;
 }
 
@@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
 
+/**
+ * drm_mode_connector_set_link_status_property - Set link status property of a connector
+ * @connector: drm connector
+ * @link_status: new value of link status property (0: Good, 1: Bad)
+ *
+ * In usual working scenario, this link status property will always be set to
+ * "GOOD". If something fails during or after a mode set, the kernel driver should
+ * set this link status property to "BAD" and prune the mode list based on new
+ * information. The caller then needs to send a hotplug uevent for userspace to
+ *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
+ *
+ * Note that a lot of existing userspace do not handle this property.
+ * Drivers can therefore not rely on userspace to fix up everything and
+ * should try to handle issues (like just re-training a link) without
+ * userspace's intervention. This should only be used when the current mode
+ * fails and userspace must select a different display mode.
+ * The DRM driver can chose to not modify property and keep link status
+ * as "GOOD" always to keep the user experience same as it currently is.
+ *
+ * The reason for adding this property is to handle link training failures, but
+ * it is not limited to DP or link training. For example, if we implement
+ * asynchronous setcrtc, this property can be used to report any failures in that.
+ */
+void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
+						 uint64_t link_status)
+{
+	struct drm_device *dev = connector->dev;
+
+	/* Make sure the mutex is grabbed */
+	lockdep_assert_held(&dev->mode_config.mutex);
+	connector->link_status = link_status;
+	drm_object_property_set_value(&connector->base,
+				      dev->mode_config.link_status_property,
+				      link_status);
+}
+EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
+
 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 34f9741..3d513ab 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -213,6 +213,9 @@ struct drm_connector_state {
 
 	struct drm_encoder *best_encoder;
 
+	/* Connector Link status */
+	unsigned int link_status;
+
 	struct drm_atomic_state *state;
 };
 
@@ -695,6 +698,12 @@ struct drm_connector {
 	uint8_t num_h_tile, num_v_tile;
 	uint8_t tile_h_loc, tile_v_loc;
 	uint16_t tile_h_size, tile_v_size;
+
+	/* Connector Link status
+	 * 0: If the link is Good
+	 * 1: If the link is Bad
+	 */
+	int link_status;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
 int drm_mode_create_scaling_mode_property(struct drm_device *dev);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
-
 int drm_mode_connector_set_path_property(struct drm_connector *connector,
 					 const char *path);
 int drm_mode_connector_set_tile_property(struct drm_connector *connector);
 int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 					    const struct edid *edid);
+void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
+						 uint64_t link_status);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index bf9991b..86faee4 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -431,6 +431,11 @@ struct drm_mode_config {
 	 */
 	struct drm_property *tile_property;
 	/**
+	 * @link_status_property: Default connector property for link status
+	 * of a connector
+	 */
+	struct drm_property *link_status_property;
+	/**
 	 * @plane_type_property: Default plane property to differentiate
 	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
 	 */
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 728790b..309c478 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -123,6 +123,10 @@
 #define DRM_MODE_DIRTY_ON       1
 #define DRM_MODE_DIRTY_ANNOTATE 2
 
+/* Link Status options */
+#define DRM_MODE_LINK_STATUS_GOOD	0
+#define DRM_MODE_LINK_STATUS_BAD	1
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* ✗ Fi.CI.BAT: warning for drm: Add a new connector atomic property for link status
  2016-11-23  1:30 [PATCH RFC] drm: Add a new connector atomic property for link status Manasi Navare
@ 2016-11-23  1:45 ` Patchwork
  2016-11-23  2:27 ` [PATCH RFC] " Sean Paul
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 27+ messages in thread
From: Patchwork @ 2016-11-23  1:45 UTC (permalink / raw)
  To: Navare, Manasi D; +Cc: intel-gfx

== Series Details ==

Series: drm: Add a new connector atomic property for link status
URL   : https://patchwork.freedesktop.org/series/15781/
State : warning

== Summary ==

Series 15781v1 drm: Add a new connector atomic property for link status
https://patchwork.freedesktop.org/api/1.0/series/15781/revisions/1/mbox/

Test drv_module_reload_basic:
                dmesg-warn -> PASS       (fi-skl-6770hq)
Test kms_pipe_crc_basic:
        Subgroup hang-read-crc-pipe-b:
                pass       -> DMESG-WARN (fi-ilk-650)
        Subgroup nonblocking-crc-pipe-a:
                dmesg-warn -> PASS       (fi-ilk-650)

fi-bdw-5557u     total:244  pass:229  dwarn:0   dfail:0   fail:0   skip:15 
fi-bsw-n3050     total:244  pass:204  dwarn:0   dfail:0   fail:0   skip:40 
fi-bxt-t5700     total:244  pass:216  dwarn:0   dfail:0   fail:0   skip:28 
fi-byt-j1900     total:244  pass:216  dwarn:0   dfail:0   fail:0   skip:28 
fi-byt-n2820     total:244  pass:212  dwarn:0   dfail:0   fail:0   skip:32 
fi-hsw-4770      total:244  pass:224  dwarn:0   dfail:0   fail:0   skip:20 
fi-hsw-4770r     total:244  pass:224  dwarn:0   dfail:0   fail:0   skip:20 
fi-ilk-650       total:244  pass:190  dwarn:1   dfail:0   fail:0   skip:53 
fi-ivb-3520m     total:244  pass:222  dwarn:0   dfail:0   fail:0   skip:22 
fi-ivb-3770      total:244  pass:222  dwarn:0   dfail:0   fail:0   skip:22 
fi-kbl-7200u     total:244  pass:222  dwarn:0   dfail:0   fail:0   skip:22 
fi-skl-6260u     total:244  pass:230  dwarn:0   dfail:0   fail:0   skip:14 
fi-skl-6700hq    total:244  pass:223  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6700k     total:244  pass:222  dwarn:1   dfail:0   fail:0   skip:21 
fi-skl-6770hq    total:244  pass:230  dwarn:0   dfail:0   fail:0   skip:14 
fi-snb-2520m     total:244  pass:212  dwarn:0   dfail:0   fail:0   skip:32 
fi-snb-2600      total:244  pass:211  dwarn:0   dfail:0   fail:0   skip:33 

b34f27e00c9a21d2078062da760e24fd4a620391 drm-intel-nightly: 2016y-11m-22d-17h-42m-39s UTC integration manifest
09b9c0a drm: Add a new connector atomic property for link status

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3087/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23  1:30 [PATCH RFC] drm: Add a new connector atomic property for link status Manasi Navare
  2016-11-23  1:45 ` ✗ Fi.CI.BAT: warning for " Patchwork
@ 2016-11-23  2:27 ` Sean Paul
  2016-11-23  8:09   ` Daniel Vetter
  2016-11-23 10:00 ` Daniel Vetter
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 27+ messages in thread
From: Sean Paul @ 2016-11-23  2:27 UTC (permalink / raw)
  To: Manasi Navare; +Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
<manasi.d.navare@intel.com> wrote:
> This is RFC patch for adding a connector link-status property
> and making it atomic by adding it to the drm_connector_state.
> This is to make sure its wired properly in drm_atomic_connector_set_property
> and drm_atomic_connector_get_property functions.
>

Thanks for sending this. We ran into some re-training awkwardness
recently, and I
was hoping for such a patch.

> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>  include/drm/drm_connector.h     | 12 +++++++-
>  include/drm/drm_mode_config.h   |  5 ++++
>  include/uapi/drm/drm_mode.h     |  4 +++
>  5 files changed, 88 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 89737e4..644d19f 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>                  * now?) atomic writes to DPMS property:
>                  */
>                 return -EINVAL;
> +       } else if (property == config->link_status_property) {
> +               state->link_status = val;
> +               return 0;
>         } else if (connector->funcs->atomic_set_property) {
>                 return connector->funcs->atomic_set_property(connector,
>                                 state, property, val);
> @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>                 *val = (state->crtc) ? state->crtc->base.id : 0;
>         } else if (property == config->dpms_property) {
>                 *val = connector->dpms;
> +       } else if (property == config->link_status_property) {
> +               *val = state->link_status;
>         } else if (connector->funcs->atomic_get_property) {
>                 return connector->funcs->atomic_get_property(connector,
>                                 state, property, val);
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 5a45262..4576c9f 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>         drm_object_attach_property(&connector->base,
>                                       config->dpms_property, 0);
>
> +       drm_object_attach_property(&connector->base,
> +                                  config->link_status_property,
> +                                  0);
> +
>         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>         }
> @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>  };
>  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>
> +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
> +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
> +};
> +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> +
>  /**
>   * drm_display_info_set_bus_formats - set the supported bus formats
>   * @info: display info to store bus formats in
> @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>   *     path property the MST manager created. Userspace cannot change this
>   *     property.
>   * TILE:
> - *     Connector tile group property to indicate how a set of DRM connector
> + *      Connector tile group property to indicate how a set of DRM connector

keyboard slip here

>   *     compose together into one logical screen. This is used by both high-res
>   *     external screens (often only using a single cable, but exposing multiple
>   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
> @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>   *     should update this value using drm_mode_connector_set_tile_property().
>   *     Userspace cannot change this property.
> - *
> + * link-status:
> + *      Connector link-status property to indicate the status of link during
> + *      the modeset. The default value of link-status is "GOOD". If something
> + *      fails during modeset, the kernel driver can set this to "BAD", prune
> + *      the mode list based on new link parameters and send a hotplug uevent
> + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> + *      IOCTL and redo a modeset. Drivers should update this value using
> + *      drm_mode_connector_set_link_status_property().
>   * Connectors also have one standardized atomic property:
>   *
>   * CRTC_ID:
> @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>                 return -ENOMEM;
>         dev->mode_config.tile_property = prop;
>
> +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> +                                       drm_link_status_enum_list,
> +                                       ARRAY_SIZE(drm_link_status_enum_list));
> +       if (!prop)
> +               return -ENOMEM;
> +       dev->mode_config.link_status_property = prop;
> +
>         return 0;
>  }
>
> @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>
> +/**
> + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> + * @connector: drm connector
> + * @link_status: new value of link status property (0: Good, 1: Bad)
> + *
> + * In usual working scenario, this link status property will always be set to
> + * "GOOD". If something fails during or after a mode set, the kernel driver should
> + * set this link status property to "BAD" and prune the mode list based on new

Does the mode list really *need* to be pruned? In the case of needing
to re-train a DP link,
it seems like we should be able to set this BAD and keep the modelist
as-is (since the sink
hasn't changed)

> + * information. The caller then needs to send a hotplug uevent for userspace to
> + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.

extra space

> + *
> + * Note that a lot of existing userspace do not handle this property.
> + * Drivers can therefore not rely on userspace to fix up everything and
> + * should try to handle issues (like just re-training a link) without
> + * userspace's intervention. This should only be used when the current mode
> + * fails and userspace must select a different display mode.

Hmm, I suppose this answers my last question. It's too bad we can't
rely on this, since we'll
just end up with each driver rolling their own re-training logic on
top of possibly supporting
this (but probably not, since it's really just overhead). Perhaps this
is an overly pessimistic
view?

> + * The DRM driver can chose to not modify property and keep link status
> + * as "GOOD" always to keep the user experience same as it currently is.
> + *
> + * The reason for adding this property is to handle link training failures, but
> + * it is not limited to DP or link training. For example, if we implement
> + * asynchronous setcrtc, this property can be used to report any failures in that.
> + */
> +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> +                                                uint64_t link_status)
> +{
> +       struct drm_device *dev = connector->dev;
> +
> +       /* Make sure the mutex is grabbed */
> +       lockdep_assert_held(&dev->mode_config.mutex);
> +       connector->link_status = link_status;
> +       drm_object_property_set_value(&connector->base,
> +                                     dev->mode_config.link_status_property,
> +                                     link_status);
> +}
> +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> +
>  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>                                     struct drm_property *property,
>                                     uint64_t value)
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 34f9741..3d513ab 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -213,6 +213,9 @@ struct drm_connector_state {
>
>         struct drm_encoder *best_encoder;
>
> +       /* Connector Link status */
> +       unsigned int link_status;
> +
>         struct drm_atomic_state *state;
>  };
>
> @@ -695,6 +698,12 @@ struct drm_connector {
>         uint8_t num_h_tile, num_v_tile;
>         uint8_t tile_h_loc, tile_v_loc;
>         uint16_t tile_h_size, tile_v_size;
> +
> +       /* Connector Link status
> +        * 0: If the link is Good
> +        * 1: If the link is Bad
> +        */
> +       int link_status;
>  };
>
>  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> -

lost a line here

>  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>                                          const char *path);
>  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>                                             const struct edid *edid);
> +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> +                                                uint64_t link_status);
>
>  /**
>   * struct drm_tile_group - Tile group metadata
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index bf9991b..86faee4 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -431,6 +431,11 @@ struct drm_mode_config {
>          */
>         struct drm_property *tile_property;
>         /**
> +        * @link_status_property: Default connector property for link status
> +        * of a connector
> +        */
> +       struct drm_property *link_status_property;
> +       /**
>          * @plane_type_property: Default plane property to differentiate
>          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>          */
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 728790b..309c478 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -123,6 +123,10 @@
>  #define DRM_MODE_DIRTY_ON       1
>  #define DRM_MODE_DIRTY_ANNOTATE 2
>
> +/* Link Status options */
> +#define DRM_MODE_LINK_STATUS_GOOD      0
> +#define DRM_MODE_LINK_STATUS_BAD       1
> +
>  struct drm_mode_modeinfo {
>         __u32 clock;
>         __u16 hdisplay;
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23  2:27 ` [PATCH RFC] " Sean Paul
@ 2016-11-23  8:09   ` Daniel Vetter
  2016-11-23 14:40     ` Sean Paul
  2016-11-29  0:59     ` Manasi Navare
  0 siblings, 2 replies; 27+ messages in thread
From: Daniel Vetter @ 2016-11-23  8:09 UTC (permalink / raw)
  To: Sean Paul
  Cc: Manasi Navare, Daniel Vetter, Intel Graphics Development, dri-devel

On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
> <manasi.d.navare@intel.com> wrote:
> > This is RFC patch for adding a connector link-status property
> > and making it atomic by adding it to the drm_connector_state.
> > This is to make sure its wired properly in drm_atomic_connector_set_property
> > and drm_atomic_connector_get_property functions.
> >
> 
> Thanks for sending this. We ran into some re-training awkwardness
> recently, and I
> was hoping for such a patch.
> 
> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
> >  include/drm/drm_connector.h     | 12 +++++++-
> >  include/drm/drm_mode_config.h   |  5 ++++
> >  include/uapi/drm/drm_mode.h     |  4 +++
> >  5 files changed, 88 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 89737e4..644d19f 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> >                  * now?) atomic writes to DPMS property:
> >                  */
> >                 return -EINVAL;
> > +       } else if (property == config->link_status_property) {
> > +               state->link_status = val;

I think we should have a check here to make sure userspace never tries to
set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
atomic userspace is supposed to be able to just restore everything to what
it was.

I don't think trying to set it to "BAD" should cause an error though, just
silently keep the link status at "GOOG". So:

	/* Never downgrade from GOOD to BAD on userspace's request here,
	 * only hw issues can do that. */
	if (state->link_status == GOOD)
		return 0;
	state->link_status = val;
	return 0;

> > +               return 0;
> >         } else if (connector->funcs->atomic_set_property) {
> >                 return connector->funcs->atomic_set_property(connector,
> >                                 state, property, val);
> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
> >         } else if (property == config->dpms_property) {
> >                 *val = connector->dpms;
> > +       } else if (property == config->link_status_property) {
> > +               *val = state->link_status;
> >         } else if (connector->funcs->atomic_get_property) {
> >                 return connector->funcs->atomic_get_property(connector,
> >                                 state, property, val);
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 5a45262..4576c9f 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
> >         drm_object_attach_property(&connector->base,
> >                                       config->dpms_property, 0);
> >
> > +       drm_object_attach_property(&connector->base,
> > +                                  config->link_status_property,
> > +                                  0);
> > +
> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
> >         }
> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
> >  };
> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
> >
> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
> > +};
> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> > +
> >  /**
> >   * drm_display_info_set_bus_formats - set the supported bus formats
> >   * @info: display info to store bus formats in
> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >   *     path property the MST manager created. Userspace cannot change this
> >   *     property.
> >   * TILE:
> > - *     Connector tile group property to indicate how a set of DRM connector
> > + *      Connector tile group property to indicate how a set of DRM connector
> 
> keyboard slip here
> 
> >   *     compose together into one logical screen. This is used by both high-res
> >   *     external screens (often only using a single cable, but exposing multiple
> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
> >   *     should update this value using drm_mode_connector_set_tile_property().
> >   *     Userspace cannot change this property.
> > - *
> > + * link-status:
> > + *      Connector link-status property to indicate the status of link during
> > + *      the modeset. The default value of link-status is "GOOD". If something
> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
> > + *      the mode list based on new link parameters and send a hotplug uevent
> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> > + *      IOCTL and redo a modeset. Drivers should update this value using
> > + *      drm_mode_connector_set_link_status_property().
> >   * Connectors also have one standardized atomic property:
> >   *
> >   * CRTC_ID:
> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> >                 return -ENOMEM;
> >         dev->mode_config.tile_property = prop;
> >
> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> > +                                       drm_link_status_enum_list,
> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
> > +       if (!prop)
> > +               return -ENOMEM;
> > +       dev->mode_config.link_status_property = prop;
> > +
> >         return 0;
> >  }
> >
> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >  }
> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
> >
> > +/**
> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> > + * @connector: drm connector
> > + * @link_status: new value of link status property (0: Good, 1: Bad)
> > + *
> > + * In usual working scenario, this link status property will always be set to
> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
> > + * set this link status property to "BAD" and prune the mode list based on new
> 
> Does the mode list really *need* to be pruned? In the case of needing
> to re-train a DP link,
> it seems like we should be able to set this BAD and keep the modelist
> as-is (since the sink
> hasn't changed)

Well, if you prune it with the same constraints as before, no additional
modes will be removed and the same list is there. Pruning here refers to
the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.

We might want to be a bit more explicit here perhaps? Have some good
proposal text to insert?
> 
> > + * information. The caller then needs to send a hotplug uevent for userspace to
> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> 
> extra space
> 
> > + *
> > + * Note that a lot of existing userspace do not handle this property.
> > + * Drivers can therefore not rely on userspace to fix up everything and
> > + * should try to handle issues (like just re-training a link) without
> > + * userspace's intervention. This should only be used when the current mode
> > + * fails and userspace must select a different display mode.
> 
> Hmm, I suppose this answers my last question. It's too bad we can't
> rely on this, since we'll
> just end up with each driver rolling their own re-training logic on
> top of possibly supporting
> this (but probably not, since it's really just overhead). Perhaps this
> is an overly pessimistic
> view?

You can forgo any re-training of course, that should work too. It's just
that DP spec and everyone else seem to recommend to at least do some
minimal effort (or maybe even upfront link training) here. But totally not
doing anything if the link is bad should be ok too (and probably really
simple to implement for drivers, maybe even with a dp_hpd_handler() helper
function which checks link status and set link-status to bad&fires off the
uevent if needed.

Again, do you have some sample prose to add here to clarify this?

Thanks for taking a look at this.

Cheers, Daniel

> > + * The DRM driver can chose to not modify property and keep link status
> > + * as "GOOD" always to keep the user experience same as it currently is.
> > + *
> > + * The reason for adding this property is to handle link training failures, but
> > + * it is not limited to DP or link training. For example, if we implement
> > + * asynchronous setcrtc, this property can be used to report any failures in that.
> > + */
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +                                                uint64_t link_status)
> > +{
> > +       struct drm_device *dev = connector->dev;
> > +
> > +       /* Make sure the mutex is grabbed */
> > +       lockdep_assert_held(&dev->mode_config.mutex);
> > +       connector->link_status = link_status;
> > +       drm_object_property_set_value(&connector->base,
> > +                                     dev->mode_config.link_status_property,
> > +                                     link_status);
> > +}
> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> > +
> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> >                                     struct drm_property *property,
> >                                     uint64_t value)
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index 34f9741..3d513ab 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -213,6 +213,9 @@ struct drm_connector_state {
> >
> >         struct drm_encoder *best_encoder;
> >
> > +       /* Connector Link status */
> > +       unsigned int link_status;
> > +
> >         struct drm_atomic_state *state;
> >  };
> >
> > @@ -695,6 +698,12 @@ struct drm_connector {
> >         uint8_t num_h_tile, num_v_tile;
> >         uint8_t tile_h_loc, tile_v_loc;
> >         uint16_t tile_h_size, tile_v_size;
> > +
> > +       /* Connector Link status
> > +        * 0: If the link is Good
> > +        * 1: If the link is Bad
> > +        */
> > +       int link_status;
> >  };
> >
> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> > -
> 
> lost a line here
> 
> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
> >                                          const char *path);
> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >                                             const struct edid *edid);
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +                                                uint64_t link_status);
> >
> >  /**
> >   * struct drm_tile_group - Tile group metadata
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index bf9991b..86faee4 100644
> > --- a/include/drm/drm_mode_config.h
> > +++ b/include/drm/drm_mode_config.h
> > @@ -431,6 +431,11 @@ struct drm_mode_config {
> >          */
> >         struct drm_property *tile_property;
> >         /**
> > +        * @link_status_property: Default connector property for link status
> > +        * of a connector
> > +        */
> > +       struct drm_property *link_status_property;
> > +       /**
> >          * @plane_type_property: Default plane property to differentiate
> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
> >          */
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 728790b..309c478 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -123,6 +123,10 @@
> >  #define DRM_MODE_DIRTY_ON       1
> >  #define DRM_MODE_DIRTY_ANNOTATE 2
> >
> > +/* Link Status options */
> > +#define DRM_MODE_LINK_STATUS_GOOD      0
> > +#define DRM_MODE_LINK_STATUS_BAD       1
> > +
> >  struct drm_mode_modeinfo {
> >         __u32 clock;
> >         __u16 hdisplay;
> > --
> > 1.9.1
> >
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23  1:30 [PATCH RFC] drm: Add a new connector atomic property for link status Manasi Navare
  2016-11-23  1:45 ` ✗ Fi.CI.BAT: warning for " Patchwork
  2016-11-23  2:27 ` [PATCH RFC] " Sean Paul
@ 2016-11-23 10:00 ` Daniel Vetter
  2016-11-23 19:07   ` Manasi Navare
  2016-11-24  2:38 ` [PATCH RFC v2] " Manasi Navare
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 27+ messages in thread
From: Daniel Vetter @ 2016-11-23 10:00 UTC (permalink / raw)
  To: Manasi Navare; +Cc: Daniel Vetter, intel-gfx, dri-devel

On Tue, Nov 22, 2016 at 05:30:21PM -0800, Manasi Navare wrote:
> This is RFC patch for adding a connector link-status property
> and making it atomic by adding it to the drm_connector_state.
> This is to make sure its wired properly in drm_atomic_connector_set_property
> and drm_atomic_connector_get_property functions.
> 
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>  include/drm/drm_connector.h     | 12 +++++++-
>  include/drm/drm_mode_config.h   |  5 ++++
>  include/uapi/drm/drm_mode.h     |  4 +++
>  5 files changed, 88 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 89737e4..644d19f 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>  		 * now?) atomic writes to DPMS property:
>  		 */
>  		return -EINVAL;
> +	} else if (property == config->link_status_property) {
> +		state->link_status = val;
> +		return 0;
>  	} else if (connector->funcs->atomic_set_property) {
>  		return connector->funcs->atomic_set_property(connector,
>  				state, property, val);
> @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>  		*val = (state->crtc) ? state->crtc->base.id : 0;
>  	} else if (property == config->dpms_property) {
>  		*val = connector->dpms;
> +	} else if (property == config->link_status_property) {
> +		*val = state->link_status;
>  	} else if (connector->funcs->atomic_get_property) {
>  		return connector->funcs->atomic_get_property(connector,
>  				state, property, val);
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 5a45262..4576c9f 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>  	drm_object_attach_property(&connector->base,
>  				      config->dpms_property, 0);
>  
> +	drm_object_attach_property(&connector->base,
> +				   config->link_status_property,
> +				   0);
> +
>  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>  		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>  	}
> @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>  };
>  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>  
> +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> +	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
> +	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
> +};
> +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> +
>  /**
>   * drm_display_info_set_bus_formats - set the supported bus formats
>   * @info: display info to store bus formats in
> @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>   * 	path property the MST manager created. Userspace cannot change this
>   * 	property.
>   * TILE:
> - * 	Connector tile group property to indicate how a set of DRM connector
> + *      Connector tile group property to indicate how a set of DRM connector
>   * 	compose together into one logical screen. This is used by both high-res
>   * 	external screens (often only using a single cable, but exposing multiple
>   * 	DP MST sinks), or high-res integrated panels (like dual-link DSI) which
> @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>   * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>   * 	should update this value using drm_mode_connector_set_tile_property().
>   * 	Userspace cannot change this property.
> - *
> + * link-status:
> + *      Connector link-status property to indicate the status of link during
> + *      the modeset. The default value of link-status is "GOOD". If something
> + *      fails during modeset, the kernel driver can set this to "BAD", prune
> + *      the mode list based on new link parameters and send a hotplug uevent
> + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> + *      IOCTL and redo a modeset. Drivers should update this value using
> + *      drm_mode_connector_set_link_status_property().
>   * Connectors also have one standardized atomic property:
>   *
>   * CRTC_ID:
> @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>  		return -ENOMEM;
>  	dev->mode_config.tile_property = prop;
>  
> +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> +					drm_link_status_enum_list,
> +					ARRAY_SIZE(drm_link_status_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +	dev->mode_config.link_status_property = prop;
> +
>  	return 0;
>  }
>  
> @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>  
> +/**
> + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> + * @connector: drm connector
> + * @link_status: new value of link status property (0: Good, 1: Bad)
> + *
> + * In usual working scenario, this link status property will always be set to
> + * "GOOD". If something fails during or after a mode set, the kernel driver should
> + * set this link status property to "BAD" and prune the mode list based on new
> + * information. The caller then needs to send a hotplug uevent for userspace to
> + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> + *
> + * Note that a lot of existing userspace do not handle this property.
> + * Drivers can therefore not rely on userspace to fix up everything and
> + * should try to handle issues (like just re-training a link) without
> + * userspace's intervention. This should only be used when the current mode
> + * fails and userspace must select a different display mode.
> + * The DRM driver can chose to not modify property and keep link status
> + * as "GOOD" always to keep the user experience same as it currently is.
> + *
> + * The reason for adding this property is to handle link training failures, but
> + * it is not limited to DP or link training. For example, if we implement
> + * asynchronous setcrtc, this property can be used to report any failures in that.
> + */
> +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> +						 uint64_t link_status)
> +{
> +	struct drm_device *dev = connector->dev;
> +
> +	/* Make sure the mutex is grabbed */
> +	lockdep_assert_held(&dev->mode_config.mutex);

For atomic the lock we need is dev->mode_config.connection_mutex); Maybe
we should just grab that here, from a quick check it shouldn't result in a
deadlock.

> +	connector->link_status = link_status;

You need to set connector->state->link_status here for an atomic property.

> +	drm_object_property_set_value(&connector->base,
> +				      dev->mode_config.link_status_property,
> +				      link_status);

And this here isn't needed anymore with atomic.

> +}
> +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> +
>  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>  				    struct drm_property *property,
>  				    uint64_t value)
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 34f9741..3d513ab 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -213,6 +213,9 @@ struct drm_connector_state {
>  
>  	struct drm_encoder *best_encoder;
>  
> +	/* Connector Link status */
> +	unsigned int link_status;

enum drm_link_status {
	DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD;
	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_GOOD;
};

This way you don't need a comment explaing that 0 is good and 1 is bad.

> +
>  	struct drm_atomic_state *state;
>  };
>  
> @@ -695,6 +698,12 @@ struct drm_connector {
>  	uint8_t num_h_tile, num_v_tile;
>  	uint8_t tile_h_loc, tile_v_loc;
>  	uint16_t tile_h_size, tile_v_size;
> +
> +	/* Connector Link status
> +	 * 0: If the link is Good
> +	 * 1: If the link is Bad
> +	 */
> +	int link_status;

This one needs to go, we don't want to duplicate this information.

>  };
>  
>  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> -
>  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>  					 const char *path);
>  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>  					    const struct edid *edid);
> +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> +						 uint64_t link_status);
>  
>  /**
>   * struct drm_tile_group - Tile group metadata
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index bf9991b..86faee4 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -431,6 +431,11 @@ struct drm_mode_config {
>  	 */
>  	struct drm_property *tile_property;
>  	/**
> +	 * @link_status_property: Default connector property for link status
> +	 * of a connector
> +	 */
> +	struct drm_property *link_status_property;
> +	/**
>  	 * @plane_type_property: Default plane property to differentiate
>  	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>  	 */
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 728790b..309c478 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -123,6 +123,10 @@
>  #define DRM_MODE_DIRTY_ON       1
>  #define DRM_MODE_DIRTY_ANNOTATE 2
>  
> +/* Link Status options */
> +#define DRM_MODE_LINK_STATUS_GOOD	0
> +#define DRM_MODE_LINK_STATUS_BAD	1

The change to reset link_status to good for SETCRTC seems to be missing.
Something like the below (totally untested) should get the job done.

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 494680c9056e..5f47049d611e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2258,6 +2258,8 @@ static int update_output_state(struct drm_atomic_state *state,
 								NULL);
 			if (ret)
 				return ret;
+
+			conn_state->link_status = DRM_LINK_STATUS_GOOD;
 		}
 	}
 
Small exercise for you: Follow the call chain of this function and figure
out how it works. And let's hope I did it right and it does work ;-)

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23  8:09   ` Daniel Vetter
@ 2016-11-23 14:40     ` Sean Paul
  2016-11-23 15:15       ` Jani Nikula
  2016-11-29  0:59     ` Manasi Navare
  1 sibling, 1 reply; 27+ messages in thread
From: Sean Paul @ 2016-11-23 14:40 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Manasi Navare, Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, Nov 23, 2016 at 3:09 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>> <manasi.d.navare@intel.com> wrote:
>> > This is RFC patch for adding a connector link-status property
>> > and making it atomic by adding it to the drm_connector_state.
>> > This is to make sure its wired properly in drm_atomic_connector_set_property
>> > and drm_atomic_connector_get_property functions.
>> >
>>
>> Thanks for sending this. We ran into some re-training awkwardness
>> recently, and I
>> was hoping for such a patch.
>>
>> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> > Cc: Daniel Vetter <daniel.vetter@intel.com>
>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>> > ---
>> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>> >  include/drm/drm_connector.h     | 12 +++++++-
>> >  include/drm/drm_mode_config.h   |  5 ++++
>> >  include/uapi/drm/drm_mode.h     |  4 +++
>> >  5 files changed, 88 insertions(+), 3 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> > index 89737e4..644d19f 100644
>> > --- a/drivers/gpu/drm/drm_atomic.c
>> > +++ b/drivers/gpu/drm/drm_atomic.c
>> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>> >                  * now?) atomic writes to DPMS property:
>> >                  */
>> >                 return -EINVAL;
>> > +       } else if (property == config->link_status_property) {
>> > +               state->link_status = val;
>
> I think we should have a check here to make sure userspace never tries to
> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
> atomic userspace is supposed to be able to just restore everything to what
> it was.
>
> I don't think trying to set it to "BAD" should cause an error though, just
> silently keep the link status at "GOOG". So:
>
>         /* Never downgrade from GOOD to BAD on userspace's request here,
>          * only hw issues can do that. */
>         if (state->link_status == GOOD)
>                 return 0;

Can we return an error if the transition is invalid?

>         state->link_status = val;
>         return 0;
>
>> > +               return 0;
>> >         } else if (connector->funcs->atomic_set_property) {
>> >                 return connector->funcs->atomic_set_property(connector,
>> >                                 state, property, val);
>> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>> >         } else if (property == config->dpms_property) {
>> >                 *val = connector->dpms;
>> > +       } else if (property == config->link_status_property) {
>> > +               *val = state->link_status;
>> >         } else if (connector->funcs->atomic_get_property) {
>> >                 return connector->funcs->atomic_get_property(connector,
>> >                                 state, property, val);
>> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>> > index 5a45262..4576c9f 100644
>> > --- a/drivers/gpu/drm/drm_connector.c
>> > +++ b/drivers/gpu/drm/drm_connector.c
>> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>> >         drm_object_attach_property(&connector->base,
>> >                                       config->dpms_property, 0);
>> >
>> > +       drm_object_attach_property(&connector->base,
>> > +                                  config->link_status_property,
>> > +                                  0);
>> > +
>> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>> >         }
>> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>> >  };
>> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>> >
>> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>> > +};
>> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>> > +
>> >  /**
>> >   * drm_display_info_set_bus_formats - set the supported bus formats
>> >   * @info: display info to store bus formats in
>> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> >   *     path property the MST manager created. Userspace cannot change this
>> >   *     property.
>> >   * TILE:
>> > - *     Connector tile group property to indicate how a set of DRM connector
>> > + *      Connector tile group property to indicate how a set of DRM connector
>>
>> keyboard slip here
>>
>> >   *     compose together into one logical screen. This is used by both high-res
>> >   *     external screens (often only using a single cable, but exposing multiple
>> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>> >   *     should update this value using drm_mode_connector_set_tile_property().
>> >   *     Userspace cannot change this property.
>> > - *
>> > + * link-status:
>> > + *      Connector link-status property to indicate the status of link during
>> > + *      the modeset. The default value of link-status is "GOOD". If something
>> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>> > + *      the mode list based on new link parameters and send a hotplug uevent
>> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>> > + *      IOCTL and redo a modeset. Drivers should update this value using
>> > + *      drm_mode_connector_set_link_status_property().
>> >   * Connectors also have one standardized atomic property:
>> >   *
>> >   * CRTC_ID:
>> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>> >                 return -ENOMEM;
>> >         dev->mode_config.tile_property = prop;
>> >
>> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>> > +                                       drm_link_status_enum_list,
>> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>> > +       if (!prop)
>> > +               return -ENOMEM;
>> > +       dev->mode_config.link_status_property = prop;
>> > +
>> >         return 0;
>> >  }
>> >
>> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>> >  }
>> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>> >
>> > +/**
>> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>> > + * @connector: drm connector
>> > + * @link_status: new value of link status property (0: Good, 1: Bad)
>> > + *
>> > + * In usual working scenario, this link status property will always be set to
>> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>> > + * set this link status property to "BAD" and prune the mode list based on new
>>
>> Does the mode list really *need* to be pruned? In the case of needing
>> to re-train a DP link,
>> it seems like we should be able to set this BAD and keep the modelist
>> as-is (since the sink
>> hasn't changed)
>
> Well, if you prune it with the same constraints as before, no additional
> modes will be removed and the same list is there. Pruning here refers to
> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>
> We might want to be a bit more explicit here perhaps? Have some good
> proposal text to insert?

Ah, hmm, I hadn't equated this prune to the normal drm_connector
prune_invalid. I suppose the "based on new information" is what did
it. It seems like the mode_valid pruning will happen automagically
when userspace realizes the connection is BAD and asks for a new mode
list. So is it worth even mentioning pruning the mode list?

>>
>> > + * information. The caller then needs to send a hotplug uevent for userspace to
>> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>>
>> extra space
>>
>> > + *
>> > + * Note that a lot of existing userspace do not handle this property.
>> > + * Drivers can therefore not rely on userspace to fix up everything and
>> > + * should try to handle issues (like just re-training a link) without
>> > + * userspace's intervention. This should only be used when the current mode
>> > + * fails and userspace must select a different display mode.
>>
>> Hmm, I suppose this answers my last question. It's too bad we can't
>> rely on this, since we'll
>> just end up with each driver rolling their own re-training logic on
>> top of possibly supporting
>> this (but probably not, since it's really just overhead). Perhaps this
>> is an overly pessimistic
>> view?
>
> You can forgo any re-training of course, that should work too. It's just
> that DP spec and everyone else seem to recommend to at least do some
> minimal effort (or maybe even upfront link training) here. But totally not
> doing anything if the link is bad should be ok too (and probably really
> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
> function which checks link status and set link-status to bad&fires off the
> uevent if needed.
>
> Again, do you have some sample prose to add here to clarify this?
>

I don't think it's merely a matter of clarifying the comment, tbh.
Without relying on userspace to fix us, there's not much point in
exposing the property in the first place.

As a driver author, I need to decide whether I want re-training to
work properly. If I do, I need to handroll it in my driver since I
can't rely on userspace, at which point, implementing the property
isn't meaningful. If I don't care about it being bulletproof, I can
expose the property and let userspace fix me if they know how.

So I'd prefer to have the helper be a hybrid between this patch and
the previous one that did a full modeset under the covers (perhaps
with a client cap or similar to let us know which path to trust). That
way I can call the helper from my driver and know that I'm going to be
re-trained either way.

Sean


> Thanks for taking a look at this.
>
> Cheers, Daniel
>
>> > + * The DRM driver can chose to not modify property and keep link status
>> > + * as "GOOD" always to keep the user experience same as it currently is.
>> > + *
>> > + * The reason for adding this property is to handle link training failures, but
>> > + * it is not limited to DP or link training. For example, if we implement
>> > + * asynchronous setcrtc, this property can be used to report any failures in that.
>> > + */
>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>> > +                                                uint64_t link_status)
>> > +{
>> > +       struct drm_device *dev = connector->dev;
>> > +
>> > +       /* Make sure the mutex is grabbed */
>> > +       lockdep_assert_held(&dev->mode_config.mutex);
>> > +       connector->link_status = link_status;
>> > +       drm_object_property_set_value(&connector->base,
>> > +                                     dev->mode_config.link_status_property,
>> > +                                     link_status);
>> > +}
>> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>> > +
>> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>> >                                     struct drm_property *property,
>> >                                     uint64_t value)
>> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>> > index 34f9741..3d513ab 100644
>> > --- a/include/drm/drm_connector.h
>> > +++ b/include/drm/drm_connector.h
>> > @@ -213,6 +213,9 @@ struct drm_connector_state {
>> >
>> >         struct drm_encoder *best_encoder;
>> >
>> > +       /* Connector Link status */
>> > +       unsigned int link_status;
>> > +
>> >         struct drm_atomic_state *state;
>> >  };
>> >
>> > @@ -695,6 +698,12 @@ struct drm_connector {
>> >         uint8_t num_h_tile, num_v_tile;
>> >         uint8_t tile_h_loc, tile_v_loc;
>> >         uint16_t tile_h_size, tile_v_size;
>> > +
>> > +       /* Connector Link status
>> > +        * 0: If the link is Good
>> > +        * 1: If the link is Bad
>> > +        */
>> > +       int link_status;
>> >  };
>> >
>> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>> > -
>>
>> lost a line here
>>
>> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>> >                                          const char *path);
>> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>> >                                             const struct edid *edid);
>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>> > +                                                uint64_t link_status);
>> >
>> >  /**
>> >   * struct drm_tile_group - Tile group metadata
>> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>> > index bf9991b..86faee4 100644
>> > --- a/include/drm/drm_mode_config.h
>> > +++ b/include/drm/drm_mode_config.h
>> > @@ -431,6 +431,11 @@ struct drm_mode_config {
>> >          */
>> >         struct drm_property *tile_property;
>> >         /**
>> > +        * @link_status_property: Default connector property for link status
>> > +        * of a connector
>> > +        */
>> > +       struct drm_property *link_status_property;
>> > +       /**
>> >          * @plane_type_property: Default plane property to differentiate
>> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>> >          */
>> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>> > index 728790b..309c478 100644
>> > --- a/include/uapi/drm/drm_mode.h
>> > +++ b/include/uapi/drm/drm_mode.h
>> > @@ -123,6 +123,10 @@
>> >  #define DRM_MODE_DIRTY_ON       1
>> >  #define DRM_MODE_DIRTY_ANNOTATE 2
>> >
>> > +/* Link Status options */
>> > +#define DRM_MODE_LINK_STATUS_GOOD      0
>> > +#define DRM_MODE_LINK_STATUS_BAD       1
>> > +
>> >  struct drm_mode_modeinfo {
>> >         __u32 clock;
>> >         __u16 hdisplay;
>> > --
>> > 1.9.1
>> >
>> > _______________________________________________
>> > dri-devel mailing list
>> > dri-devel@lists.freedesktop.org
>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 14:40     ` Sean Paul
@ 2016-11-23 15:15       ` Jani Nikula
  2016-11-23 15:32         ` Sean Paul
  0 siblings, 1 reply; 27+ messages in thread
From: Jani Nikula @ 2016-11-23 15:15 UTC (permalink / raw)
  To: Sean Paul, Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
> On Wed, Nov 23, 2016 at 3:09 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>>> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>>> <manasi.d.navare@intel.com> wrote:
>>> > This is RFC patch for adding a connector link-status property
>>> > and making it atomic by adding it to the drm_connector_state.
>>> > This is to make sure its wired properly in drm_atomic_connector_set_property
>>> > and drm_atomic_connector_get_property functions.
>>> >
>>>
>>> Thanks for sending this. We ran into some re-training awkwardness
>>> recently, and I
>>> was hoping for such a patch.
>>>
>>> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>>> > Cc: Daniel Vetter <daniel.vetter@intel.com>
>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>>> > ---
>>> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>>> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>>> >  include/drm/drm_connector.h     | 12 +++++++-
>>> >  include/drm/drm_mode_config.h   |  5 ++++
>>> >  include/uapi/drm/drm_mode.h     |  4 +++
>>> >  5 files changed, 88 insertions(+), 3 deletions(-)
>>> >
>>> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>>> > index 89737e4..644d19f 100644
>>> > --- a/drivers/gpu/drm/drm_atomic.c
>>> > +++ b/drivers/gpu/drm/drm_atomic.c
>>> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>>> >                  * now?) atomic writes to DPMS property:
>>> >                  */
>>> >                 return -EINVAL;
>>> > +       } else if (property == config->link_status_property) {
>>> > +               state->link_status = val;
>>
>> I think we should have a check here to make sure userspace never tries to
>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
>> atomic userspace is supposed to be able to just restore everything to what
>> it was.
>>
>> I don't think trying to set it to "BAD" should cause an error though, just
>> silently keep the link status at "GOOG". So:
>>
>>         /* Never downgrade from GOOD to BAD on userspace's request here,
>>          * only hw issues can do that. */
>>         if (state->link_status == GOOD)
>>                 return 0;
>
> Can we return an error if the transition is invalid?
>
>>         state->link_status = val;
>>         return 0;
>>
>>> > +               return 0;
>>> >         } else if (connector->funcs->atomic_set_property) {
>>> >                 return connector->funcs->atomic_set_property(connector,
>>> >                                 state, property, val);
>>> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>>> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>>> >         } else if (property == config->dpms_property) {
>>> >                 *val = connector->dpms;
>>> > +       } else if (property == config->link_status_property) {
>>> > +               *val = state->link_status;
>>> >         } else if (connector->funcs->atomic_get_property) {
>>> >                 return connector->funcs->atomic_get_property(connector,
>>> >                                 state, property, val);
>>> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>>> > index 5a45262..4576c9f 100644
>>> > --- a/drivers/gpu/drm/drm_connector.c
>>> > +++ b/drivers/gpu/drm/drm_connector.c
>>> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>>> >         drm_object_attach_property(&connector->base,
>>> >                                       config->dpms_property, 0);
>>> >
>>> > +       drm_object_attach_property(&connector->base,
>>> > +                                  config->link_status_property,
>>> > +                                  0);
>>> > +
>>> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>>> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>>> >         }
>>> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>>> >  };
>>> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>>> >
>>> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>>> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>>> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>>> > +};
>>> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>>> > +
>>> >  /**
>>> >   * drm_display_info_set_bus_formats - set the supported bus formats
>>> >   * @info: display info to store bus formats in
>>> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>> >   *     path property the MST manager created. Userspace cannot change this
>>> >   *     property.
>>> >   * TILE:
>>> > - *     Connector tile group property to indicate how a set of DRM connector
>>> > + *      Connector tile group property to indicate how a set of DRM connector
>>>
>>> keyboard slip here
>>>
>>> >   *     compose together into one logical screen. This is used by both high-res
>>> >   *     external screens (often only using a single cable, but exposing multiple
>>> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>>> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>>> >   *     should update this value using drm_mode_connector_set_tile_property().
>>> >   *     Userspace cannot change this property.
>>> > - *
>>> > + * link-status:
>>> > + *      Connector link-status property to indicate the status of link during
>>> > + *      the modeset. The default value of link-status is "GOOD". If something
>>> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>>> > + *      the mode list based on new link parameters and send a hotplug uevent
>>> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>>> > + *      IOCTL and redo a modeset. Drivers should update this value using
>>> > + *      drm_mode_connector_set_link_status_property().
>>> >   * Connectors also have one standardized atomic property:
>>> >   *
>>> >   * CRTC_ID:
>>> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>>> >                 return -ENOMEM;
>>> >         dev->mode_config.tile_property = prop;
>>> >
>>> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>>> > +                                       drm_link_status_enum_list,
>>> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>>> > +       if (!prop)
>>> > +               return -ENOMEM;
>>> > +       dev->mode_config.link_status_property = prop;
>>> > +
>>> >         return 0;
>>> >  }
>>> >
>>> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>> >  }
>>> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>>> >
>>> > +/**
>>> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>>> > + * @connector: drm connector
>>> > + * @link_status: new value of link status property (0: Good, 1: Bad)
>>> > + *
>>> > + * In usual working scenario, this link status property will always be set to
>>> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>>> > + * set this link status property to "BAD" and prune the mode list based on new
>>>
>>> Does the mode list really *need* to be pruned? In the case of needing
>>> to re-train a DP link,
>>> it seems like we should be able to set this BAD and keep the modelist
>>> as-is (since the sink
>>> hasn't changed)
>>
>> Well, if you prune it with the same constraints as before, no additional
>> modes will be removed and the same list is there. Pruning here refers to
>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>>
>> We might want to be a bit more explicit here perhaps? Have some good
>> proposal text to insert?
>
> Ah, hmm, I hadn't equated this prune to the normal drm_connector
> prune_invalid. I suppose the "based on new information" is what did
> it. It seems like the mode_valid pruning will happen automagically
> when userspace realizes the connection is BAD and asks for a new mode
> list. So is it worth even mentioning pruning the mode list?
>
>>>
>>> > + * information. The caller then needs to send a hotplug uevent for userspace to
>>> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>>>
>>> extra space
>>>
>>> > + *
>>> > + * Note that a lot of existing userspace do not handle this property.
>>> > + * Drivers can therefore not rely on userspace to fix up everything and
>>> > + * should try to handle issues (like just re-training a link) without
>>> > + * userspace's intervention. This should only be used when the current mode
>>> > + * fails and userspace must select a different display mode.
>>>
>>> Hmm, I suppose this answers my last question. It's too bad we can't
>>> rely on this, since we'll
>>> just end up with each driver rolling their own re-training logic on
>>> top of possibly supporting
>>> this (but probably not, since it's really just overhead). Perhaps this
>>> is an overly pessimistic
>>> view?
>>
>> You can forgo any re-training of course, that should work too. It's just
>> that DP spec and everyone else seem to recommend to at least do some
>> minimal effort (or maybe even upfront link training) here. But totally not
>> doing anything if the link is bad should be ok too (and probably really
>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
>> function which checks link status and set link-status to bad&fires off the
>> uevent if needed.
>>
>> Again, do you have some sample prose to add here to clarify this?
>>
>
> I don't think it's merely a matter of clarifying the comment, tbh.
> Without relying on userspace to fix us, there's not much point in
> exposing the property in the first place.
>
> As a driver author, I need to decide whether I want re-training to
> work properly. If I do, I need to handroll it in my driver since I
> can't rely on userspace, at which point, implementing the property
> isn't meaningful. If I don't care about it being bulletproof, I can
> expose the property and let userspace fix me if they know how.
>
> So I'd prefer to have the helper be a hybrid between this patch and
> the previous one that did a full modeset under the covers (perhaps
> with a client cap or similar to let us know which path to trust). That
> way I can call the helper from my driver and know that I'm going to be
> re-trained either way.

If your driver is able to handle everything in kernel, then do so by all
means. If it can't, defer to userspace, which may or may not fix stuff,
depending on whether it looks at the property. If the userspace doesn't
do anything, things will be just as good or bad as they are currently,
before this property.

This allows the drivers to choose how much they can/want to do in
kernel, and what they defer to userspace.

BR,
Jani.



>
> Sean
>
>
>> Thanks for taking a look at this.
>>
>> Cheers, Daniel
>>
>>> > + * The DRM driver can chose to not modify property and keep link status
>>> > + * as "GOOD" always to keep the user experience same as it currently is.
>>> > + *
>>> > + * The reason for adding this property is to handle link training failures, but
>>> > + * it is not limited to DP or link training. For example, if we implement
>>> > + * asynchronous setcrtc, this property can be used to report any failures in that.
>>> > + */
>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>> > +                                                uint64_t link_status)
>>> > +{
>>> > +       struct drm_device *dev = connector->dev;
>>> > +
>>> > +       /* Make sure the mutex is grabbed */
>>> > +       lockdep_assert_held(&dev->mode_config.mutex);
>>> > +       connector->link_status = link_status;
>>> > +       drm_object_property_set_value(&connector->base,
>>> > +                                     dev->mode_config.link_status_property,
>>> > +                                     link_status);
>>> > +}
>>> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>>> > +
>>> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>>> >                                     struct drm_property *property,
>>> >                                     uint64_t value)
>>> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>>> > index 34f9741..3d513ab 100644
>>> > --- a/include/drm/drm_connector.h
>>> > +++ b/include/drm/drm_connector.h
>>> > @@ -213,6 +213,9 @@ struct drm_connector_state {
>>> >
>>> >         struct drm_encoder *best_encoder;
>>> >
>>> > +       /* Connector Link status */
>>> > +       unsigned int link_status;
>>> > +
>>> >         struct drm_atomic_state *state;
>>> >  };
>>> >
>>> > @@ -695,6 +698,12 @@ struct drm_connector {
>>> >         uint8_t num_h_tile, num_v_tile;
>>> >         uint8_t tile_h_loc, tile_v_loc;
>>> >         uint16_t tile_h_size, tile_v_size;
>>> > +
>>> > +       /* Connector Link status
>>> > +        * 0: If the link is Good
>>> > +        * 1: If the link is Bad
>>> > +        */
>>> > +       int link_status;
>>> >  };
>>> >
>>> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>>> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>>> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>>> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>>> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>>> > -
>>>
>>> lost a line here
>>>
>>> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>>> >                                          const char *path);
>>> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>>> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>> >                                             const struct edid *edid);
>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>> > +                                                uint64_t link_status);
>>> >
>>> >  /**
>>> >   * struct drm_tile_group - Tile group metadata
>>> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>>> > index bf9991b..86faee4 100644
>>> > --- a/include/drm/drm_mode_config.h
>>> > +++ b/include/drm/drm_mode_config.h
>>> > @@ -431,6 +431,11 @@ struct drm_mode_config {
>>> >          */
>>> >         struct drm_property *tile_property;
>>> >         /**
>>> > +        * @link_status_property: Default connector property for link status
>>> > +        * of a connector
>>> > +        */
>>> > +       struct drm_property *link_status_property;
>>> > +       /**
>>> >          * @plane_type_property: Default plane property to differentiate
>>> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>>> >          */
>>> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>>> > index 728790b..309c478 100644
>>> > --- a/include/uapi/drm/drm_mode.h
>>> > +++ b/include/uapi/drm/drm_mode.h
>>> > @@ -123,6 +123,10 @@
>>> >  #define DRM_MODE_DIRTY_ON       1
>>> >  #define DRM_MODE_DIRTY_ANNOTATE 2
>>> >
>>> > +/* Link Status options */
>>> > +#define DRM_MODE_LINK_STATUS_GOOD      0
>>> > +#define DRM_MODE_LINK_STATUS_BAD       1
>>> > +
>>> >  struct drm_mode_modeinfo {
>>> >         __u32 clock;
>>> >         __u16 hdisplay;
>>> > --
>>> > 1.9.1
>>> >
>>> > _______________________________________________
>>> > dri-devel mailing list
>>> > dri-devel@lists.freedesktop.org
>>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>> _______________________________________________
>>> dri-devel mailing list
>>> dri-devel@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>> --
>> Daniel Vetter
>> Software Engineer, Intel Corporation
>> http://blog.ffwll.ch
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 15:15       ` Jani Nikula
@ 2016-11-23 15:32         ` Sean Paul
  2016-11-23 15:43           ` Ville Syrjälä
  2016-11-23 15:52           ` Jani Nikula
  0 siblings, 2 replies; 27+ messages in thread
From: Sean Paul @ 2016-11-23 15:32 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Manasi Navare, Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, Nov 23, 2016 at 10:15 AM, Jani Nikula
<jani.nikula@linux.intel.com> wrote:
> On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
>> On Wed, Nov 23, 2016 at 3:09 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>>>> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>>>> <manasi.d.navare@intel.com> wrote:
>>>> > This is RFC patch for adding a connector link-status property
>>>> > and making it atomic by adding it to the drm_connector_state.
>>>> > This is to make sure its wired properly in drm_atomic_connector_set_property
>>>> > and drm_atomic_connector_get_property functions.
>>>> >
>>>>
>>>> Thanks for sending this. We ran into some re-training awkwardness
>>>> recently, and I
>>>> was hoping for such a patch.
>>>>
>>>> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>>>> > Cc: Daniel Vetter <daniel.vetter@intel.com>
>>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>>> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>>>> > ---
>>>> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>>>> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>>>> >  include/drm/drm_connector.h     | 12 +++++++-
>>>> >  include/drm/drm_mode_config.h   |  5 ++++
>>>> >  include/uapi/drm/drm_mode.h     |  4 +++
>>>> >  5 files changed, 88 insertions(+), 3 deletions(-)
>>>> >
>>>> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>>>> > index 89737e4..644d19f 100644
>>>> > --- a/drivers/gpu/drm/drm_atomic.c
>>>> > +++ b/drivers/gpu/drm/drm_atomic.c
>>>> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>>>> >                  * now?) atomic writes to DPMS property:
>>>> >                  */
>>>> >                 return -EINVAL;
>>>> > +       } else if (property == config->link_status_property) {
>>>> > +               state->link_status = val;
>>>
>>> I think we should have a check here to make sure userspace never tries to
>>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
>>> atomic userspace is supposed to be able to just restore everything to what
>>> it was.
>>>
>>> I don't think trying to set it to "BAD" should cause an error though, just
>>> silently keep the link status at "GOOG". So:
>>>
>>>         /* Never downgrade from GOOD to BAD on userspace's request here,
>>>          * only hw issues can do that. */
>>>         if (state->link_status == GOOD)
>>>                 return 0;
>>
>> Can we return an error if the transition is invalid?
>>
>>>         state->link_status = val;
>>>         return 0;
>>>
>>>> > +               return 0;
>>>> >         } else if (connector->funcs->atomic_set_property) {
>>>> >                 return connector->funcs->atomic_set_property(connector,
>>>> >                                 state, property, val);
>>>> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>>>> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>>>> >         } else if (property == config->dpms_property) {
>>>> >                 *val = connector->dpms;
>>>> > +       } else if (property == config->link_status_property) {
>>>> > +               *val = state->link_status;
>>>> >         } else if (connector->funcs->atomic_get_property) {
>>>> >                 return connector->funcs->atomic_get_property(connector,
>>>> >                                 state, property, val);
>>>> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>>>> > index 5a45262..4576c9f 100644
>>>> > --- a/drivers/gpu/drm/drm_connector.c
>>>> > +++ b/drivers/gpu/drm/drm_connector.c
>>>> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>>>> >         drm_object_attach_property(&connector->base,
>>>> >                                       config->dpms_property, 0);
>>>> >
>>>> > +       drm_object_attach_property(&connector->base,
>>>> > +                                  config->link_status_property,
>>>> > +                                  0);
>>>> > +
>>>> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>>>> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>>>> >         }
>>>> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>>>> >  };
>>>> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>>>> >
>>>> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>>>> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>>>> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>>>> > +};
>>>> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>>>> > +
>>>> >  /**
>>>> >   * drm_display_info_set_bus_formats - set the supported bus formats
>>>> >   * @info: display info to store bus formats in
>>>> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>>> >   *     path property the MST manager created. Userspace cannot change this
>>>> >   *     property.
>>>> >   * TILE:
>>>> > - *     Connector tile group property to indicate how a set of DRM connector
>>>> > + *      Connector tile group property to indicate how a set of DRM connector
>>>>
>>>> keyboard slip here
>>>>
>>>> >   *     compose together into one logical screen. This is used by both high-res
>>>> >   *     external screens (often only using a single cable, but exposing multiple
>>>> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>>>> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>>> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>>>> >   *     should update this value using drm_mode_connector_set_tile_property().
>>>> >   *     Userspace cannot change this property.
>>>> > - *
>>>> > + * link-status:
>>>> > + *      Connector link-status property to indicate the status of link during
>>>> > + *      the modeset. The default value of link-status is "GOOD". If something
>>>> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>>>> > + *      the mode list based on new link parameters and send a hotplug uevent
>>>> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>>>> > + *      IOCTL and redo a modeset. Drivers should update this value using
>>>> > + *      drm_mode_connector_set_link_status_property().
>>>> >   * Connectors also have one standardized atomic property:
>>>> >   *
>>>> >   * CRTC_ID:
>>>> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>>>> >                 return -ENOMEM;
>>>> >         dev->mode_config.tile_property = prop;
>>>> >
>>>> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>>>> > +                                       drm_link_status_enum_list,
>>>> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>>>> > +       if (!prop)
>>>> > +               return -ENOMEM;
>>>> > +       dev->mode_config.link_status_property = prop;
>>>> > +
>>>> >         return 0;
>>>> >  }
>>>> >
>>>> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>>> >  }
>>>> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>>>> >
>>>> > +/**
>>>> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>>>> > + * @connector: drm connector
>>>> > + * @link_status: new value of link status property (0: Good, 1: Bad)
>>>> > + *
>>>> > + * In usual working scenario, this link status property will always be set to
>>>> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>>>> > + * set this link status property to "BAD" and prune the mode list based on new
>>>>
>>>> Does the mode list really *need* to be pruned? In the case of needing
>>>> to re-train a DP link,
>>>> it seems like we should be able to set this BAD and keep the modelist
>>>> as-is (since the sink
>>>> hasn't changed)
>>>
>>> Well, if you prune it with the same constraints as before, no additional
>>> modes will be removed and the same list is there. Pruning here refers to
>>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>>>
>>> We might want to be a bit more explicit here perhaps? Have some good
>>> proposal text to insert?
>>
>> Ah, hmm, I hadn't equated this prune to the normal drm_connector
>> prune_invalid. I suppose the "based on new information" is what did
>> it. It seems like the mode_valid pruning will happen automagically
>> when userspace realizes the connection is BAD and asks for a new mode
>> list. So is it worth even mentioning pruning the mode list?
>>
>>>>
>>>> > + * information. The caller then needs to send a hotplug uevent for userspace to
>>>> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>>>>
>>>> extra space
>>>>
>>>> > + *
>>>> > + * Note that a lot of existing userspace do not handle this property.
>>>> > + * Drivers can therefore not rely on userspace to fix up everything and
>>>> > + * should try to handle issues (like just re-training a link) without
>>>> > + * userspace's intervention. This should only be used when the current mode
>>>> > + * fails and userspace must select a different display mode.
>>>>
>>>> Hmm, I suppose this answers my last question. It's too bad we can't
>>>> rely on this, since we'll
>>>> just end up with each driver rolling their own re-training logic on
>>>> top of possibly supporting
>>>> this (but probably not, since it's really just overhead). Perhaps this
>>>> is an overly pessimistic
>>>> view?
>>>
>>> You can forgo any re-training of course, that should work too. It's just
>>> that DP spec and everyone else seem to recommend to at least do some
>>> minimal effort (or maybe even upfront link training) here. But totally not
>>> doing anything if the link is bad should be ok too (and probably really
>>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
>>> function which checks link status and set link-status to bad&fires off the
>>> uevent if needed.
>>>
>>> Again, do you have some sample prose to add here to clarify this?
>>>
>>
>> I don't think it's merely a matter of clarifying the comment, tbh.
>> Without relying on userspace to fix us, there's not much point in
>> exposing the property in the first place.
>>
>> As a driver author, I need to decide whether I want re-training to
>> work properly. If I do, I need to handroll it in my driver since I
>> can't rely on userspace, at which point, implementing the property
>> isn't meaningful. If I don't care about it being bulletproof, I can
>> expose the property and let userspace fix me if they know how.
>>
>> So I'd prefer to have the helper be a hybrid between this patch and
>> the previous one that did a full modeset under the covers (perhaps
>> with a client cap or similar to let us know which path to trust). That
>> way I can call the helper from my driver and know that I'm going to be
>> re-trained either way.
>
> If your driver is able to handle everything in kernel, then do so by all
> means. If it can't, defer to userspace, which may or may not fix stuff,
> depending on whether it looks at the property. If the userspace doesn't
> do anything, things will be just as good or bad as they are currently,
> before this property.
>
> This allows the drivers to choose how much they can/want to do in
> kernel, and what they defer to userspace.
>

Just because I can, doesn't mean I want to :)

Take the CDN DP driver in rockchip for example (posted yesterday).
There's a worker in the driver that is responsible for handling
hpd/extcon events from the USB-C port. Ideally, this worker should
just be a thin shell around a kms uevent that lets userspace know
there's been a change. Unfortunately since we need to make re-training
work (/me grumbles about productization) seamlessly, we need to add a
bunch of goo into the worker to handle re-training. Since we need to
handle re-training there and in modeset, we need to properly
synchronize things. So we end up with a bunch of code that doesn't
*really* need to be there.

So is the correct path forward to add GOOD/BAD connection handling to
Chrome/drm_hwc and rip re-training out of the various kernel drivers?

Sean


> BR,
> Jani.
>
>
>
>>
>> Sean
>>
>>
>>> Thanks for taking a look at this.
>>>
>>> Cheers, Daniel
>>>
>>>> > + * The DRM driver can chose to not modify property and keep link status
>>>> > + * as "GOOD" always to keep the user experience same as it currently is.
>>>> > + *
>>>> > + * The reason for adding this property is to handle link training failures, but
>>>> > + * it is not limited to DP or link training. For example, if we implement
>>>> > + * asynchronous setcrtc, this property can be used to report any failures in that.
>>>> > + */
>>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>>> > +                                                uint64_t link_status)
>>>> > +{
>>>> > +       struct drm_device *dev = connector->dev;
>>>> > +
>>>> > +       /* Make sure the mutex is grabbed */
>>>> > +       lockdep_assert_held(&dev->mode_config.mutex);
>>>> > +       connector->link_status = link_status;
>>>> > +       drm_object_property_set_value(&connector->base,
>>>> > +                                     dev->mode_config.link_status_property,
>>>> > +                                     link_status);
>>>> > +}
>>>> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>>>> > +
>>>> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>>>> >                                     struct drm_property *property,
>>>> >                                     uint64_t value)
>>>> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>>>> > index 34f9741..3d513ab 100644
>>>> > --- a/include/drm/drm_connector.h
>>>> > +++ b/include/drm/drm_connector.h
>>>> > @@ -213,6 +213,9 @@ struct drm_connector_state {
>>>> >
>>>> >         struct drm_encoder *best_encoder;
>>>> >
>>>> > +       /* Connector Link status */
>>>> > +       unsigned int link_status;
>>>> > +
>>>> >         struct drm_atomic_state *state;
>>>> >  };
>>>> >
>>>> > @@ -695,6 +698,12 @@ struct drm_connector {
>>>> >         uint8_t num_h_tile, num_v_tile;
>>>> >         uint8_t tile_h_loc, tile_v_loc;
>>>> >         uint16_t tile_h_size, tile_v_size;
>>>> > +
>>>> > +       /* Connector Link status
>>>> > +        * 0: If the link is Good
>>>> > +        * 1: If the link is Bad
>>>> > +        */
>>>> > +       int link_status;
>>>> >  };
>>>> >
>>>> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>>>> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>>>> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>>>> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>>>> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>>>> > -
>>>>
>>>> lost a line here
>>>>
>>>> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>>>> >                                          const char *path);
>>>> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>>>> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>>> >                                             const struct edid *edid);
>>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>>> > +                                                uint64_t link_status);
>>>> >
>>>> >  /**
>>>> >   * struct drm_tile_group - Tile group metadata
>>>> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>>>> > index bf9991b..86faee4 100644
>>>> > --- a/include/drm/drm_mode_config.h
>>>> > +++ b/include/drm/drm_mode_config.h
>>>> > @@ -431,6 +431,11 @@ struct drm_mode_config {
>>>> >          */
>>>> >         struct drm_property *tile_property;
>>>> >         /**
>>>> > +        * @link_status_property: Default connector property for link status
>>>> > +        * of a connector
>>>> > +        */
>>>> > +       struct drm_property *link_status_property;
>>>> > +       /**
>>>> >          * @plane_type_property: Default plane property to differentiate
>>>> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>>>> >          */
>>>> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>>>> > index 728790b..309c478 100644
>>>> > --- a/include/uapi/drm/drm_mode.h
>>>> > +++ b/include/uapi/drm/drm_mode.h
>>>> > @@ -123,6 +123,10 @@
>>>> >  #define DRM_MODE_DIRTY_ON       1
>>>> >  #define DRM_MODE_DIRTY_ANNOTATE 2
>>>> >
>>>> > +/* Link Status options */
>>>> > +#define DRM_MODE_LINK_STATUS_GOOD      0
>>>> > +#define DRM_MODE_LINK_STATUS_BAD       1
>>>> > +
>>>> >  struct drm_mode_modeinfo {
>>>> >         __u32 clock;
>>>> >         __u16 hdisplay;
>>>> > --
>>>> > 1.9.1
>>>> >
>>>> > _______________________________________________
>>>> > dri-devel mailing list
>>>> > dri-devel@lists.freedesktop.org
>>>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>> _______________________________________________
>>>> dri-devel mailing list
>>>> dri-devel@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>
>>> --
>>> Daniel Vetter
>>> Software Engineer, Intel Corporation
>>> http://blog.ffwll.ch
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 15:32         ` Sean Paul
@ 2016-11-23 15:43           ` Ville Syrjälä
  2016-11-23 16:05             ` [Intel-gfx] " Sean Paul
  2016-11-23 15:52           ` Jani Nikula
  1 sibling, 1 reply; 27+ messages in thread
From: Ville Syrjälä @ 2016-11-23 15:43 UTC (permalink / raw)
  To: Sean Paul; +Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, Nov 23, 2016 at 10:32:44AM -0500, Sean Paul wrote:
> On Wed, Nov 23, 2016 at 10:15 AM, Jani Nikula
> <jani.nikula@linux.intel.com> wrote:
> > On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
> >> On Wed, Nov 23, 2016 at 3:09 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
> >>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
> >>>> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
> >>>> <manasi.d.navare@intel.com> wrote:
> >>>> > This is RFC patch for adding a connector link-status property
> >>>> > and making it atomic by adding it to the drm_connector_state.
> >>>> > This is to make sure its wired properly in drm_atomic_connector_set_property
> >>>> > and drm_atomic_connector_get_property functions.
> >>>> >
> >>>>
> >>>> Thanks for sending this. We ran into some re-training awkwardness
> >>>> recently, and I
> >>>> was hoping for such a patch.
> >>>>
> >>>> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> >>>> > Cc: Daniel Vetter <daniel.vetter@intel.com>
> >>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> >>>> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> >>>> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> >>>> > ---
> >>>> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
> >>>> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
> >>>> >  include/drm/drm_connector.h     | 12 +++++++-
> >>>> >  include/drm/drm_mode_config.h   |  5 ++++
> >>>> >  include/uapi/drm/drm_mode.h     |  4 +++
> >>>> >  5 files changed, 88 insertions(+), 3 deletions(-)
> >>>> >
> >>>> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >>>> > index 89737e4..644d19f 100644
> >>>> > --- a/drivers/gpu/drm/drm_atomic.c
> >>>> > +++ b/drivers/gpu/drm/drm_atomic.c
> >>>> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> >>>> >                  * now?) atomic writes to DPMS property:
> >>>> >                  */
> >>>> >                 return -EINVAL;
> >>>> > +       } else if (property == config->link_status_property) {
> >>>> > +               state->link_status = val;
> >>>
> >>> I think we should have a check here to make sure userspace never tries to
> >>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
> >>> atomic userspace is supposed to be able to just restore everything to what
> >>> it was.
> >>>
> >>> I don't think trying to set it to "BAD" should cause an error though, just
> >>> silently keep the link status at "GOOG". So:
> >>>
> >>>         /* Never downgrade from GOOD to BAD on userspace's request here,
> >>>          * only hw issues can do that. */
> >>>         if (state->link_status == GOOD)
> >>>                 return 0;
> >>
> >> Can we return an error if the transition is invalid?
> >>
> >>>         state->link_status = val;
> >>>         return 0;
> >>>
> >>>> > +               return 0;
> >>>> >         } else if (connector->funcs->atomic_set_property) {
> >>>> >                 return connector->funcs->atomic_set_property(connector,
> >>>> >                                 state, property, val);
> >>>> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
> >>>> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
> >>>> >         } else if (property == config->dpms_property) {
> >>>> >                 *val = connector->dpms;
> >>>> > +       } else if (property == config->link_status_property) {
> >>>> > +               *val = state->link_status;
> >>>> >         } else if (connector->funcs->atomic_get_property) {
> >>>> >                 return connector->funcs->atomic_get_property(connector,
> >>>> >                                 state, property, val);
> >>>> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> >>>> > index 5a45262..4576c9f 100644
> >>>> > --- a/drivers/gpu/drm/drm_connector.c
> >>>> > +++ b/drivers/gpu/drm/drm_connector.c
> >>>> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
> >>>> >         drm_object_attach_property(&connector->base,
> >>>> >                                       config->dpms_property, 0);
> >>>> >
> >>>> > +       drm_object_attach_property(&connector->base,
> >>>> > +                                  config->link_status_property,
> >>>> > +                                  0);
> >>>> > +
> >>>> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> >>>> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
> >>>> >         }
> >>>> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
> >>>> >  };
> >>>> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
> >>>> >
> >>>> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> >>>> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
> >>>> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
> >>>> > +};
> >>>> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> >>>> > +
> >>>> >  /**
> >>>> >   * drm_display_info_set_bus_formats - set the supported bus formats
> >>>> >   * @info: display info to store bus formats in
> >>>> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >>>> >   *     path property the MST manager created. Userspace cannot change this
> >>>> >   *     property.
> >>>> >   * TILE:
> >>>> > - *     Connector tile group property to indicate how a set of DRM connector
> >>>> > + *      Connector tile group property to indicate how a set of DRM connector
> >>>>
> >>>> keyboard slip here
> >>>>
> >>>> >   *     compose together into one logical screen. This is used by both high-res
> >>>> >   *     external screens (often only using a single cable, but exposing multiple
> >>>> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
> >>>> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >>>> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
> >>>> >   *     should update this value using drm_mode_connector_set_tile_property().
> >>>> >   *     Userspace cannot change this property.
> >>>> > - *
> >>>> > + * link-status:
> >>>> > + *      Connector link-status property to indicate the status of link during
> >>>> > + *      the modeset. The default value of link-status is "GOOD". If something
> >>>> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
> >>>> > + *      the mode list based on new link parameters and send a hotplug uevent
> >>>> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> >>>> > + *      IOCTL and redo a modeset. Drivers should update this value using
> >>>> > + *      drm_mode_connector_set_link_status_property().
> >>>> >   * Connectors also have one standardized atomic property:
> >>>> >   *
> >>>> >   * CRTC_ID:
> >>>> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> >>>> >                 return -ENOMEM;
> >>>> >         dev->mode_config.tile_property = prop;
> >>>> >
> >>>> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> >>>> > +                                       drm_link_status_enum_list,
> >>>> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
> >>>> > +       if (!prop)
> >>>> > +               return -ENOMEM;
> >>>> > +       dev->mode_config.link_status_property = prop;
> >>>> > +
> >>>> >         return 0;
> >>>> >  }
> >>>> >
> >>>> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >>>> >  }
> >>>> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
> >>>> >
> >>>> > +/**
> >>>> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> >>>> > + * @connector: drm connector
> >>>> > + * @link_status: new value of link status property (0: Good, 1: Bad)
> >>>> > + *
> >>>> > + * In usual working scenario, this link status property will always be set to
> >>>> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
> >>>> > + * set this link status property to "BAD" and prune the mode list based on new
> >>>>
> >>>> Does the mode list really *need* to be pruned? In the case of needing
> >>>> to re-train a DP link,
> >>>> it seems like we should be able to set this BAD and keep the modelist
> >>>> as-is (since the sink
> >>>> hasn't changed)
> >>>
> >>> Well, if you prune it with the same constraints as before, no additional
> >>> modes will be removed and the same list is there. Pruning here refers to
> >>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
> >>>
> >>> We might want to be a bit more explicit here perhaps? Have some good
> >>> proposal text to insert?
> >>
> >> Ah, hmm, I hadn't equated this prune to the normal drm_connector
> >> prune_invalid. I suppose the "based on new information" is what did
> >> it. It seems like the mode_valid pruning will happen automagically
> >> when userspace realizes the connection is BAD and asks for a new mode
> >> list. So is it worth even mentioning pruning the mode list?
> >>
> >>>>
> >>>> > + * information. The caller then needs to send a hotplug uevent for userspace to
> >>>> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> >>>>
> >>>> extra space
> >>>>
> >>>> > + *
> >>>> > + * Note that a lot of existing userspace do not handle this property.
> >>>> > + * Drivers can therefore not rely on userspace to fix up everything and
> >>>> > + * should try to handle issues (like just re-training a link) without
> >>>> > + * userspace's intervention. This should only be used when the current mode
> >>>> > + * fails and userspace must select a different display mode.
> >>>>
> >>>> Hmm, I suppose this answers my last question. It's too bad we can't
> >>>> rely on this, since we'll
> >>>> just end up with each driver rolling their own re-training logic on
> >>>> top of possibly supporting
> >>>> this (but probably not, since it's really just overhead). Perhaps this
> >>>> is an overly pessimistic
> >>>> view?
> >>>
> >>> You can forgo any re-training of course, that should work too. It's just
> >>> that DP spec and everyone else seem to recommend to at least do some
> >>> minimal effort (or maybe even upfront link training) here. But totally not
> >>> doing anything if the link is bad should be ok too (and probably really
> >>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
> >>> function which checks link status and set link-status to bad&fires off the
> >>> uevent if needed.
> >>>
> >>> Again, do you have some sample prose to add here to clarify this?
> >>>
> >>
> >> I don't think it's merely a matter of clarifying the comment, tbh.
> >> Without relying on userspace to fix us, there's not much point in
> >> exposing the property in the first place.
> >>
> >> As a driver author, I need to decide whether I want re-training to
> >> work properly. If I do, I need to handroll it in my driver since I
> >> can't rely on userspace, at which point, implementing the property
> >> isn't meaningful. If I don't care about it being bulletproof, I can
> >> expose the property and let userspace fix me if they know how.
> >>
> >> So I'd prefer to have the helper be a hybrid between this patch and
> >> the previous one that did a full modeset under the covers (perhaps
> >> with a client cap or similar to let us know which path to trust). That
> >> way I can call the helper from my driver and know that I'm going to be
> >> re-trained either way.
> >
> > If your driver is able to handle everything in kernel, then do so by all
> > means. If it can't, defer to userspace, which may or may not fix stuff,
> > depending on whether it looks at the property. If the userspace doesn't
> > do anything, things will be just as good or bad as they are currently,
> > before this property.
> >
> > This allows the drivers to choose how much they can/want to do in
> > kernel, and what they defer to userspace.
> >
> 
> Just because I can, doesn't mean I want to :)
> 
> Take the CDN DP driver in rockchip for example (posted yesterday).
> There's a worker in the driver that is responsible for handling
> hpd/extcon events from the USB-C port. Ideally, this worker should
> just be a thin shell around a kms uevent that lets userspace know
> there's been a change. Unfortunately since we need to make re-training
> work (/me grumbles about productization) seamlessly, we need to add a
> bunch of goo into the worker to handle re-training. Since we need to
> handle re-training there and in modeset, we need to properly
> synchronize things. So we end up with a bunch of code that doesn't
> *really* need to be there.
> 
> So is the correct path forward to add GOOD/BAD connection handling to
> Chrome/drm_hwc and rip re-training out of the various kernel drivers?

In i915 I think we might still want to do the "try to retrain with
the current link parameters" thing automagically. It's not difficult
to do after all, and should be faster than doing a full modeset.

> 
> Sean
> 
> 
> > BR,
> > Jani.
> >
> >
> >
> >>
> >> Sean
> >>
> >>
> >>> Thanks for taking a look at this.
> >>>
> >>> Cheers, Daniel
> >>>
> >>>> > + * The DRM driver can chose to not modify property and keep link status
> >>>> > + * as "GOOD" always to keep the user experience same as it currently is.
> >>>> > + *
> >>>> > + * The reason for adding this property is to handle link training failures, but
> >>>> > + * it is not limited to DP or link training. For example, if we implement
> >>>> > + * asynchronous setcrtc, this property can be used to report any failures in that.
> >>>> > + */
> >>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> >>>> > +                                                uint64_t link_status)
> >>>> > +{
> >>>> > +       struct drm_device *dev = connector->dev;
> >>>> > +
> >>>> > +       /* Make sure the mutex is grabbed */
> >>>> > +       lockdep_assert_held(&dev->mode_config.mutex);
> >>>> > +       connector->link_status = link_status;
> >>>> > +       drm_object_property_set_value(&connector->base,
> >>>> > +                                     dev->mode_config.link_status_property,
> >>>> > +                                     link_status);
> >>>> > +}
> >>>> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> >>>> > +
> >>>> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> >>>> >                                     struct drm_property *property,
> >>>> >                                     uint64_t value)
> >>>> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> >>>> > index 34f9741..3d513ab 100644
> >>>> > --- a/include/drm/drm_connector.h
> >>>> > +++ b/include/drm/drm_connector.h
> >>>> > @@ -213,6 +213,9 @@ struct drm_connector_state {
> >>>> >
> >>>> >         struct drm_encoder *best_encoder;
> >>>> >
> >>>> > +       /* Connector Link status */
> >>>> > +       unsigned int link_status;
> >>>> > +
> >>>> >         struct drm_atomic_state *state;
> >>>> >  };
> >>>> >
> >>>> > @@ -695,6 +698,12 @@ struct drm_connector {
> >>>> >         uint8_t num_h_tile, num_v_tile;
> >>>> >         uint8_t tile_h_loc, tile_v_loc;
> >>>> >         uint16_t tile_h_size, tile_v_size;
> >>>> > +
> >>>> > +       /* Connector Link status
> >>>> > +        * 0: If the link is Good
> >>>> > +        * 1: If the link is Bad
> >>>> > +        */
> >>>> > +       int link_status;
> >>>> >  };
> >>>> >
> >>>> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> >>>> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> >>>> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> >>>> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
> >>>> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> >>>> > -
> >>>>
> >>>> lost a line here
> >>>>
> >>>> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
> >>>> >                                          const char *path);
> >>>> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
> >>>> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >>>> >                                             const struct edid *edid);
> >>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> >>>> > +                                                uint64_t link_status);
> >>>> >
> >>>> >  /**
> >>>> >   * struct drm_tile_group - Tile group metadata
> >>>> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> >>>> > index bf9991b..86faee4 100644
> >>>> > --- a/include/drm/drm_mode_config.h
> >>>> > +++ b/include/drm/drm_mode_config.h
> >>>> > @@ -431,6 +431,11 @@ struct drm_mode_config {
> >>>> >          */
> >>>> >         struct drm_property *tile_property;
> >>>> >         /**
> >>>> > +        * @link_status_property: Default connector property for link status
> >>>> > +        * of a connector
> >>>> > +        */
> >>>> > +       struct drm_property *link_status_property;
> >>>> > +       /**
> >>>> >          * @plane_type_property: Default plane property to differentiate
> >>>> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
> >>>> >          */
> >>>> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> >>>> > index 728790b..309c478 100644
> >>>> > --- a/include/uapi/drm/drm_mode.h
> >>>> > +++ b/include/uapi/drm/drm_mode.h
> >>>> > @@ -123,6 +123,10 @@
> >>>> >  #define DRM_MODE_DIRTY_ON       1
> >>>> >  #define DRM_MODE_DIRTY_ANNOTATE 2
> >>>> >
> >>>> > +/* Link Status options */
> >>>> > +#define DRM_MODE_LINK_STATUS_GOOD      0
> >>>> > +#define DRM_MODE_LINK_STATUS_BAD       1
> >>>> > +
> >>>> >  struct drm_mode_modeinfo {
> >>>> >         __u32 clock;
> >>>> >         __u16 hdisplay;
> >>>> > --
> >>>> > 1.9.1
> >>>> >
> >>>> > _______________________________________________
> >>>> > dri-devel mailing list
> >>>> > dri-devel@lists.freedesktop.org
> >>>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> >>>> _______________________________________________
> >>>> dri-devel mailing list
> >>>> dri-devel@lists.freedesktop.org
> >>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> >>>
> >>> --
> >>> Daniel Vetter
> >>> Software Engineer, Intel Corporation
> >>> http://blog.ffwll.ch
> >> _______________________________________________
> >> dri-devel mailing list
> >> dri-devel@lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> >
> > --
> > Jani Nikula, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 15:32         ` Sean Paul
  2016-11-23 15:43           ` Ville Syrjälä
@ 2016-11-23 15:52           ` Jani Nikula
  2016-11-23 16:09             ` Sean Paul
  2016-11-23 16:11             ` Daniel Vetter
  1 sibling, 2 replies; 27+ messages in thread
From: Jani Nikula @ 2016-11-23 15:52 UTC (permalink / raw)
  To: Sean Paul
  Cc: Manasi Navare, Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
> On Wed, Nov 23, 2016 at 10:15 AM, Jani Nikula
> <jani.nikula@linux.intel.com> wrote:
>> On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
>>> On Wed, Nov 23, 2016 at 3:09 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>>>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>>>>> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>>>>> <manasi.d.navare@intel.com> wrote:
>>>>> > This is RFC patch for adding a connector link-status property
>>>>> > and making it atomic by adding it to the drm_connector_state.
>>>>> > This is to make sure its wired properly in drm_atomic_connector_set_property
>>>>> > and drm_atomic_connector_get_property functions.
>>>>> >
>>>>>
>>>>> Thanks for sending this. We ran into some re-training awkwardness
>>>>> recently, and I
>>>>> was hoping for such a patch.
>>>>>
>>>>> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>>>>> > Cc: Daniel Vetter <daniel.vetter@intel.com>
>>>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>>>> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>>> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>>>>> > ---
>>>>> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>>>>> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>>>>> >  include/drm/drm_connector.h     | 12 +++++++-
>>>>> >  include/drm/drm_mode_config.h   |  5 ++++
>>>>> >  include/uapi/drm/drm_mode.h     |  4 +++
>>>>> >  5 files changed, 88 insertions(+), 3 deletions(-)
>>>>> >
>>>>> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>>>>> > index 89737e4..644d19f 100644
>>>>> > --- a/drivers/gpu/drm/drm_atomic.c
>>>>> > +++ b/drivers/gpu/drm/drm_atomic.c
>>>>> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>>>>> >                  * now?) atomic writes to DPMS property:
>>>>> >                  */
>>>>> >                 return -EINVAL;
>>>>> > +       } else if (property == config->link_status_property) {
>>>>> > +               state->link_status = val;
>>>>
>>>> I think we should have a check here to make sure userspace never tries to
>>>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
>>>> atomic userspace is supposed to be able to just restore everything to what
>>>> it was.
>>>>
>>>> I don't think trying to set it to "BAD" should cause an error though, just
>>>> silently keep the link status at "GOOG". So:
>>>>
>>>>         /* Never downgrade from GOOD to BAD on userspace's request here,
>>>>          * only hw issues can do that. */
>>>>         if (state->link_status == GOOD)
>>>>                 return 0;
>>>
>>> Can we return an error if the transition is invalid?
>>>
>>>>         state->link_status = val;
>>>>         return 0;
>>>>
>>>>> > +               return 0;
>>>>> >         } else if (connector->funcs->atomic_set_property) {
>>>>> >                 return connector->funcs->atomic_set_property(connector,
>>>>> >                                 state, property, val);
>>>>> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>>>>> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>>>>> >         } else if (property == config->dpms_property) {
>>>>> >                 *val = connector->dpms;
>>>>> > +       } else if (property == config->link_status_property) {
>>>>> > +               *val = state->link_status;
>>>>> >         } else if (connector->funcs->atomic_get_property) {
>>>>> >                 return connector->funcs->atomic_get_property(connector,
>>>>> >                                 state, property, val);
>>>>> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>>>>> > index 5a45262..4576c9f 100644
>>>>> > --- a/drivers/gpu/drm/drm_connector.c
>>>>> > +++ b/drivers/gpu/drm/drm_connector.c
>>>>> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>>>>> >         drm_object_attach_property(&connector->base,
>>>>> >                                       config->dpms_property, 0);
>>>>> >
>>>>> > +       drm_object_attach_property(&connector->base,
>>>>> > +                                  config->link_status_property,
>>>>> > +                                  0);
>>>>> > +
>>>>> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>>>>> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>>>>> >         }
>>>>> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>>>>> >  };
>>>>> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>>>>> >
>>>>> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>>>>> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>>>>> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>>>>> > +};
>>>>> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>>>>> > +
>>>>> >  /**
>>>>> >   * drm_display_info_set_bus_formats - set the supported bus formats
>>>>> >   * @info: display info to store bus formats in
>>>>> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>>>> >   *     path property the MST manager created. Userspace cannot change this
>>>>> >   *     property.
>>>>> >   * TILE:
>>>>> > - *     Connector tile group property to indicate how a set of DRM connector
>>>>> > + *      Connector tile group property to indicate how a set of DRM connector
>>>>>
>>>>> keyboard slip here
>>>>>
>>>>> >   *     compose together into one logical screen. This is used by both high-res
>>>>> >   *     external screens (often only using a single cable, but exposing multiple
>>>>> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>>>>> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>>>> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>>>>> >   *     should update this value using drm_mode_connector_set_tile_property().
>>>>> >   *     Userspace cannot change this property.
>>>>> > - *
>>>>> > + * link-status:
>>>>> > + *      Connector link-status property to indicate the status of link during
>>>>> > + *      the modeset. The default value of link-status is "GOOD". If something
>>>>> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>>>>> > + *      the mode list based on new link parameters and send a hotplug uevent
>>>>> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>>>>> > + *      IOCTL and redo a modeset. Drivers should update this value using
>>>>> > + *      drm_mode_connector_set_link_status_property().
>>>>> >   * Connectors also have one standardized atomic property:
>>>>> >   *
>>>>> >   * CRTC_ID:
>>>>> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>>>>> >                 return -ENOMEM;
>>>>> >         dev->mode_config.tile_property = prop;
>>>>> >
>>>>> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>>>>> > +                                       drm_link_status_enum_list,
>>>>> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>>>>> > +       if (!prop)
>>>>> > +               return -ENOMEM;
>>>>> > +       dev->mode_config.link_status_property = prop;
>>>>> > +
>>>>> >         return 0;
>>>>> >  }
>>>>> >
>>>>> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>>>> >  }
>>>>> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>>>>> >
>>>>> > +/**
>>>>> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>>>>> > + * @connector: drm connector
>>>>> > + * @link_status: new value of link status property (0: Good, 1: Bad)
>>>>> > + *
>>>>> > + * In usual working scenario, this link status property will always be set to
>>>>> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>>>>> > + * set this link status property to "BAD" and prune the mode list based on new
>>>>>
>>>>> Does the mode list really *need* to be pruned? In the case of needing
>>>>> to re-train a DP link,
>>>>> it seems like we should be able to set this BAD and keep the modelist
>>>>> as-is (since the sink
>>>>> hasn't changed)
>>>>
>>>> Well, if you prune it with the same constraints as before, no additional
>>>> modes will be removed and the same list is there. Pruning here refers to
>>>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>>>>
>>>> We might want to be a bit more explicit here perhaps? Have some good
>>>> proposal text to insert?
>>>
>>> Ah, hmm, I hadn't equated this prune to the normal drm_connector
>>> prune_invalid. I suppose the "based on new information" is what did
>>> it. It seems like the mode_valid pruning will happen automagically
>>> when userspace realizes the connection is BAD and asks for a new mode
>>> list. So is it worth even mentioning pruning the mode list?
>>>
>>>>>
>>>>> > + * information. The caller then needs to send a hotplug uevent for userspace to
>>>>> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>>>>>
>>>>> extra space
>>>>>
>>>>> > + *
>>>>> > + * Note that a lot of existing userspace do not handle this property.
>>>>> > + * Drivers can therefore not rely on userspace to fix up everything and
>>>>> > + * should try to handle issues (like just re-training a link) without
>>>>> > + * userspace's intervention. This should only be used when the current mode
>>>>> > + * fails and userspace must select a different display mode.
>>>>>
>>>>> Hmm, I suppose this answers my last question. It's too bad we can't
>>>>> rely on this, since we'll
>>>>> just end up with each driver rolling their own re-training logic on
>>>>> top of possibly supporting
>>>>> this (but probably not, since it's really just overhead). Perhaps this
>>>>> is an overly pessimistic
>>>>> view?
>>>>
>>>> You can forgo any re-training of course, that should work too. It's just
>>>> that DP spec and everyone else seem to recommend to at least do some
>>>> minimal effort (or maybe even upfront link training) here. But totally not
>>>> doing anything if the link is bad should be ok too (and probably really
>>>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
>>>> function which checks link status and set link-status to bad&fires off the
>>>> uevent if needed.
>>>>
>>>> Again, do you have some sample prose to add here to clarify this?
>>>>
>>>
>>> I don't think it's merely a matter of clarifying the comment, tbh.
>>> Without relying on userspace to fix us, there's not much point in
>>> exposing the property in the first place.
>>>
>>> As a driver author, I need to decide whether I want re-training to
>>> work properly. If I do, I need to handroll it in my driver since I
>>> can't rely on userspace, at which point, implementing the property
>>> isn't meaningful. If I don't care about it being bulletproof, I can
>>> expose the property and let userspace fix me if they know how.
>>>
>>> So I'd prefer to have the helper be a hybrid between this patch and
>>> the previous one that did a full modeset under the covers (perhaps
>>> with a client cap or similar to let us know which path to trust). That
>>> way I can call the helper from my driver and know that I'm going to be
>>> re-trained either way.
>>
>> If your driver is able to handle everything in kernel, then do so by all
>> means. If it can't, defer to userspace, which may or may not fix stuff,
>> depending on whether it looks at the property. If the userspace doesn't
>> do anything, things will be just as good or bad as they are currently,
>> before this property.
>>
>> This allows the drivers to choose how much they can/want to do in
>> kernel, and what they defer to userspace.
>>
>
> Just because I can, doesn't mean I want to :)

And just because I want to, doesn't mean I can! ;)

> Take the CDN DP driver in rockchip for example (posted yesterday).
> There's a worker in the driver that is responsible for handling
> hpd/extcon events from the USB-C port. Ideally, this worker should
> just be a thin shell around a kms uevent that lets userspace know
> there's been a change. Unfortunately since we need to make re-training
> work (/me grumbles about productization) seamlessly, we need to add a
> bunch of goo into the worker to handle re-training. Since we need to
> handle re-training there and in modeset, we need to properly
> synchronize things. So we end up with a bunch of code that doesn't
> *really* need to be there.
>
> So is the correct path forward to add GOOD/BAD connection handling to
> Chrome/drm_hwc

I think so.

> and rip re-training out of the various kernel drivers?

IMO if it works, don't change it, at least not in a rush. It also
depends on the hardware and the driver; the amount of code required may
be vastly different for various drivers.

Personally, I think in the long run letting userspace help here leads to
a simpler design and more efficient happy day scenario handling, and
userspace knows what's going on.

BR,
Jani.

>
> Sean
>
>
>> BR,
>> Jani.
>>
>>
>>
>>>
>>> Sean
>>>
>>>
>>>> Thanks for taking a look at this.
>>>>
>>>> Cheers, Daniel
>>>>
>>>>> > + * The DRM driver can chose to not modify property and keep link status
>>>>> > + * as "GOOD" always to keep the user experience same as it currently is.
>>>>> > + *
>>>>> > + * The reason for adding this property is to handle link training failures, but
>>>>> > + * it is not limited to DP or link training. For example, if we implement
>>>>> > + * asynchronous setcrtc, this property can be used to report any failures in that.
>>>>> > + */
>>>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>>>> > +                                                uint64_t link_status)
>>>>> > +{
>>>>> > +       struct drm_device *dev = connector->dev;
>>>>> > +
>>>>> > +       /* Make sure the mutex is grabbed */
>>>>> > +       lockdep_assert_held(&dev->mode_config.mutex);
>>>>> > +       connector->link_status = link_status;
>>>>> > +       drm_object_property_set_value(&connector->base,
>>>>> > +                                     dev->mode_config.link_status_property,
>>>>> > +                                     link_status);
>>>>> > +}
>>>>> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>>>>> > +
>>>>> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>>>>> >                                     struct drm_property *property,
>>>>> >                                     uint64_t value)
>>>>> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>>>>> > index 34f9741..3d513ab 100644
>>>>> > --- a/include/drm/drm_connector.h
>>>>> > +++ b/include/drm/drm_connector.h
>>>>> > @@ -213,6 +213,9 @@ struct drm_connector_state {
>>>>> >
>>>>> >         struct drm_encoder *best_encoder;
>>>>> >
>>>>> > +       /* Connector Link status */
>>>>> > +       unsigned int link_status;
>>>>> > +
>>>>> >         struct drm_atomic_state *state;
>>>>> >  };
>>>>> >
>>>>> > @@ -695,6 +698,12 @@ struct drm_connector {
>>>>> >         uint8_t num_h_tile, num_v_tile;
>>>>> >         uint8_t tile_h_loc, tile_v_loc;
>>>>> >         uint16_t tile_h_size, tile_v_size;
>>>>> > +
>>>>> > +       /* Connector Link status
>>>>> > +        * 0: If the link is Good
>>>>> > +        * 1: If the link is Bad
>>>>> > +        */
>>>>> > +       int link_status;
>>>>> >  };
>>>>> >
>>>>> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>>>>> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>>>>> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>>>>> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>>>>> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>>>>> > -
>>>>>
>>>>> lost a line here
>>>>>
>>>>> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>>>>> >                                          const char *path);
>>>>> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>>>>> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>>>> >                                             const struct edid *edid);
>>>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>>>> > +                                                uint64_t link_status);
>>>>> >
>>>>> >  /**
>>>>> >   * struct drm_tile_group - Tile group metadata
>>>>> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>>>>> > index bf9991b..86faee4 100644
>>>>> > --- a/include/drm/drm_mode_config.h
>>>>> > +++ b/include/drm/drm_mode_config.h
>>>>> > @@ -431,6 +431,11 @@ struct drm_mode_config {
>>>>> >          */
>>>>> >         struct drm_property *tile_property;
>>>>> >         /**
>>>>> > +        * @link_status_property: Default connector property for link status
>>>>> > +        * of a connector
>>>>> > +        */
>>>>> > +       struct drm_property *link_status_property;
>>>>> > +       /**
>>>>> >          * @plane_type_property: Default plane property to differentiate
>>>>> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>>>>> >          */
>>>>> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>>>>> > index 728790b..309c478 100644
>>>>> > --- a/include/uapi/drm/drm_mode.h
>>>>> > +++ b/include/uapi/drm/drm_mode.h
>>>>> > @@ -123,6 +123,10 @@
>>>>> >  #define DRM_MODE_DIRTY_ON       1
>>>>> >  #define DRM_MODE_DIRTY_ANNOTATE 2
>>>>> >
>>>>> > +/* Link Status options */
>>>>> > +#define DRM_MODE_LINK_STATUS_GOOD      0
>>>>> > +#define DRM_MODE_LINK_STATUS_BAD       1
>>>>> > +
>>>>> >  struct drm_mode_modeinfo {
>>>>> >         __u32 clock;
>>>>> >         __u16 hdisplay;
>>>>> > --
>>>>> > 1.9.1
>>>>> >
>>>>> > _______________________________________________
>>>>> > dri-devel mailing list
>>>>> > dri-devel@lists.freedesktop.org
>>>>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>>> _______________________________________________
>>>>> dri-devel mailing list
>>>>> dri-devel@lists.freedesktop.org
>>>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>>
>>>> --
>>>> Daniel Vetter
>>>> Software Engineer, Intel Corporation
>>>> http://blog.ffwll.ch
>>> _______________________________________________
>>> dri-devel mailing list
>>> dri-devel@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>> --
>> Jani Nikula, Intel Open Source Technology Center

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Intel-gfx] [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 15:43           ` Ville Syrjälä
@ 2016-11-23 16:05             ` Sean Paul
  0 siblings, 0 replies; 27+ messages in thread
From: Sean Paul @ 2016-11-23 16:05 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, Nov 23, 2016 at 10:43 AM, Ville Syrjälä
<ville.syrjala@linux.intel.com> wrote:
> On Wed, Nov 23, 2016 at 10:32:44AM -0500, Sean Paul wrote:
>> On Wed, Nov 23, 2016 at 10:15 AM, Jani Nikula
>> <jani.nikula@linux.intel.com> wrote:
>> > On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
>> >> On Wed, Nov 23, 2016 at 3:09 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>> >>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>> >>>> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>> >>>> <manasi.d.navare@intel.com> wrote:
>> >>>> > This is RFC patch for adding a connector link-status property
>> >>>> > and making it atomic by adding it to the drm_connector_state.
>> >>>> > This is to make sure its wired properly in drm_atomic_connector_set_property
>> >>>> > and drm_atomic_connector_get_property functions.
>> >>>> >
>> >>>>
>> >>>> Thanks for sending this. We ran into some re-training awkwardness
>> >>>> recently, and I
>> >>>> was hoping for such a patch.
>> >>>>
>> >>>> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> >>>> > Cc: Daniel Vetter <daniel.vetter@intel.com>
>> >>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>> >>>> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> >>>> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>> >>>> > ---
>> >>>> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>> >>>> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>> >>>> >  include/drm/drm_connector.h     | 12 +++++++-
>> >>>> >  include/drm/drm_mode_config.h   |  5 ++++
>> >>>> >  include/uapi/drm/drm_mode.h     |  4 +++
>> >>>> >  5 files changed, 88 insertions(+), 3 deletions(-)
>> >>>> >
>> >>>> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> >>>> > index 89737e4..644d19f 100644
>> >>>> > --- a/drivers/gpu/drm/drm_atomic.c
>> >>>> > +++ b/drivers/gpu/drm/drm_atomic.c
>> >>>> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>> >>>> >                  * now?) atomic writes to DPMS property:
>> >>>> >                  */
>> >>>> >                 return -EINVAL;
>> >>>> > +       } else if (property == config->link_status_property) {
>> >>>> > +               state->link_status = val;
>> >>>
>> >>> I think we should have a check here to make sure userspace never tries to
>> >>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
>> >>> atomic userspace is supposed to be able to just restore everything to what
>> >>> it was.
>> >>>
>> >>> I don't think trying to set it to "BAD" should cause an error though, just
>> >>> silently keep the link status at "GOOG". So:
>> >>>
>> >>>         /* Never downgrade from GOOD to BAD on userspace's request here,
>> >>>          * only hw issues can do that. */
>> >>>         if (state->link_status == GOOD)
>> >>>                 return 0;
>> >>
>> >> Can we return an error if the transition is invalid?
>> >>
>> >>>         state->link_status = val;
>> >>>         return 0;
>> >>>
>> >>>> > +               return 0;
>> >>>> >         } else if (connector->funcs->atomic_set_property) {
>> >>>> >                 return connector->funcs->atomic_set_property(connector,
>> >>>> >                                 state, property, val);
>> >>>> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>> >>>> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>> >>>> >         } else if (property == config->dpms_property) {
>> >>>> >                 *val = connector->dpms;
>> >>>> > +       } else if (property == config->link_status_property) {
>> >>>> > +               *val = state->link_status;
>> >>>> >         } else if (connector->funcs->atomic_get_property) {
>> >>>> >                 return connector->funcs->atomic_get_property(connector,
>> >>>> >                                 state, property, val);
>> >>>> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>> >>>> > index 5a45262..4576c9f 100644
>> >>>> > --- a/drivers/gpu/drm/drm_connector.c
>> >>>> > +++ b/drivers/gpu/drm/drm_connector.c
>> >>>> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>> >>>> >         drm_object_attach_property(&connector->base,
>> >>>> >                                       config->dpms_property, 0);
>> >>>> >
>> >>>> > +       drm_object_attach_property(&connector->base,
>> >>>> > +                                  config->link_status_property,
>> >>>> > +                                  0);
>> >>>> > +
>> >>>> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>> >>>> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>> >>>> >         }
>> >>>> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>> >>>> >  };
>> >>>> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>> >>>> >
>> >>>> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>> >>>> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>> >>>> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>> >>>> > +};
>> >>>> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>> >>>> > +
>> >>>> >  /**
>> >>>> >   * drm_display_info_set_bus_formats - set the supported bus formats
>> >>>> >   * @info: display info to store bus formats in
>> >>>> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> >>>> >   *     path property the MST manager created. Userspace cannot change this
>> >>>> >   *     property.
>> >>>> >   * TILE:
>> >>>> > - *     Connector tile group property to indicate how a set of DRM connector
>> >>>> > + *      Connector tile group property to indicate how a set of DRM connector
>> >>>>
>> >>>> keyboard slip here
>> >>>>
>> >>>> >   *     compose together into one logical screen. This is used by both high-res
>> >>>> >   *     external screens (often only using a single cable, but exposing multiple
>> >>>> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>> >>>> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> >>>> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>> >>>> >   *     should update this value using drm_mode_connector_set_tile_property().
>> >>>> >   *     Userspace cannot change this property.
>> >>>> > - *
>> >>>> > + * link-status:
>> >>>> > + *      Connector link-status property to indicate the status of link during
>> >>>> > + *      the modeset. The default value of link-status is "GOOD". If something
>> >>>> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>> >>>> > + *      the mode list based on new link parameters and send a hotplug uevent
>> >>>> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>> >>>> > + *      IOCTL and redo a modeset. Drivers should update this value using
>> >>>> > + *      drm_mode_connector_set_link_status_property().
>> >>>> >   * Connectors also have one standardized atomic property:
>> >>>> >   *
>> >>>> >   * CRTC_ID:
>> >>>> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>> >>>> >                 return -ENOMEM;
>> >>>> >         dev->mode_config.tile_property = prop;
>> >>>> >
>> >>>> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>> >>>> > +                                       drm_link_status_enum_list,
>> >>>> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>> >>>> > +       if (!prop)
>> >>>> > +               return -ENOMEM;
>> >>>> > +       dev->mode_config.link_status_property = prop;
>> >>>> > +
>> >>>> >         return 0;
>> >>>> >  }
>> >>>> >
>> >>>> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>> >>>> >  }
>> >>>> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>> >>>> >
>> >>>> > +/**
>> >>>> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>> >>>> > + * @connector: drm connector
>> >>>> > + * @link_status: new value of link status property (0: Good, 1: Bad)
>> >>>> > + *
>> >>>> > + * In usual working scenario, this link status property will always be set to
>> >>>> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>> >>>> > + * set this link status property to "BAD" and prune the mode list based on new
>> >>>>
>> >>>> Does the mode list really *need* to be pruned? In the case of needing
>> >>>> to re-train a DP link,
>> >>>> it seems like we should be able to set this BAD and keep the modelist
>> >>>> as-is (since the sink
>> >>>> hasn't changed)
>> >>>
>> >>> Well, if you prune it with the same constraints as before, no additional
>> >>> modes will be removed and the same list is there. Pruning here refers to
>> >>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>> >>>
>> >>> We might want to be a bit more explicit here perhaps? Have some good
>> >>> proposal text to insert?
>> >>
>> >> Ah, hmm, I hadn't equated this prune to the normal drm_connector
>> >> prune_invalid. I suppose the "based on new information" is what did
>> >> it. It seems like the mode_valid pruning will happen automagically
>> >> when userspace realizes the connection is BAD and asks for a new mode
>> >> list. So is it worth even mentioning pruning the mode list?
>> >>
>> >>>>
>> >>>> > + * information. The caller then needs to send a hotplug uevent for userspace to
>> >>>> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>> >>>>
>> >>>> extra space
>> >>>>
>> >>>> > + *
>> >>>> > + * Note that a lot of existing userspace do not handle this property.
>> >>>> > + * Drivers can therefore not rely on userspace to fix up everything and
>> >>>> > + * should try to handle issues (like just re-training a link) without
>> >>>> > + * userspace's intervention. This should only be used when the current mode
>> >>>> > + * fails and userspace must select a different display mode.
>> >>>>
>> >>>> Hmm, I suppose this answers my last question. It's too bad we can't
>> >>>> rely on this, since we'll
>> >>>> just end up with each driver rolling their own re-training logic on
>> >>>> top of possibly supporting
>> >>>> this (but probably not, since it's really just overhead). Perhaps this
>> >>>> is an overly pessimistic
>> >>>> view?
>> >>>
>> >>> You can forgo any re-training of course, that should work too. It's just
>> >>> that DP spec and everyone else seem to recommend to at least do some
>> >>> minimal effort (or maybe even upfront link training) here. But totally not
>> >>> doing anything if the link is bad should be ok too (and probably really
>> >>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
>> >>> function which checks link status and set link-status to bad&fires off the
>> >>> uevent if needed.
>> >>>
>> >>> Again, do you have some sample prose to add here to clarify this?
>> >>>
>> >>
>> >> I don't think it's merely a matter of clarifying the comment, tbh.
>> >> Without relying on userspace to fix us, there's not much point in
>> >> exposing the property in the first place.
>> >>
>> >> As a driver author, I need to decide whether I want re-training to
>> >> work properly. If I do, I need to handroll it in my driver since I
>> >> can't rely on userspace, at which point, implementing the property
>> >> isn't meaningful. If I don't care about it being bulletproof, I can
>> >> expose the property and let userspace fix me if they know how.
>> >>
>> >> So I'd prefer to have the helper be a hybrid between this patch and
>> >> the previous one that did a full modeset under the covers (perhaps
>> >> with a client cap or similar to let us know which path to trust). That
>> >> way I can call the helper from my driver and know that I'm going to be
>> >> re-trained either way.
>> >
>> > If your driver is able to handle everything in kernel, then do so by all
>> > means. If it can't, defer to userspace, which may or may not fix stuff,
>> > depending on whether it looks at the property. If the userspace doesn't
>> > do anything, things will be just as good or bad as they are currently,
>> > before this property.
>> >
>> > This allows the drivers to choose how much they can/want to do in
>> > kernel, and what they defer to userspace.
>> >
>>
>> Just because I can, doesn't mean I want to :)
>>
>> Take the CDN DP driver in rockchip for example (posted yesterday).
>> There's a worker in the driver that is responsible for handling
>> hpd/extcon events from the USB-C port. Ideally, this worker should
>> just be a thin shell around a kms uevent that lets userspace know
>> there's been a change. Unfortunately since we need to make re-training
>> work (/me grumbles about productization) seamlessly, we need to add a
>> bunch of goo into the worker to handle re-training. Since we need to
>> handle re-training there and in modeset, we need to properly
>> synchronize things. So we end up with a bunch of code that doesn't
>> *really* need to be there.
>>
>> So is the correct path forward to add GOOD/BAD connection handling to
>> Chrome/drm_hwc and rip re-training out of the various kernel drivers?
>
> In i915 I think we might still want to do the "try to retrain with
> the current link parameters" thing automagically. It's not difficult
> to do after all, and should be faster than doing a full modeset.
>

I'm not sure I buy the "It's not difficult to do" argument. We've
squashed a ton of asynchronous training bugs over the past few years
in various drivers. It's just one more thing that needs to be
synchronized with hotplug/modeset/suspend/disable, and Synchronization
Is Hard for a lot of people.

So while it may be faster, I'd happily take the performance hit to unify paths.

Sean


>>
>> Sean
>>
>>
>> > BR,
>> > Jani.
>> >
>> >
>> >
>> >>
>> >> Sean
>> >>
>> >>
>> >>> Thanks for taking a look at this.
>> >>>
>> >>> Cheers, Daniel
>> >>>
>> >>>> > + * The DRM driver can chose to not modify property and keep link status
>> >>>> > + * as "GOOD" always to keep the user experience same as it currently is.
>> >>>> > + *
>> >>>> > + * The reason for adding this property is to handle link training failures, but
>> >>>> > + * it is not limited to DP or link training. For example, if we implement
>> >>>> > + * asynchronous setcrtc, this property can be used to report any failures in that.
>> >>>> > + */
>> >>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>> >>>> > +                                                uint64_t link_status)
>> >>>> > +{
>> >>>> > +       struct drm_device *dev = connector->dev;
>> >>>> > +
>> >>>> > +       /* Make sure the mutex is grabbed */
>> >>>> > +       lockdep_assert_held(&dev->mode_config.mutex);
>> >>>> > +       connector->link_status = link_status;
>> >>>> > +       drm_object_property_set_value(&connector->base,
>> >>>> > +                                     dev->mode_config.link_status_property,
>> >>>> > +                                     link_status);
>> >>>> > +}
>> >>>> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>> >>>> > +
>> >>>> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>> >>>> >                                     struct drm_property *property,
>> >>>> >                                     uint64_t value)
>> >>>> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>> >>>> > index 34f9741..3d513ab 100644
>> >>>> > --- a/include/drm/drm_connector.h
>> >>>> > +++ b/include/drm/drm_connector.h
>> >>>> > @@ -213,6 +213,9 @@ struct drm_connector_state {
>> >>>> >
>> >>>> >         struct drm_encoder *best_encoder;
>> >>>> >
>> >>>> > +       /* Connector Link status */
>> >>>> > +       unsigned int link_status;
>> >>>> > +
>> >>>> >         struct drm_atomic_state *state;
>> >>>> >  };
>> >>>> >
>> >>>> > @@ -695,6 +698,12 @@ struct drm_connector {
>> >>>> >         uint8_t num_h_tile, num_v_tile;
>> >>>> >         uint8_t tile_h_loc, tile_v_loc;
>> >>>> >         uint16_t tile_h_size, tile_v_size;
>> >>>> > +
>> >>>> > +       /* Connector Link status
>> >>>> > +        * 0: If the link is Good
>> >>>> > +        * 1: If the link is Bad
>> >>>> > +        */
>> >>>> > +       int link_status;
>> >>>> >  };
>> >>>> >
>> >>>> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>> >>>> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>> >>>> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>> >>>> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>> >>>> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>> >>>> > -
>> >>>>
>> >>>> lost a line here
>> >>>>
>> >>>> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>> >>>> >                                          const char *path);
>> >>>> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>> >>>> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>> >>>> >                                             const struct edid *edid);
>> >>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>> >>>> > +                                                uint64_t link_status);
>> >>>> >
>> >>>> >  /**
>> >>>> >   * struct drm_tile_group - Tile group metadata
>> >>>> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>> >>>> > index bf9991b..86faee4 100644
>> >>>> > --- a/include/drm/drm_mode_config.h
>> >>>> > +++ b/include/drm/drm_mode_config.h
>> >>>> > @@ -431,6 +431,11 @@ struct drm_mode_config {
>> >>>> >          */
>> >>>> >         struct drm_property *tile_property;
>> >>>> >         /**
>> >>>> > +        * @link_status_property: Default connector property for link status
>> >>>> > +        * of a connector
>> >>>> > +        */
>> >>>> > +       struct drm_property *link_status_property;
>> >>>> > +       /**
>> >>>> >          * @plane_type_property: Default plane property to differentiate
>> >>>> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>> >>>> >          */
>> >>>> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>> >>>> > index 728790b..309c478 100644
>> >>>> > --- a/include/uapi/drm/drm_mode.h
>> >>>> > +++ b/include/uapi/drm/drm_mode.h
>> >>>> > @@ -123,6 +123,10 @@
>> >>>> >  #define DRM_MODE_DIRTY_ON       1
>> >>>> >  #define DRM_MODE_DIRTY_ANNOTATE 2
>> >>>> >
>> >>>> > +/* Link Status options */
>> >>>> > +#define DRM_MODE_LINK_STATUS_GOOD      0
>> >>>> > +#define DRM_MODE_LINK_STATUS_BAD       1
>> >>>> > +
>> >>>> >  struct drm_mode_modeinfo {
>> >>>> >         __u32 clock;
>> >>>> >         __u16 hdisplay;
>> >>>> > --
>> >>>> > 1.9.1
>> >>>> >
>> >>>> > _______________________________________________
>> >>>> > dri-devel mailing list
>> >>>> > dri-devel@lists.freedesktop.org
>> >>>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>> >>>> _______________________________________________
>> >>>> dri-devel mailing list
>> >>>> dri-devel@lists.freedesktop.org
>> >>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>> >>>
>> >>> --
>> >>> Daniel Vetter
>> >>> Software Engineer, Intel Corporation
>> >>> http://blog.ffwll.ch
>> >> _______________________________________________
>> >> dri-devel mailing list
>> >> dri-devel@lists.freedesktop.org
>> >> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>> >
>> > --
>> > Jani Nikula, Intel Open Source Technology Center
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Ville Syrjälä
> Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 15:52           ` Jani Nikula
@ 2016-11-23 16:09             ` Sean Paul
  2016-11-23 16:11             ` Daniel Vetter
  1 sibling, 0 replies; 27+ messages in thread
From: Sean Paul @ 2016-11-23 16:09 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Manasi Navare, Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, Nov 23, 2016 at 10:52 AM, Jani Nikula
<jani.nikula@linux.intel.com> wrote:
> On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
>> On Wed, Nov 23, 2016 at 10:15 AM, Jani Nikula
>> <jani.nikula@linux.intel.com> wrote:
>>> On Wed, 23 Nov 2016, Sean Paul <seanpaul@chromium.org> wrote:
>>>> On Wed, Nov 23, 2016 at 3:09 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>>>>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>>>>>> On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>>>>>> <manasi.d.navare@intel.com> wrote:
>>>>>> > This is RFC patch for adding a connector link-status property
>>>>>> > and making it atomic by adding it to the drm_connector_state.
>>>>>> > This is to make sure its wired properly in drm_atomic_connector_set_property
>>>>>> > and drm_atomic_connector_get_property functions.
>>>>>> >
>>>>>>
>>>>>> Thanks for sending this. We ran into some re-training awkwardness
>>>>>> recently, and I
>>>>>> was hoping for such a patch.
>>>>>>
>>>>>> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>>>>>> > Cc: Daniel Vetter <daniel.vetter@intel.com>
>>>>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>>>>> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>>>> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>>>>>> > ---
>>>>>> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>>>>>> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>>>>>> >  include/drm/drm_connector.h     | 12 +++++++-
>>>>>> >  include/drm/drm_mode_config.h   |  5 ++++
>>>>>> >  include/uapi/drm/drm_mode.h     |  4 +++
>>>>>> >  5 files changed, 88 insertions(+), 3 deletions(-)
>>>>>> >
>>>>>> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>>>>>> > index 89737e4..644d19f 100644
>>>>>> > --- a/drivers/gpu/drm/drm_atomic.c
>>>>>> > +++ b/drivers/gpu/drm/drm_atomic.c
>>>>>> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>>>>>> >                  * now?) atomic writes to DPMS property:
>>>>>> >                  */
>>>>>> >                 return -EINVAL;
>>>>>> > +       } else if (property == config->link_status_property) {
>>>>>> > +               state->link_status = val;
>>>>>
>>>>> I think we should have a check here to make sure userspace never tries to
>>>>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
>>>>> atomic userspace is supposed to be able to just restore everything to what
>>>>> it was.
>>>>>
>>>>> I don't think trying to set it to "BAD" should cause an error though, just
>>>>> silently keep the link status at "GOOG". So:
>>>>>
>>>>>         /* Never downgrade from GOOD to BAD on userspace's request here,
>>>>>          * only hw issues can do that. */
>>>>>         if (state->link_status == GOOD)
>>>>>                 return 0;
>>>>
>>>> Can we return an error if the transition is invalid?
>>>>
>>>>>         state->link_status = val;
>>>>>         return 0;
>>>>>
>>>>>> > +               return 0;
>>>>>> >         } else if (connector->funcs->atomic_set_property) {
>>>>>> >                 return connector->funcs->atomic_set_property(connector,
>>>>>> >                                 state, property, val);
>>>>>> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>>>>>> >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>>>>>> >         } else if (property == config->dpms_property) {
>>>>>> >                 *val = connector->dpms;
>>>>>> > +       } else if (property == config->link_status_property) {
>>>>>> > +               *val = state->link_status;
>>>>>> >         } else if (connector->funcs->atomic_get_property) {
>>>>>> >                 return connector->funcs->atomic_get_property(connector,
>>>>>> >                                 state, property, val);
>>>>>> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>>>>>> > index 5a45262..4576c9f 100644
>>>>>> > --- a/drivers/gpu/drm/drm_connector.c
>>>>>> > +++ b/drivers/gpu/drm/drm_connector.c
>>>>>> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>>>>>> >         drm_object_attach_property(&connector->base,
>>>>>> >                                       config->dpms_property, 0);
>>>>>> >
>>>>>> > +       drm_object_attach_property(&connector->base,
>>>>>> > +                                  config->link_status_property,
>>>>>> > +                                  0);
>>>>>> > +
>>>>>> >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>>>>>> >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>>>>>> >         }
>>>>>> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>>>>>> >  };
>>>>>> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>>>>>> >
>>>>>> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>>>>>> > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>>>>>> > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>>>>>> > +};
>>>>>> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>>>>>> > +
>>>>>> >  /**
>>>>>> >   * drm_display_info_set_bus_formats - set the supported bus formats
>>>>>> >   * @info: display info to store bus formats in
>>>>>> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>>>>> >   *     path property the MST manager created. Userspace cannot change this
>>>>>> >   *     property.
>>>>>> >   * TILE:
>>>>>> > - *     Connector tile group property to indicate how a set of DRM connector
>>>>>> > + *      Connector tile group property to indicate how a set of DRM connector
>>>>>>
>>>>>> keyboard slip here
>>>>>>
>>>>>> >   *     compose together into one logical screen. This is used by both high-res
>>>>>> >   *     external screens (often only using a single cable, but exposing multiple
>>>>>> >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>>>>>> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>>>>> >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>>>>>> >   *     should update this value using drm_mode_connector_set_tile_property().
>>>>>> >   *     Userspace cannot change this property.
>>>>>> > - *
>>>>>> > + * link-status:
>>>>>> > + *      Connector link-status property to indicate the status of link during
>>>>>> > + *      the modeset. The default value of link-status is "GOOD". If something
>>>>>> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>>>>>> > + *      the mode list based on new link parameters and send a hotplug uevent
>>>>>> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>>>>>> > + *      IOCTL and redo a modeset. Drivers should update this value using
>>>>>> > + *      drm_mode_connector_set_link_status_property().
>>>>>> >   * Connectors also have one standardized atomic property:
>>>>>> >   *
>>>>>> >   * CRTC_ID:
>>>>>> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>>>>>> >                 return -ENOMEM;
>>>>>> >         dev->mode_config.tile_property = prop;
>>>>>> >
>>>>>> > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>>>>>> > +                                       drm_link_status_enum_list,
>>>>>> > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>>>>>> > +       if (!prop)
>>>>>> > +               return -ENOMEM;
>>>>>> > +       dev->mode_config.link_status_property = prop;
>>>>>> > +
>>>>>> >         return 0;
>>>>>> >  }
>>>>>> >
>>>>>> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>>>>> >  }
>>>>>> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>>>>>> >
>>>>>> > +/**
>>>>>> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>>>>>> > + * @connector: drm connector
>>>>>> > + * @link_status: new value of link status property (0: Good, 1: Bad)
>>>>>> > + *
>>>>>> > + * In usual working scenario, this link status property will always be set to
>>>>>> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>>>>>> > + * set this link status property to "BAD" and prune the mode list based on new
>>>>>>
>>>>>> Does the mode list really *need* to be pruned? In the case of needing
>>>>>> to re-train a DP link,
>>>>>> it seems like we should be able to set this BAD and keep the modelist
>>>>>> as-is (since the sink
>>>>>> hasn't changed)
>>>>>
>>>>> Well, if you prune it with the same constraints as before, no additional
>>>>> modes will be removed and the same list is there. Pruning here refers to
>>>>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>>>>>
>>>>> We might want to be a bit more explicit here perhaps? Have some good
>>>>> proposal text to insert?
>>>>
>>>> Ah, hmm, I hadn't equated this prune to the normal drm_connector
>>>> prune_invalid. I suppose the "based on new information" is what did
>>>> it. It seems like the mode_valid pruning will happen automagically
>>>> when userspace realizes the connection is BAD and asks for a new mode
>>>> list. So is it worth even mentioning pruning the mode list?
>>>>
>>>>>>
>>>>>> > + * information. The caller then needs to send a hotplug uevent for userspace to
>>>>>> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>>>>>>
>>>>>> extra space
>>>>>>
>>>>>> > + *
>>>>>> > + * Note that a lot of existing userspace do not handle this property.
>>>>>> > + * Drivers can therefore not rely on userspace to fix up everything and
>>>>>> > + * should try to handle issues (like just re-training a link) without
>>>>>> > + * userspace's intervention. This should only be used when the current mode
>>>>>> > + * fails and userspace must select a different display mode.
>>>>>>
>>>>>> Hmm, I suppose this answers my last question. It's too bad we can't
>>>>>> rely on this, since we'll
>>>>>> just end up with each driver rolling their own re-training logic on
>>>>>> top of possibly supporting
>>>>>> this (but probably not, since it's really just overhead). Perhaps this
>>>>>> is an overly pessimistic
>>>>>> view?
>>>>>
>>>>> You can forgo any re-training of course, that should work too. It's just
>>>>> that DP spec and everyone else seem to recommend to at least do some
>>>>> minimal effort (or maybe even upfront link training) here. But totally not
>>>>> doing anything if the link is bad should be ok too (and probably really
>>>>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
>>>>> function which checks link status and set link-status to bad&fires off the
>>>>> uevent if needed.
>>>>>
>>>>> Again, do you have some sample prose to add here to clarify this?
>>>>>
>>>>
>>>> I don't think it's merely a matter of clarifying the comment, tbh.
>>>> Without relying on userspace to fix us, there's not much point in
>>>> exposing the property in the first place.
>>>>
>>>> As a driver author, I need to decide whether I want re-training to
>>>> work properly. If I do, I need to handroll it in my driver since I
>>>> can't rely on userspace, at which point, implementing the property
>>>> isn't meaningful. If I don't care about it being bulletproof, I can
>>>> expose the property and let userspace fix me if they know how.
>>>>
>>>> So I'd prefer to have the helper be a hybrid between this patch and
>>>> the previous one that did a full modeset under the covers (perhaps
>>>> with a client cap or similar to let us know which path to trust). That
>>>> way I can call the helper from my driver and know that I'm going to be
>>>> re-trained either way.
>>>
>>> If your driver is able to handle everything in kernel, then do so by all
>>> means. If it can't, defer to userspace, which may or may not fix stuff,
>>> depending on whether it looks at the property. If the userspace doesn't
>>> do anything, things will be just as good or bad as they are currently,
>>> before this property.
>>>
>>> This allows the drivers to choose how much they can/want to do in
>>> kernel, and what they defer to userspace.
>>>
>>
>> Just because I can, doesn't mean I want to :)
>
> And just because I want to, doesn't mean I can! ;)
>

Truth. Many people have tried and failed :-D

>> Take the CDN DP driver in rockchip for example (posted yesterday).
>> There's a worker in the driver that is responsible for handling
>> hpd/extcon events from the USB-C port. Ideally, this worker should
>> just be a thin shell around a kms uevent that lets userspace know
>> there's been a change. Unfortunately since we need to make re-training
>> work (/me grumbles about productization) seamlessly, we need to add a
>> bunch of goo into the worker to handle re-training. Since we need to
>> handle re-training there and in modeset, we need to properly
>> synchronize things. So we end up with a bunch of code that doesn't
>> *really* need to be there.
>>
>> So is the correct path forward to add GOOD/BAD connection handling to
>> Chrome/drm_hwc
>
> I think so.
>
>> and rip re-training out of the various kernel drivers?
>
> IMO if it works, don't change it, at least not in a rush. It also
> depends on the hardware and the driver; the amount of code required may
> be vastly different for various drivers.
>
> Personally, I think in the long run letting userspace help here leads to
> a simpler design and more efficient happy day scenario handling, and
> userspace knows what's going on.
>

Agreed on this.

I wish there were an easier way for drivers to do the right thing, but
I suppose we can struggle on until userspace supports this :/

Sean


> BR,
> Jani.
>
>>
>> Sean
>>
>>
>>> BR,
>>> Jani.
>>>
>>>
>>>
>>>>
>>>> Sean
>>>>
>>>>
>>>>> Thanks for taking a look at this.
>>>>>
>>>>> Cheers, Daniel
>>>>>
>>>>>> > + * The DRM driver can chose to not modify property and keep link status
>>>>>> > + * as "GOOD" always to keep the user experience same as it currently is.
>>>>>> > + *
>>>>>> > + * The reason for adding this property is to handle link training failures, but
>>>>>> > + * it is not limited to DP or link training. For example, if we implement
>>>>>> > + * asynchronous setcrtc, this property can be used to report any failures in that.
>>>>>> > + */
>>>>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>>>>> > +                                                uint64_t link_status)
>>>>>> > +{
>>>>>> > +       struct drm_device *dev = connector->dev;
>>>>>> > +
>>>>>> > +       /* Make sure the mutex is grabbed */
>>>>>> > +       lockdep_assert_held(&dev->mode_config.mutex);
>>>>>> > +       connector->link_status = link_status;
>>>>>> > +       drm_object_property_set_value(&connector->base,
>>>>>> > +                                     dev->mode_config.link_status_property,
>>>>>> > +                                     link_status);
>>>>>> > +}
>>>>>> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>>>>>> > +
>>>>>> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>>>>>> >                                     struct drm_property *property,
>>>>>> >                                     uint64_t value)
>>>>>> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>>>>>> > index 34f9741..3d513ab 100644
>>>>>> > --- a/include/drm/drm_connector.h
>>>>>> > +++ b/include/drm/drm_connector.h
>>>>>> > @@ -213,6 +213,9 @@ struct drm_connector_state {
>>>>>> >
>>>>>> >         struct drm_encoder *best_encoder;
>>>>>> >
>>>>>> > +       /* Connector Link status */
>>>>>> > +       unsigned int link_status;
>>>>>> > +
>>>>>> >         struct drm_atomic_state *state;
>>>>>> >  };
>>>>>> >
>>>>>> > @@ -695,6 +698,12 @@ struct drm_connector {
>>>>>> >         uint8_t num_h_tile, num_v_tile;
>>>>>> >         uint8_t tile_h_loc, tile_v_loc;
>>>>>> >         uint16_t tile_h_size, tile_v_size;
>>>>>> > +
>>>>>> > +       /* Connector Link status
>>>>>> > +        * 0: If the link is Good
>>>>>> > +        * 1: If the link is Bad
>>>>>> > +        */
>>>>>> > +       int link_status;
>>>>>> >  };
>>>>>> >
>>>>>> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>>>>>> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>>>>>> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>>>>>> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>>>>>> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>>>>>> > -
>>>>>>
>>>>>> lost a line here
>>>>>>
>>>>>> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>>>>>> >                                          const char *path);
>>>>>> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>>>>>> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>>>>> >                                             const struct edid *edid);
>>>>>> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>>>>> > +                                                uint64_t link_status);
>>>>>> >
>>>>>> >  /**
>>>>>> >   * struct drm_tile_group - Tile group metadata
>>>>>> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>>>>>> > index bf9991b..86faee4 100644
>>>>>> > --- a/include/drm/drm_mode_config.h
>>>>>> > +++ b/include/drm/drm_mode_config.h
>>>>>> > @@ -431,6 +431,11 @@ struct drm_mode_config {
>>>>>> >          */
>>>>>> >         struct drm_property *tile_property;
>>>>>> >         /**
>>>>>> > +        * @link_status_property: Default connector property for link status
>>>>>> > +        * of a connector
>>>>>> > +        */
>>>>>> > +       struct drm_property *link_status_property;
>>>>>> > +       /**
>>>>>> >          * @plane_type_property: Default plane property to differentiate
>>>>>> >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>>>>>> >          */
>>>>>> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>>>>>> > index 728790b..309c478 100644
>>>>>> > --- a/include/uapi/drm/drm_mode.h
>>>>>> > +++ b/include/uapi/drm/drm_mode.h
>>>>>> > @@ -123,6 +123,10 @@
>>>>>> >  #define DRM_MODE_DIRTY_ON       1
>>>>>> >  #define DRM_MODE_DIRTY_ANNOTATE 2
>>>>>> >
>>>>>> > +/* Link Status options */
>>>>>> > +#define DRM_MODE_LINK_STATUS_GOOD      0
>>>>>> > +#define DRM_MODE_LINK_STATUS_BAD       1
>>>>>> > +
>>>>>> >  struct drm_mode_modeinfo {
>>>>>> >         __u32 clock;
>>>>>> >         __u16 hdisplay;
>>>>>> > --
>>>>>> > 1.9.1
>>>>>> >
>>>>>> > _______________________________________________
>>>>>> > dri-devel mailing list
>>>>>> > dri-devel@lists.freedesktop.org
>>>>>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>>>> _______________________________________________
>>>>>> dri-devel mailing list
>>>>>> dri-devel@lists.freedesktop.org
>>>>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>>>
>>>>> --
>>>>> Daniel Vetter
>>>>> Software Engineer, Intel Corporation
>>>>> http://blog.ffwll.ch
>>>> _______________________________________________
>>>> dri-devel mailing list
>>>> dri-devel@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>
>>> --
>>> Jani Nikula, Intel Open Source Technology Center
>
> --
> Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 15:52           ` Jani Nikula
  2016-11-23 16:09             ` Sean Paul
@ 2016-11-23 16:11             ` Daniel Vetter
  1 sibling, 0 replies; 27+ messages in thread
From: Daniel Vetter @ 2016-11-23 16:11 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Manasi Navare, Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, Nov 23, 2016 at 4:52 PM, Jani Nikula
<jani.nikula@linux.intel.com> wrote:
>> Take the CDN DP driver in rockchip for example (posted yesterday).
>> There's a worker in the driver that is responsible for handling
>> hpd/extcon events from the USB-C port. Ideally, this worker should
>> just be a thin shell around a kms uevent that lets userspace know
>> there's been a change. Unfortunately since we need to make re-training
>> work (/me grumbles about productization) seamlessly, we need to add a
>> bunch of goo into the worker to handle re-training. Since we need to
>> handle re-training there and in modeset, we need to properly
>> synchronize things. So we end up with a bunch of code that doesn't
>> *really* need to be there.
>>
>> So is the correct path forward to add GOOD/BAD connection handling to
>> Chrome/drm_hwc
>
> I think so.
>
>> and rip re-training out of the various kernel drivers?
>
> IMO if it works, don't change it, at least not in a rush. It also
> depends on the hardware and the driver; the amount of code required may
> be vastly different for various drivers.
>
> Personally, I think in the long run letting userspace help here leads to
> a simpler design and more efficient happy day scenario handling, and
> userspace knows what's going on.

We can't rip out re-training from existing drivers since it would
break existing userspace in certain cases (like cable re-plug into
same screen). But we could try to not implement so much for new
drivers.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23 10:00 ` Daniel Vetter
@ 2016-11-23 19:07   ` Manasi Navare
  0 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-11-23 19:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, intel-gfx, dri-devel

On Wed, Nov 23, 2016 at 11:00:59AM +0100, Daniel Vetter wrote:
> On Tue, Nov 22, 2016 at 05:30:21PM -0800, Manasi Navare wrote:
> > This is RFC patch for adding a connector link-status property
> > and making it atomic by adding it to the drm_connector_state.
> > This is to make sure its wired properly in drm_atomic_connector_set_property
> > and drm_atomic_connector_get_property functions.
> > 
> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
> >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
> >  include/drm/drm_connector.h     | 12 +++++++-
> >  include/drm/drm_mode_config.h   |  5 ++++
> >  include/uapi/drm/drm_mode.h     |  4 +++
> >  5 files changed, 88 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 89737e4..644d19f 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> >  		 * now?) atomic writes to DPMS property:
> >  		 */
> >  		return -EINVAL;
> > +	} else if (property == config->link_status_property) {
> > +		state->link_status = val;
> > +		return 0;
> >  	} else if (connector->funcs->atomic_set_property) {
> >  		return connector->funcs->atomic_set_property(connector,
> >  				state, property, val);
> > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
> >  		*val = (state->crtc) ? state->crtc->base.id : 0;
> >  	} else if (property == config->dpms_property) {
> >  		*val = connector->dpms;
> > +	} else if (property == config->link_status_property) {
> > +		*val = state->link_status;
> >  	} else if (connector->funcs->atomic_get_property) {
> >  		return connector->funcs->atomic_get_property(connector,
> >  				state, property, val);
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 5a45262..4576c9f 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
> >  	drm_object_attach_property(&connector->base,
> >  				      config->dpms_property, 0);
> >  
> > +	drm_object_attach_property(&connector->base,
> > +				   config->link_status_property,
> > +				   0);
> > +
> >  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> >  		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
> >  	}
> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
> >  };
> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
> >  
> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> > +	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
> > +	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
> > +};
> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> > +
> >  /**
> >   * drm_display_info_set_bus_formats - set the supported bus formats
> >   * @info: display info to store bus formats in
> > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >   * 	path property the MST manager created. Userspace cannot change this
> >   * 	property.
> >   * TILE:
> > - * 	Connector tile group property to indicate how a set of DRM connector
> > + *      Connector tile group property to indicate how a set of DRM connector
> >   * 	compose together into one logical screen. This is used by both high-res
> >   * 	external screens (often only using a single cable, but exposing multiple
> >   * 	DP MST sinks), or high-res integrated panels (like dual-link DSI) which
> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >   * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
> >   * 	should update this value using drm_mode_connector_set_tile_property().
> >   * 	Userspace cannot change this property.
> > - *
> > + * link-status:
> > + *      Connector link-status property to indicate the status of link during
> > + *      the modeset. The default value of link-status is "GOOD". If something
> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
> > + *      the mode list based on new link parameters and send a hotplug uevent
> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> > + *      IOCTL and redo a modeset. Drivers should update this value using
> > + *      drm_mode_connector_set_link_status_property().
> >   * Connectors also have one standardized atomic property:
> >   *
> >   * CRTC_ID:
> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> >  		return -ENOMEM;
> >  	dev->mode_config.tile_property = prop;
> >  
> > +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> > +					drm_link_status_enum_list,
> > +					ARRAY_SIZE(drm_link_status_enum_list));
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	dev->mode_config.link_status_property = prop;
> > +
> >  	return 0;
> >  }
> >  
> > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >  }
> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
> >  
> > +/**
> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> > + * @connector: drm connector
> > + * @link_status: new value of link status property (0: Good, 1: Bad)
> > + *
> > + * In usual working scenario, this link status property will always be set to
> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
> > + * set this link status property to "BAD" and prune the mode list based on new
> > + * information. The caller then needs to send a hotplug uevent for userspace to
> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> > + *
> > + * Note that a lot of existing userspace do not handle this property.
> > + * Drivers can therefore not rely on userspace to fix up everything and
> > + * should try to handle issues (like just re-training a link) without
> > + * userspace's intervention. This should only be used when the current mode
> > + * fails and userspace must select a different display mode.
> > + * The DRM driver can chose to not modify property and keep link status
> > + * as "GOOD" always to keep the user experience same as it currently is.
> > + *
> > + * The reason for adding this property is to handle link training failures, but
> > + * it is not limited to DP or link training. For example, if we implement
> > + * asynchronous setcrtc, this property can be used to report any failures in that.
> > + */
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +						 uint64_t link_status)
> > +{
> > +	struct drm_device *dev = connector->dev;
> > +
> > +	/* Make sure the mutex is grabbed */
> > +	lockdep_assert_held(&dev->mode_config.mutex);
> 
> For atomic the lock we need is dev->mode_config.connection_mutex); Maybe
> we should just grab that here, from a quick check it shouldn't result in a
> deadlock.
>

So after grabing the connection mutex, do we still need the lockdep assert held for
mode_config.mutex?
This gets called from the work func that holds the mode-config.mutex, do we need to drop that
mutex then or is it okay to hold mode_config.mutex as well as connection mutex?

 
> > +	connector->link_status = link_status;
> 
> You need to set connector->state->link_status here for an atomic property.
>

Yes I need to set the connector state here. I will add that.
 
> > +	drm_object_property_set_value(&connector->base,
> > +				      dev->mode_config.link_status_property,
> > +				      link_status);
> 
> And this here isn't needed anymore with atomic.
>

So we no longer have the link_status property in mode_config struct?
All we have is the link_status in dmr_connector_state?

Manasi 
> > +}
> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> > +
> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> >  				    struct drm_property *property,
> >  				    uint64_t value)
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index 34f9741..3d513ab 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -213,6 +213,9 @@ struct drm_connector_state {
> >  
> >  	struct drm_encoder *best_encoder;
> >  
> > +	/* Connector Link status */
> > +	unsigned int link_status;
> 
> enum drm_link_status {
> 	DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD;
> 	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_GOOD;
> };
> 
> This way you don't need a comment explaing that 0 is good and 1 is bad.
> 
> > +
> >  	struct drm_atomic_state *state;
> >  };
> >  
> > @@ -695,6 +698,12 @@ struct drm_connector {
> >  	uint8_t num_h_tile, num_v_tile;
> >  	uint8_t tile_h_loc, tile_v_loc;
> >  	uint16_t tile_h_size, tile_v_size;
> > +
> > +	/* Connector Link status
> > +	 * 0: If the link is Good
> > +	 * 1: If the link is Bad
> > +	 */
> > +	int link_status;
> 
> This one needs to go, we don't want to duplicate this information.
> 
> >  };

This was added so we can easily grab this value within intel_dp functions,
or should those functions directly read the connector->state->link_sttaus?


> >  
> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> > -
> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
> >  					 const char *path);
> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >  					    const struct edid *edid);
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +						 uint64_t link_status);
> >  
> >  /**
> >   * struct drm_tile_group - Tile group metadata
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index bf9991b..86faee4 100644
> > --- a/include/drm/drm_mode_config.h
> > +++ b/include/drm/drm_mode_config.h
> > @@ -431,6 +431,11 @@ struct drm_mode_config {
> >  	 */
> >  	struct drm_property *tile_property;
> >  	/**
> > +	 * @link_status_property: Default connector property for link status
> > +	 * of a connector
> > +	 */
> > +	struct drm_property *link_status_property;
> > +	/**
> >  	 * @plane_type_property: Default plane property to differentiate
> >  	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
> >  	 */
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 728790b..309c478 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -123,6 +123,10 @@
> >  #define DRM_MODE_DIRTY_ON       1
> >  #define DRM_MODE_DIRTY_ANNOTATE 2
> >  
> > +/* Link Status options */
> > +#define DRM_MODE_LINK_STATUS_GOOD	0
> > +#define DRM_MODE_LINK_STATUS_BAD	1
> 
> The change to reset link_status to good for SETCRTC seems to be missing.
> Something like the below (totally untested) should get the job done.
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 494680c9056e..5f47049d611e 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2258,6 +2258,8 @@ static int update_output_state(struct drm_atomic_state *state,
>  								NULL);
>  			if (ret)
>  				return ret;
> +
> +			conn_state->link_status = DRM_LINK_STATUS_GOOD;
>  		}
>  	}
>  
> Small exercise for you: Follow the call chain of this function and figure
> out how it works. And let's hope I did it right and it does work ;-)
> 
> Cheers, Daniel
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH RFC v2] drm: Add a new connector atomic property for link status
  2016-11-23  1:30 [PATCH RFC] drm: Add a new connector atomic property for link status Manasi Navare
                   ` (2 preceding siblings ...)
  2016-11-23 10:00 ` Daniel Vetter
@ 2016-11-24  2:38 ` Manasi Navare
  2016-11-24  7:28   ` [PATCH RFC v3] " Manasi Navare
  2016-11-24  4:01 ` ✗ Fi.CI.BAT: failure for drm: Add a new connector atomic property for link status (rev3) Patchwork
  2016-11-24  8:45 ` ✓ Fi.CI.BAT: success for drm: Add a new connector atomic property for link status (rev4) Patchwork
  5 siblings, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-11-24  2:38 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: Daniel Vetter

This is RFC patch for adding a connector link-status property
and making it atomic by adding it to the drm_connector_state.
This is to make sure its wired properly in drm_atomic_connector_set_property
and drm_atomic_connector_get_property functions.

v2:
* Removed connector->link_status (Daniel Vetter)
* Set connector->state->link_status in drm_mode_connector_set_link_status_property
(Daniel Vetter)
* Set the connector_changed flag to true if connector->state->link_status changed.
* Reset link_status to GOOD in update_output_state (Daniel Vetter)
* Never allow userspace to set link status from Good To Bad (Daniel Vetter)

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 10 ++++++
 drivers/gpu/drm/drm_atomic_helper.c |  8 +++++
 drivers/gpu/drm/drm_connector.c     | 61 ++++++++++++++++++++++++++++++++++++-
 include/drm/drm_connector.h         | 18 ++++++++++-
 include/drm/drm_mode_config.h       |  5 +++
 include/uapi/drm/drm_mode.h         |  4 +++
 6 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 89737e4..2cfaea9 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1087,6 +1087,14 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
 		 * now?) atomic writes to DPMS property:
 		 */
 		return -EINVAL;
+	} else if (property == config->link_status_property) {
+		/* Never downgrade from GOOD to BAD on userspace's request here,
+		 * only hw issues can do that.
+		 */
+		if (state->link_status == GOOD)
+			return 0;
+		state->link_status = val;
+		return 0;
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -1135,6 +1143,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 		*val = (state->crtc) ? state->crtc->base.id : 0;
 	} else if (property == config->dpms_property) {
 		*val = connector->dpms;
+	} else if (property == config->link_status_property) {
+		*val = state->link_status;
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 494680c..962ed66 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -519,6 +519,13 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 					       connector_state);
 		if (ret)
 			return ret;
+		if (connector->state->crtc) {
+			crtc_state = drm_atomic_get_existing_crtc_state(state,
+									connector->state->crtc);
+			if (connector->state->link_status !=
+			    connector_state->link_status)
+				crtc_state->connectors_changed = true;
+		}
 	}
 
 	/*
@@ -2258,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
 								NULL);
 			if (ret)
 				return ret;
+			conn_state->link_status = DRM_LINK_STATUS_GOOD;
 		}
 	}
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 5a45262..cd53c39 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
 	drm_object_attach_property(&connector->base,
 				      config->dpms_property, 0);
 
+	drm_object_attach_property(&connector->base,
+				   config->link_status_property,
+				   0);
+
 	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
 	}
@@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
 };
 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
 
+static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
+	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
+	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
+};
+DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
+
 /**
  * drm_display_info_set_bus_formats - set the supported bus formats
  * @info: display info to store bus formats in
@@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
  * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
  * 	should update this value using drm_mode_connector_set_tile_property().
  * 	Userspace cannot change this property.
- *
+ * link-status:
+ *      Connector link-status property to indicate the status of link during
+ *      the modeset. The default value of link-status is "GOOD". If something
+ *      fails during modeset, the kernel driver can set this to "BAD", prune
+ *      the mode list based on new link parameters and send a hotplug uevent
+ *      to notify userspace to re-check the valid modes through GET_CONNECTOR
+ *      IOCTL and redo a modeset. Drivers should update this value using
+ *      drm_mode_connector_set_link_status_property().
  * Connectors also have one standardized atomic property:
  *
  * CRTC_ID:
@@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
 		return -ENOMEM;
 	dev->mode_config.tile_property = prop;
 
+	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
+					drm_link_status_enum_list,
+					ARRAY_SIZE(drm_link_status_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.link_status_property = prop;
+
 	return 0;
 }
 
@@ -995,6 +1019,41 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
 
+/**
+ * drm_mode_connector_set_link_status_property - Set link status property of a connector
+ * @connector: drm connector
+ * @link_status: new value of link status property (0: Good, 1: Bad)
+ *
+ * In usual working scenario, this link status property will always be set to
+ * "GOOD". If something fails during or after a mode set, the kernel driver should
+ * set this link status property to "BAD" and prune the mode list based on new
+ * information. The caller then needs to send a hotplug uevent for userspace to
+ *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
+ *
+ * Note that a lot of existing userspace do not handle this property.
+ * Drivers can therefore not rely on userspace to fix up everything and
+ * should try to handle issues (like just re-training a link) without
+ * userspace's intervention. This should only be used when the current mode
+ * fails and userspace must select a different display mode.
+ * The DRM driver can chose to not modify property and keep link status
+ * as "GOOD" always to keep the user experience same as it currently is.
+ *
+ * The reason for adding this property is to handle link training failures, but
+ * it is not limited to DP or link training. For example, if we implement
+ * asynchronous setcrtc, this property can be used to report any failures in that.
+ */
+void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
+						 uint64_t link_status)
+{
+	struct drm_device *dev = connector->dev;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	connector->state->link_status = link_status;
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+}
+EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
+
 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 34f9741..ba22ed1 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -90,6 +90,17 @@ enum subpixel_order {
 };
 
 /**
+ * enum drm_link_status - connector's link_status property value
+ *
+ * This enum is used as the connector's link status property value.
+ * It is set to the values defined in uapi.
+ */
+enum drm_link_status {
+	DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD,
+	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
+};
+
+/**
  * struct drm_display_info - runtime data about the connected sink
  *
  * Describes a given display (e.g. CRT or flat panel) and its limitations. For
@@ -213,6 +224,9 @@ struct drm_connector_state {
 
 	struct drm_encoder *best_encoder;
 
+	/* Connector Link status */
+	enum drm_link_status link_status;
+
 	struct drm_atomic_state *state;
 };
 
@@ -695,6 +709,7 @@ struct drm_connector {
 	uint8_t num_h_tile, num_v_tile;
 	uint8_t tile_h_loc, tile_v_loc;
 	uint16_t tile_h_size, tile_v_size;
+
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -767,12 +782,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
 int drm_mode_create_scaling_mode_property(struct drm_device *dev);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
-
 int drm_mode_connector_set_path_property(struct drm_connector *connector,
 					 const char *path);
 int drm_mode_connector_set_tile_property(struct drm_connector *connector);
 int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 					    const struct edid *edid);
+void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
+						 uint64_t link_status);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index bf9991b..86faee4 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -431,6 +431,11 @@ struct drm_mode_config {
 	 */
 	struct drm_property *tile_property;
 	/**
+	 * @link_status_property: Default connector property for link status
+	 * of a connector
+	 */
+	struct drm_property *link_status_property;
+	/**
 	 * @plane_type_property: Default plane property to differentiate
 	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
 	 */
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 728790b..309c478 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -123,6 +123,10 @@
 #define DRM_MODE_DIRTY_ON       1
 #define DRM_MODE_DIRTY_ANNOTATE 2
 
+/* Link Status options */
+#define DRM_MODE_LINK_STATUS_GOOD	0
+#define DRM_MODE_LINK_STATUS_BAD	1
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* ✗ Fi.CI.BAT: failure for drm: Add a new connector atomic property for link status (rev3)
  2016-11-23  1:30 [PATCH RFC] drm: Add a new connector atomic property for link status Manasi Navare
                   ` (3 preceding siblings ...)
  2016-11-24  2:38 ` [PATCH RFC v2] " Manasi Navare
@ 2016-11-24  4:01 ` Patchwork
  2016-11-24  8:45 ` ✓ Fi.CI.BAT: success for drm: Add a new connector atomic property for link status (rev4) Patchwork
  5 siblings, 0 replies; 27+ messages in thread
From: Patchwork @ 2016-11-24  4:01 UTC (permalink / raw)
  To: Navare, Manasi D; +Cc: intel-gfx

== Series Details ==

Series: drm: Add a new connector atomic property for link status (rev3)
URL   : https://patchwork.freedesktop.org/series/15781/
State : failure

== Summary ==

  CC      drivers/acpi/acpica/utpredef.o
  CONMK   drivers/tty/vt/consolemap_deftbl.c
  CC      drivers/acpi/acpica/utownerid.o
  CC      drivers/acpi/acpica/utresrc.o
  CC      drivers/tty/vt/vt.o
  SHIPPED drivers/tty/vt/defkeymap.c
  CC      drivers/acpi/acpica/utstate.o
  CC      drivers/acpi/acpica/utstring.o
  CC      drivers/acpi/acpica/utstrtoul64.o
  CC      drivers/acpi/acpica/utxface.o
  CC      drivers/acpi/acpica/utxfinit.o
  CC      drivers/tty/vt/consolemap_deftbl.o
  CC      drivers/acpi/acpica/utxferror.o
  CC      drivers/acpi/acpica/utxfmutex.o
  CC      drivers/tty/vt/defkeymap.o
  LD      drivers/watchdog/watchdog.o
  LD      drivers/watchdog/built-in.o
  LD      kernel/sched/built-in.o
  LD [M]  drivers/misc/mei/mei-me.o
  LD      drivers/misc/built-in.o
  LD      kernel/built-in.o
  LD      drivers/input/mouse/psmouse.o
  LD [M]  drivers/ssb/ssb.o
  LD      drivers/input/mouse/built-in.o
  LD      drivers/input/built-in.o
  LD [M]  drivers/net/ethernet/broadcom/genet/genet.o
scripts/Makefile.build:544: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:544: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
make[1]: *** Waiting for unfinished jobs....
  LD      drivers/video/fbdev/core/fb.o
  LD      drivers/pci/pcie/pcieportdrv.o
  LD      drivers/video/fbdev/core/built-in.o
  LD      drivers/acpi/acpica/acpi.o
  LD [M]  drivers/usb/serial/usbserial.o
  LD      drivers/pci/pcie/aer/aerdriver.o
  LD      drivers/pci/pcie/aer/built-in.o
  LD      drivers/pci/pcie/built-in.o
  LD      drivers/iommu/built-in.o
  LD      drivers/mmc/built-in.o
  LD      drivers/acpi/acpica/built-in.o
  LD      drivers/video/fbdev/built-in.o
  LD      drivers/usb/storage/usb-storage.o
  LD      drivers/acpi/built-in.o
  LD      drivers/scsi/scsi_mod.o
  LD      drivers/usb/storage/built-in.o
  LD      net/ipv6/ipv6.o
  LD      drivers/tty/serial/8250/8250.o
  LD      drivers/usb/gadget/udc/udc-core.o
  LD      drivers/usb/gadget/udc/built-in.o
  LD      net/ipv6/built-in.o
  LD      drivers/thermal/thermal_sys.o
  LD      drivers/thermal/built-in.o
  LD      drivers/pci/built-in.o
  LD      drivers/usb/gadget/libcomposite.o
  LD      drivers/usb/gadget/built-in.o
  AR      lib/lib.a
  EXPORTS lib/lib-ksyms.o
  LD      lib/built-in.o
  LD      drivers/spi/built-in.o
  LD [M]  drivers/net/ethernet/intel/e1000/e1000.o
  LD      drivers/scsi/sd_mod.o
  LD [M]  sound/pci/hda/snd-hda-codec-generic.o
  LD      drivers/scsi/built-in.o
  LD      sound/pci/built-in.o
  LD      sound/built-in.o
  LD      drivers/video/console/built-in.o
  LD      drivers/video/built-in.o
  LD      drivers/usb/core/usbcore.o
  LD      drivers/tty/serial/8250/8250_base.o
  LD      drivers/tty/serial/8250/built-in.o
  LD      drivers/usb/core/built-in.o
  CC      arch/x86/kernel/cpu/capflags.o
  LD      arch/x86/kernel/cpu/built-in.o
  LD      drivers/md/md-mod.o
  LD      fs/btrfs/btrfs.o
  LD      drivers/tty/serial/built-in.o
  LD      arch/x86/kernel/built-in.o
  LD      drivers/md/built-in.o
  LD [M]  drivers/net/ethernet/intel/igbvf/igbvf.o
  LD      fs/btrfs/built-in.o
  LD      arch/x86/built-in.o
  LD      drivers/tty/vt/built-in.o
  LD      drivers/tty/built-in.o
  LD      drivers/usb/host/xhci-hcd.o
  LD      net/ipv4/built-in.o
  LD      drivers/usb/host/built-in.o
  LD [M]  drivers/net/ethernet/intel/igb/igb.o
  LD      drivers/usb/built-in.o
  LD      fs/ext4/ext4.o
  LD      fs/ext4/built-in.o
  LD      fs/built-in.o
  LD [M]  drivers/net/ethernet/intel/e1000e/e1000e.o
  LD      net/core/built-in.o
  LD      net/built-in.o
  LD      drivers/net/ethernet/built-in.o
  LD      drivers/net/built-in.o
Makefile:986: recipe for target 'drivers' failed
make: *** [drivers] Error 2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH RFC v3] drm: Add a new connector atomic property for link status
  2016-11-24  2:38 ` [PATCH RFC v2] " Manasi Navare
@ 2016-11-24  7:28   ` Manasi Navare
  2016-11-24  7:51     ` Daniel Vetter
  0 siblings, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-11-24  7:28 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: Manasi Navare, Daniel Vetter

This is RFC patch for adding a connector link-status property
and making it atomic by adding it to the drm_connector_state.
This is to make sure its wired properly in drm_atomic_connector_set_property
and drm_atomic_connector_get_property functions.

v3:
* Fixed a build error (Jani Saarinen)
v2:
* Removed connector->link_status (Daniel Vetter)
* Set connector->state->link_status in drm_mode_connector_set_link_status_property
(Daniel Vetter)
* Set the connector_changed flag to true if connector->state->link_status changed.
* Reset link_status to GOOD in update_output_state (Daniel Vetter)
* Never allow userspace to set link status from Good To Bad (Daniel Vetter)

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 10 ++++++
 drivers/gpu/drm/drm_atomic_helper.c |  8 +++++
 drivers/gpu/drm/drm_connector.c     | 61 ++++++++++++++++++++++++++++++++++++-
 include/drm/drm_connector.h         | 18 ++++++++++-
 include/drm/drm_mode_config.h       |  5 +++
 include/uapi/drm/drm_mode.h         |  4 +++
 6 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 89737e4..990f013 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1087,6 +1087,14 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
 		 * now?) atomic writes to DPMS property:
 		 */
 		return -EINVAL;
+	} else if (property == config->link_status_property) {
+		/* Never downgrade from GOOD to BAD on userspace's request here,
+		 * only hw issues can do that.
+		 */
+		if (state->link_status == DRM_LINK_STATUS_GOOD)
+			return 0;
+		state->link_status = val;
+		return 0;
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -1135,6 +1143,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 		*val = (state->crtc) ? state->crtc->base.id : 0;
 	} else if (property == config->dpms_property) {
 		*val = connector->dpms;
+	} else if (property == config->link_status_property) {
+		*val = state->link_status;
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 494680c..962ed66 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -519,6 +519,13 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
 					       connector_state);
 		if (ret)
 			return ret;
+		if (connector->state->crtc) {
+			crtc_state = drm_atomic_get_existing_crtc_state(state,
+									connector->state->crtc);
+			if (connector->state->link_status !=
+			    connector_state->link_status)
+				crtc_state->connectors_changed = true;
+		}
 	}
 
 	/*
@@ -2258,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
 								NULL);
 			if (ret)
 				return ret;
+			conn_state->link_status = DRM_LINK_STATUS_GOOD;
 		}
 	}
 
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 5a45262..cd53c39 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
 	drm_object_attach_property(&connector->base,
 				      config->dpms_property, 0);
 
+	drm_object_attach_property(&connector->base,
+				   config->link_status_property,
+				   0);
+
 	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
 		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
 	}
@@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
 };
 DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
 
+static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
+	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
+	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
+};
+DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
+
 /**
  * drm_display_info_set_bus_formats - set the supported bus formats
  * @info: display info to store bus formats in
@@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
  * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
  * 	should update this value using drm_mode_connector_set_tile_property().
  * 	Userspace cannot change this property.
- *
+ * link-status:
+ *      Connector link-status property to indicate the status of link during
+ *      the modeset. The default value of link-status is "GOOD". If something
+ *      fails during modeset, the kernel driver can set this to "BAD", prune
+ *      the mode list based on new link parameters and send a hotplug uevent
+ *      to notify userspace to re-check the valid modes through GET_CONNECTOR
+ *      IOCTL and redo a modeset. Drivers should update this value using
+ *      drm_mode_connector_set_link_status_property().
  * Connectors also have one standardized atomic property:
  *
  * CRTC_ID:
@@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
 		return -ENOMEM;
 	dev->mode_config.tile_property = prop;
 
+	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
+					drm_link_status_enum_list,
+					ARRAY_SIZE(drm_link_status_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.link_status_property = prop;
+
 	return 0;
 }
 
@@ -995,6 +1019,41 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
 
+/**
+ * drm_mode_connector_set_link_status_property - Set link status property of a connector
+ * @connector: drm connector
+ * @link_status: new value of link status property (0: Good, 1: Bad)
+ *
+ * In usual working scenario, this link status property will always be set to
+ * "GOOD". If something fails during or after a mode set, the kernel driver should
+ * set this link status property to "BAD" and prune the mode list based on new
+ * information. The caller then needs to send a hotplug uevent for userspace to
+ *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
+ *
+ * Note that a lot of existing userspace do not handle this property.
+ * Drivers can therefore not rely on userspace to fix up everything and
+ * should try to handle issues (like just re-training a link) without
+ * userspace's intervention. This should only be used when the current mode
+ * fails and userspace must select a different display mode.
+ * The DRM driver can chose to not modify property and keep link status
+ * as "GOOD" always to keep the user experience same as it currently is.
+ *
+ * The reason for adding this property is to handle link training failures, but
+ * it is not limited to DP or link training. For example, if we implement
+ * asynchronous setcrtc, this property can be used to report any failures in that.
+ */
+void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
+						 uint64_t link_status)
+{
+	struct drm_device *dev = connector->dev;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	connector->state->link_status = link_status;
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+}
+EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
+
 int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    struct drm_property *property,
 				    uint64_t value)
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 34f9741..ba22ed1 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -90,6 +90,17 @@ enum subpixel_order {
 };
 
 /**
+ * enum drm_link_status - connector's link_status property value
+ *
+ * This enum is used as the connector's link status property value.
+ * It is set to the values defined in uapi.
+ */
+enum drm_link_status {
+	DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD,
+	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
+};
+
+/**
  * struct drm_display_info - runtime data about the connected sink
  *
  * Describes a given display (e.g. CRT or flat panel) and its limitations. For
@@ -213,6 +224,9 @@ struct drm_connector_state {
 
 	struct drm_encoder *best_encoder;
 
+	/* Connector Link status */
+	enum drm_link_status link_status;
+
 	struct drm_atomic_state *state;
 };
 
@@ -695,6 +709,7 @@ struct drm_connector {
 	uint8_t num_h_tile, num_v_tile;
 	uint8_t tile_h_loc, tile_v_loc;
 	uint16_t tile_h_size, tile_v_size;
+
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -767,12 +782,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
 int drm_mode_create_scaling_mode_property(struct drm_device *dev);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
-
 int drm_mode_connector_set_path_property(struct drm_connector *connector,
 					 const char *path);
 int drm_mode_connector_set_tile_property(struct drm_connector *connector);
 int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 					    const struct edid *edid);
+void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
+						 uint64_t link_status);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index bf9991b..86faee4 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -431,6 +431,11 @@ struct drm_mode_config {
 	 */
 	struct drm_property *tile_property;
 	/**
+	 * @link_status_property: Default connector property for link status
+	 * of a connector
+	 */
+	struct drm_property *link_status_property;
+	/**
 	 * @plane_type_property: Default plane property to differentiate
 	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
 	 */
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 728790b..309c478 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -123,6 +123,10 @@
 #define DRM_MODE_DIRTY_ON       1
 #define DRM_MODE_DIRTY_ANNOTATE 2
 
+/* Link Status options */
+#define DRM_MODE_LINK_STATUS_GOOD	0
+#define DRM_MODE_LINK_STATUS_BAD	1
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v3] drm: Add a new connector atomic property for link status
  2016-11-24  7:28   ` [PATCH RFC v3] " Manasi Navare
@ 2016-11-24  7:51     ` Daniel Vetter
  2016-11-28 19:32       ` Manasi Navare
  2016-11-29  1:07       ` Manasi Navare
  0 siblings, 2 replies; 27+ messages in thread
From: Daniel Vetter @ 2016-11-24  7:51 UTC (permalink / raw)
  To: Manasi Navare; +Cc: Daniel Vetter, intel-gfx, dri-devel

On Wed, Nov 23, 2016 at 11:28:21PM -0800, Manasi Navare wrote:
> This is RFC patch for adding a connector link-status property
> and making it atomic by adding it to the drm_connector_state.
> This is to make sure its wired properly in drm_atomic_connector_set_property
> and drm_atomic_connector_get_property functions.
> 
> v3:
> * Fixed a build error (Jani Saarinen)
> v2:
> * Removed connector->link_status (Daniel Vetter)
> * Set connector->state->link_status in drm_mode_connector_set_link_status_property
> (Daniel Vetter)
> * Set the connector_changed flag to true if connector->state->link_status changed.
> * Reset link_status to GOOD in update_output_state (Daniel Vetter)
> * Never allow userspace to set link status from Good To Bad (Daniel Vetter)
> 
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Sean Paul <seanpaul@chromium.org>

You lost all the acked-by from AMD about the link-status property. We need
those.

> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>

Yeah I think this should work, but obviously testing has the final say.
Some nitpicks below, then it's r-b: me. But I think we also need to polish
the kernel-doc a bit more to address Sean Paul's questions.
-Daniel

> ---
>  drivers/gpu/drm/drm_atomic.c        | 10 ++++++
>  drivers/gpu/drm/drm_atomic_helper.c |  8 +++++
>  drivers/gpu/drm/drm_connector.c     | 61 ++++++++++++++++++++++++++++++++++++-
>  include/drm/drm_connector.h         | 18 ++++++++++-
>  include/drm/drm_mode_config.h       |  5 +++
>  include/uapi/drm/drm_mode.h         |  4 +++
>  6 files changed, 104 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 89737e4..990f013 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1087,6 +1087,14 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>  		 * now?) atomic writes to DPMS property:
>  		 */
>  		return -EINVAL;
> +	} else if (property == config->link_status_property) {
> +		/* Never downgrade from GOOD to BAD on userspace's request here,
> +		 * only hw issues can do that.
> +		 */
> +		if (state->link_status == DRM_LINK_STATUS_GOOD)
> +			return 0;
> +		state->link_status = val;
> +		return 0;
>  	} else if (connector->funcs->atomic_set_property) {
>  		return connector->funcs->atomic_set_property(connector,
>  				state, property, val);
> @@ -1135,6 +1143,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>  		*val = (state->crtc) ? state->crtc->base.id : 0;
>  	} else if (property == config->dpms_property) {
>  		*val = connector->dpms;
> +	} else if (property == config->link_status_property) {
> +		*val = state->link_status;
>  	} else if (connector->funcs->atomic_get_property) {
>  		return connector->funcs->atomic_get_property(connector,
>  				state, property, val);
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 494680c..962ed66 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -519,6 +519,13 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
>  					       connector_state);
>  		if (ret)
>  			return ret;
> +		if (connector->state->crtc) {
> +			crtc_state = drm_atomic_get_existing_crtc_state(state,
> +									connector->state->crtc);
> +			if (connector->state->link_status !=
> +			    connector_state->link_status)
> +				crtc_state->connectors_changed = true;
> +		}

Why hide this here in handle_conflicting_encoders? This is a bit
confusing. I'd move it into the connector loop in
drm_atomic_helper_check_modeset().
>  	}
>  
>  	/*
> @@ -2258,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
>  								NULL);
>  			if (ret)
>  				return ret;
> +			conn_state->link_status = DRM_LINK_STATUS_GOOD;
>  		}
>  	}
>  
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 5a45262..cd53c39 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>  	drm_object_attach_property(&connector->base,
>  				      config->dpms_property, 0);
>  
> +	drm_object_attach_property(&connector->base,
> +				   config->link_status_property,
> +				   0);
> +
>  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>  		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>  	}
> @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>  };
>  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>  
> +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> +	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
> +	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
> +};
> +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> +
>  /**
>   * drm_display_info_set_bus_formats - set the supported bus formats
>   * @info: display info to store bus formats in
> @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>   * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>   * 	should update this value using drm_mode_connector_set_tile_property().
>   * 	Userspace cannot change this property.
> - *
> + * link-status:
> + *      Connector link-status property to indicate the status of link during
> + *      the modeset. The default value of link-status is "GOOD". If something
> + *      fails during modeset, the kernel driver can set this to "BAD", prune
> + *      the mode list based on new link parameters and send a hotplug uevent
> + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> + *      IOCTL and redo a modeset. Drivers should update this value using
> + *      drm_mode_connector_set_link_status_property().

Please leave the empty line here after the definition list, for better
layout. Also I thought there were some comments from Sean Paul that the
kernel-doc was confusing, have you worked together with him to address
this?

>   * Connectors also have one standardized atomic property:
>   *
>   * CRTC_ID:
> @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>  		return -ENOMEM;
>  	dev->mode_config.tile_property = prop;
>  
> +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> +					drm_link_status_enum_list,
> +					ARRAY_SIZE(drm_link_status_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +	dev->mode_config.link_status_property = prop;
> +
>  	return 0;
>  }
>  
> @@ -995,6 +1019,41 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>  
> +/**
> + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> + * @connector: drm connector
> + * @link_status: new value of link status property (0: Good, 1: Bad)
> + *
> + * In usual working scenario, this link status property will always be set to
> + * "GOOD". If something fails during or after a mode set, the kernel driver should
> + * set this link status property to "BAD" and prune the mode list based on new
> + * information. The caller then needs to send a hotplug uevent for userspace to
> + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> + *
> + * Note that a lot of existing userspace do not handle this property.
> + * Drivers can therefore not rely on userspace to fix up everything and
> + * should try to handle issues (like just re-training a link) without
> + * userspace's intervention. This should only be used when the current mode
> + * fails and userspace must select a different display mode.
> + * The DRM driver can chose to not modify property and keep link status
> + * as "GOOD" always to keep the user experience same as it currently is.
> + *
> + * The reason for adding this property is to handle link training failures, but
> + * it is not limited to DP or link training. For example, if we implement
> + * asynchronous setcrtc, this property can be used to report any failures in that.
> + */
> +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> +						 uint64_t link_status)
> +{
> +	struct drm_device *dev = connector->dev;
> +
> +	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> +	connector->state->link_status = link_status;
> +	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +
> +}
> +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> +
>  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>  				    struct drm_property *property,
>  				    uint64_t value)
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 34f9741..ba22ed1 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -90,6 +90,17 @@ enum subpixel_order {
>  };
>  
>  /**
> + * enum drm_link_status - connector's link_status property value
> + *
> + * This enum is used as the connector's link status property value.
> + * It is set to the values defined in uapi.
> + */
> +enum drm_link_status {
> +	DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD,
> +	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
> +};
> +
> +/**
>   * struct drm_display_info - runtime data about the connected sink
>   *
>   * Describes a given display (e.g. CRT or flat panel) and its limitations. For
> @@ -213,6 +224,9 @@ struct drm_connector_state {
>  
>  	struct drm_encoder *best_encoder;
>  
> +	/* Connector Link status */
> +	enum drm_link_status link_status;

make htmldocs should complain about the missing kernel-doc here. Just
convert your inline comment into a proper kernel-doc:

	/**
	 * @link_status: Connector link status
	 */

Also in general a comment that literally says the same as the code isn't
useful. Comments should explain why the code does something, not what
exactly it does - that should be self-evident.
> +
>  	struct drm_atomic_state *state;
>  };
>  
> @@ -695,6 +709,7 @@ struct drm_connector {
>  	uint8_t num_h_tile, num_v_tile;
>  	uint8_t tile_h_loc, tile_v_loc;
>  	uint16_t tile_h_size, tile_v_size;
> +

Spurious whitespace change, pls check for these before submitting. I think
this one here is new.

>  };
>  
>  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> @@ -767,12 +782,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> -

Same.

>  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>  					 const char *path);
>  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>  					    const struct edid *edid);
> +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> +						 uint64_t link_status);
>  
>  /**
>   * struct drm_tile_group - Tile group metadata
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index bf9991b..86faee4 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -431,6 +431,11 @@ struct drm_mode_config {
>  	 */
>  	struct drm_property *tile_property;
>  	/**
> +	 * @link_status_property: Default connector property for link status
> +	 * of a connector
> +	 */
> +	struct drm_property *link_status_property;
> +	/**
>  	 * @plane_type_property: Default plane property to differentiate
>  	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>  	 */
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 728790b..309c478 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -123,6 +123,10 @@
>  #define DRM_MODE_DIRTY_ON       1
>  #define DRM_MODE_DIRTY_ANNOTATE 2
>  
> +/* Link Status options */
> +#define DRM_MODE_LINK_STATUS_GOOD	0
> +#define DRM_MODE_LINK_STATUS_BAD	1
> +
>  struct drm_mode_modeinfo {
>  	__u32 clock;
>  	__u16 hdisplay;
> -- 
> 1.9.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* ✓ Fi.CI.BAT: success for drm: Add a new connector atomic property for link status (rev4)
  2016-11-23  1:30 [PATCH RFC] drm: Add a new connector atomic property for link status Manasi Navare
                   ` (4 preceding siblings ...)
  2016-11-24  4:01 ` ✗ Fi.CI.BAT: failure for drm: Add a new connector atomic property for link status (rev3) Patchwork
@ 2016-11-24  8:45 ` Patchwork
  5 siblings, 0 replies; 27+ messages in thread
From: Patchwork @ 2016-11-24  8:45 UTC (permalink / raw)
  To: Navare, Manasi D; +Cc: intel-gfx

== Series Details ==

Series: drm: Add a new connector atomic property for link status (rev4)
URL   : https://patchwork.freedesktop.org/series/15781/
State : success

== Summary ==

Series 15781v4 drm: Add a new connector atomic property for link status
https://patchwork.freedesktop.org/api/1.0/series/15781/revisions/4/mbox/


fi-bdw-5557u     total:244  pass:229  dwarn:0   dfail:0   fail:0   skip:15 
fi-bsw-n3050     total:244  pass:204  dwarn:0   dfail:0   fail:0   skip:40 
fi-bxt-t5700     total:244  pass:216  dwarn:0   dfail:0   fail:0   skip:28 
fi-byt-j1900     total:244  pass:216  dwarn:0   dfail:0   fail:0   skip:28 
fi-byt-n2820     total:244  pass:212  dwarn:0   dfail:0   fail:0   skip:32 
fi-hsw-4770      total:244  pass:224  dwarn:0   dfail:0   fail:0   skip:20 
fi-hsw-4770r     total:244  pass:224  dwarn:0   dfail:0   fail:0   skip:20 
fi-ilk-650       total:244  pass:191  dwarn:0   dfail:0   fail:0   skip:53 
fi-ivb-3520m     total:244  pass:222  dwarn:0   dfail:0   fail:0   skip:22 
fi-ivb-3770      total:244  pass:222  dwarn:0   dfail:0   fail:0   skip:22 
fi-kbl-7200u     total:244  pass:222  dwarn:0   dfail:0   fail:0   skip:22 
fi-skl-6260u     total:244  pass:230  dwarn:0   dfail:0   fail:0   skip:14 
fi-skl-6700hq    total:244  pass:223  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6700k     total:244  pass:222  dwarn:1   dfail:0   fail:0   skip:21 
fi-skl-6770hq    total:244  pass:230  dwarn:0   dfail:0   fail:0   skip:14 
fi-snb-2520m     total:244  pass:212  dwarn:0   dfail:0   fail:0   skip:32 
fi-snb-2600      total:244  pass:211  dwarn:0   dfail:0   fail:0   skip:33 

2154a854b8c9f732ef446a5c99cb24b8d97347f7 drm-intel-nightly: 2016y-11m-24d-07h-21m-33s UTC integration manifest
c393d2c drm: Add a new connector atomic property for link status

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3102/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v3] drm: Add a new connector atomic property for link status
  2016-11-24  7:51     ` Daniel Vetter
@ 2016-11-28 19:32       ` Manasi Navare
  2016-11-29  1:07       ` Manasi Navare
  1 sibling, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-11-28 19:32 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, intel-gfx, dri-devel

On Thu, Nov 24, 2016 at 08:51:35AM +0100, Daniel Vetter wrote:
> On Wed, Nov 23, 2016 at 11:28:21PM -0800, Manasi Navare wrote:
> > This is RFC patch for adding a connector link-status property
> > and making it atomic by adding it to the drm_connector_state.
> > This is to make sure its wired properly in drm_atomic_connector_set_property
> > and drm_atomic_connector_get_property functions.
> > 
> > v3:
> > * Fixed a build error (Jani Saarinen)
> > v2:
> > * Removed connector->link_status (Daniel Vetter)
> > * Set connector->state->link_status in drm_mode_connector_set_link_status_property
> > (Daniel Vetter)
> > * Set the connector_changed flag to true if connector->state->link_status changed.
> > * Reset link_status to GOOD in update_output_state (Daniel Vetter)
> > * Never allow userspace to set link status from Good To Bad (Daniel Vetter)
> > 
> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Sean Paul <seanpaul@chromium.org>
> 
> You lost all the acked-by from AMD about the link-status property. We need
> those.
>

I removed the ACKS sinec this was just a RFC patch, I will add them back
when I submit the actual patch in the patch series.

 
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> 
> Yeah I think this should work, but obviously testing has the final say.
> Some nitpicks below, then it's r-b: me. But I think we also need to polish
> the kernel-doc a bit more to address Sean Paul's questions.
> -Daniel
>

Yes, I still need to change the kernel doc as per Sean's comments but wanted
ACK on this new atomic design for the property so that I could update
the kernel doc.

 
> > ---
> >  drivers/gpu/drm/drm_atomic.c        | 10 ++++++
> >  drivers/gpu/drm/drm_atomic_helper.c |  8 +++++
> >  drivers/gpu/drm/drm_connector.c     | 61 ++++++++++++++++++++++++++++++++++++-
> >  include/drm/drm_connector.h         | 18 ++++++++++-
> >  include/drm/drm_mode_config.h       |  5 +++
> >  include/uapi/drm/drm_mode.h         |  4 +++
> >  6 files changed, 104 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 89737e4..990f013 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -1087,6 +1087,14 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> >  		 * now?) atomic writes to DPMS property:
> >  		 */
> >  		return -EINVAL;
> > +	} else if (property == config->link_status_property) {
> > +		/* Never downgrade from GOOD to BAD on userspace's request here,
> > +		 * only hw issues can do that.
> > +		 */
> > +		if (state->link_status == DRM_LINK_STATUS_GOOD)
> > +			return 0;
> > +		state->link_status = val;
> > +		return 0;
> >  	} else if (connector->funcs->atomic_set_property) {
> >  		return connector->funcs->atomic_set_property(connector,
> >  				state, property, val);
> > @@ -1135,6 +1143,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
> >  		*val = (state->crtc) ? state->crtc->base.id : 0;
> >  	} else if (property == config->dpms_property) {
> >  		*val = connector->dpms;
> > +	} else if (property == config->link_status_property) {
> > +		*val = state->link_status;
> >  	} else if (connector->funcs->atomic_get_property) {
> >  		return connector->funcs->atomic_get_property(connector,
> >  				state, property, val);
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > index 494680c..962ed66 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -519,6 +519,13 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
> >  					       connector_state);
> >  		if (ret)
> >  			return ret;
> > +		if (connector->state->crtc) {
> > +			crtc_state = drm_atomic_get_existing_crtc_state(state,
> > +									connector->state->crtc);
> > +			if (connector->state->link_status !=
> > +			    connector_state->link_status)
> > +				crtc_state->connectors_changed = true;
> > +		}
> 
> Why hide this here in handle_conflicting_encoders? This is a bit
> confusing. I'd move it into the connector loop in
> drm_atomic_helper_check_modeset().
> >  	}
> >  

If you pull this patch, you will see that this is added in  the connector
loop inside drm_atomic_helper_check_modeset(), donno why the diff shows as if
its inside handle_conflicting_encoders.

Manasi

> >  	/*
> > @@ -2258,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
> >  								NULL);
> >  			if (ret)
> >  				return ret;
> > +			conn_state->link_status = DRM_LINK_STATUS_GOOD;
> >  		}
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 5a45262..cd53c39 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
> >  	drm_object_attach_property(&connector->base,
> >  				      config->dpms_property, 0);
> >  
> > +	drm_object_attach_property(&connector->base,
> > +				   config->link_status_property,
> > +				   0);
> > +
> >  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> >  		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
> >  	}
> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
> >  };
> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
> >  
> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> > +	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
> > +	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
> > +};
> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> > +
> >  /**
> >   * drm_display_info_set_bus_formats - set the supported bus formats
> >   * @info: display info to store bus formats in
> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >   * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
> >   * 	should update this value using drm_mode_connector_set_tile_property().
> >   * 	Userspace cannot change this property.
> > - *
> > + * link-status:
> > + *      Connector link-status property to indicate the status of link during
> > + *      the modeset. The default value of link-status is "GOOD". If something
> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
> > + *      the mode list based on new link parameters and send a hotplug uevent
> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> > + *      IOCTL and redo a modeset. Drivers should update this value using
> > + *      drm_mode_connector_set_link_status_property().
> 
> Please leave the empty line here after the definition list, for better
> layout. Also I thought there were some comments from Sean Paul that the
> kernel-doc was confusing, have you worked together with him to address
> this?
>

Now that link-status is an atomic property, shouldnt it be added after CRTC_ID in the
standardized atomic prop section?

 
> >   * Connectors also have one standardized atomic property:
> >   *
> >   * CRTC_ID:
> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> >  		return -ENOMEM;
> >  	dev->mode_config.tile_property = prop;
> >  
> > +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> > +					drm_link_status_enum_list,
> > +					ARRAY_SIZE(drm_link_status_enum_list));
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	dev->mode_config.link_status_property = prop;
> > +
> >  	return 0;
> >  }
> >  
> > @@ -995,6 +1019,41 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >  }
> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
> >  
> > +/**
> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> > + * @connector: drm connector
> > + * @link_status: new value of link status property (0: Good, 1: Bad)
> > + *
> > + * In usual working scenario, this link status property will always be set to
> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
> > + * set this link status property to "BAD" and prune the mode list based on new
> > + * information. The caller then needs to send a hotplug uevent for userspace to
> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> > + *
> > + * Note that a lot of existing userspace do not handle this property.
> > + * Drivers can therefore not rely on userspace to fix up everything and
> > + * should try to handle issues (like just re-training a link) without
> > + * userspace's intervention. This should only be used when the current mode
> > + * fails and userspace must select a different display mode.
> > + * The DRM driver can chose to not modify property and keep link status
> > + * as "GOOD" always to keep the user experience same as it currently is.
> > + *
> > + * The reason for adding this property is to handle link training failures, but
> > + * it is not limited to DP or link training. For example, if we implement
> > + * asynchronous setcrtc, this property can be used to report any failures in that.
> > + */
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +						 uint64_t link_status)
> > +{
> > +	struct drm_device *dev = connector->dev;
> > +
> > +	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> > +	connector->state->link_status = link_status;
> > +	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> > +
> > +}
> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> > +
> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> >  				    struct drm_property *property,
> >  				    uint64_t value)
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index 34f9741..ba22ed1 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -90,6 +90,17 @@ enum subpixel_order {
> >  };
> >  
> >  /**
> > + * enum drm_link_status - connector's link_status property value
> > + *
> > + * This enum is used as the connector's link status property value.
> > + * It is set to the values defined in uapi.
> > + */
> > +enum drm_link_status {
> > +	DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD,
> > +	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
> > +};
> > +
> > +/**
> >   * struct drm_display_info - runtime data about the connected sink
> >   *
> >   * Describes a given display (e.g. CRT or flat panel) and its limitations. For
> > @@ -213,6 +224,9 @@ struct drm_connector_state {
> >  
> >  	struct drm_encoder *best_encoder;
> >  
> > +	/* Connector Link status */
> > +	enum drm_link_status link_status;
> 
> make htmldocs should complain about the missing kernel-doc here. Just
> convert your inline comment into a proper kernel-doc:
> 
> 	/**
> 	 * @link_status: Connector link status
> 	 */
> 
> Also in general a comment that literally says the same as the code isn't
> useful. Comments should explain why the code does something, not what
> exactly it does - that should be self-evident.
> > +
> >  	struct drm_atomic_state *state;
> >  };
> >  
> > @@ -695,6 +709,7 @@ struct drm_connector {
> >  	uint8_t num_h_tile, num_v_tile;
> >  	uint8_t tile_h_loc, tile_v_loc;
> >  	uint16_t tile_h_size, tile_v_size;
> > +
> 
> Spurious whitespace change, pls check for these before submitting. I think
> this one here is new.
> 
> >  };

Yes removed that.

> >  
> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> > @@ -767,12 +782,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> > -
> 
> Same.
> 
> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
> >  					 const char *path);
> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >  					    const struct edid *edid);
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +						 uint64_t link_status);
> >  
> >  /**
> >   * struct drm_tile_group - Tile group metadata
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index bf9991b..86faee4 100644
> > --- a/include/drm/drm_mode_config.h
> > +++ b/include/drm/drm_mode_config.h
> > @@ -431,6 +431,11 @@ struct drm_mode_config {
> >  	 */
> >  	struct drm_property *tile_property;
> >  	/**
> > +	 * @link_status_property: Default connector property for link status
> > +	 * of a connector
> > +	 */
> > +	struct drm_property *link_status_property;
> > +	/**
> >  	 * @plane_type_property: Default plane property to differentiate
> >  	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
> >  	 */
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 728790b..309c478 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -123,6 +123,10 @@
> >  #define DRM_MODE_DIRTY_ON       1
> >  #define DRM_MODE_DIRTY_ANNOTATE 2
> >  
> > +/* Link Status options */
> > +#define DRM_MODE_LINK_STATUS_GOOD	0
> > +#define DRM_MODE_LINK_STATUS_BAD	1
> > +
> >  struct drm_mode_modeinfo {
> >  	__u32 clock;
> >  	__u16 hdisplay;
> > -- 
> > 1.9.1
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-23  8:09   ` Daniel Vetter
  2016-11-23 14:40     ` Sean Paul
@ 2016-11-29  0:59     ` Manasi Navare
  2016-11-29 14:45       ` Sean Paul
  1 sibling, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-11-29  0:59 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Wed, Nov 23, 2016 at 09:09:28AM +0100, Daniel Vetter wrote:
> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
> > On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
> > <manasi.d.navare@intel.com> wrote:
> > > This is RFC patch for adding a connector link-status property
> > > and making it atomic by adding it to the drm_connector_state.
> > > This is to make sure its wired properly in drm_atomic_connector_set_property
> > > and drm_atomic_connector_get_property functions.
> > >
> > 
> > Thanks for sending this. We ran into some re-training awkwardness
> > recently, and I
> > was hoping for such a patch.
> > 
> > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > ---
> > >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
> > >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
> > >  include/drm/drm_connector.h     | 12 +++++++-
> > >  include/drm/drm_mode_config.h   |  5 ++++
> > >  include/uapi/drm/drm_mode.h     |  4 +++
> > >  5 files changed, 88 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > index 89737e4..644d19f 100644
> > > --- a/drivers/gpu/drm/drm_atomic.c
> > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> > >                  * now?) atomic writes to DPMS property:
> > >                  */
> > >                 return -EINVAL;
> > > +       } else if (property == config->link_status_property) {
> > > +               state->link_status = val;
> 
> I think we should have a check here to make sure userspace never tries to
> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
> atomic userspace is supposed to be able to just restore everything to what
> it was.
> 
> I don't think trying to set it to "BAD" should cause an error though, just
> silently keep the link status at "GOOG". So:
> 
> 	/* Never downgrade from GOOD to BAD on userspace's request here,
> 	 * only hw issues can do that. */
> 	if (state->link_status == GOOD)
> 		return 0;
> 	state->link_status = val;
> 	return 0;
> 
> > > +               return 0;
> > >         } else if (connector->funcs->atomic_set_property) {
> > >                 return connector->funcs->atomic_set_property(connector,
> > >                                 state, property, val);
> > > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
> > >                 *val = (state->crtc) ? state->crtc->base.id : 0;
> > >         } else if (property == config->dpms_property) {
> > >                 *val = connector->dpms;
> > > +       } else if (property == config->link_status_property) {
> > > +               *val = state->link_status;
> > >         } else if (connector->funcs->atomic_get_property) {
> > >                 return connector->funcs->atomic_get_property(connector,
> > >                                 state, property, val);
> > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > > index 5a45262..4576c9f 100644
> > > --- a/drivers/gpu/drm/drm_connector.c
> > > +++ b/drivers/gpu/drm/drm_connector.c
> > > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
> > >         drm_object_attach_property(&connector->base,
> > >                                       config->dpms_property, 0);
> > >
> > > +       drm_object_attach_property(&connector->base,
> > > +                                  config->link_status_property,
> > > +                                  0);
> > > +
> > >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> > >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
> > >         }
> > > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
> > >  };
> > >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
> > >
> > > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> > > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
> > > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
> > > +};
> > > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> > > +
> > >  /**
> > >   * drm_display_info_set_bus_formats - set the supported bus formats
> > >   * @info: display info to store bus formats in
> > > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> > >   *     path property the MST manager created. Userspace cannot change this
> > >   *     property.
> > >   * TILE:
> > > - *     Connector tile group property to indicate how a set of DRM connector
> > > + *      Connector tile group property to indicate how a set of DRM connector
> > 
> > keyboard slip here
> > 
> > >   *     compose together into one logical screen. This is used by both high-res
> > >   *     external screens (often only using a single cable, but exposing multiple
> > >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
> > > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> > >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
> > >   *     should update this value using drm_mode_connector_set_tile_property().
> > >   *     Userspace cannot change this property.
> > > - *
> > > + * link-status:
> > > + *      Connector link-status property to indicate the status of link during
> > > + *      the modeset. The default value of link-status is "GOOD". If something
> > > + *      fails during modeset, the kernel driver can set this to "BAD", prune
> > > + *      the mode list based on new link parameters and send a hotplug uevent
> > > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> > > + *      IOCTL and redo a modeset. Drivers should update this value using
> > > + *      drm_mode_connector_set_link_status_property().
> > >   * Connectors also have one standardized atomic property:
> > >   *
> > >   * CRTC_ID:
> > > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> > >                 return -ENOMEM;
> > >         dev->mode_config.tile_property = prop;
> > >
> > > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> > > +                                       drm_link_status_enum_list,
> > > +                                       ARRAY_SIZE(drm_link_status_enum_list));
> > > +       if (!prop)
> > > +               return -ENOMEM;
> > > +       dev->mode_config.link_status_property = prop;
> > > +
> > >         return 0;
> > >  }
> > >
> > > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> > >  }
> > >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
> > >
> > > +/**
> > > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> > > + * @connector: drm connector
> > > + * @link_status: new value of link status property (0: Good, 1: Bad)
> > > + *
> > > + * In usual working scenario, this link status property will always be set to
> > > + * "GOOD". If something fails during or after a mode set, the kernel driver should
> > > + * set this link status property to "BAD" and prune the mode list based on new
> > 
> > Does the mode list really *need* to be pruned? In the case of needing
> > to re-train a DP link,
> > it seems like we should be able to set this BAD and keep the modelist
> > as-is (since the sink
> > hasn't changed)
> 
> Well, if you prune it with the same constraints as before, no additional
> modes will be removed and the same list is there. Pruning here refers to
> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
> 
> We might want to be a bit more explicit here perhaps? Have some good
> proposal text to insert?
> >

Sean, do you have any recommendations on the text that can go in the kernel doc for
this property to clarify that it depends on the kernel implementation whether we want
to use this link-status property to do the retraining or not. Leaving it BAD and not doing
anything will be fine too.

Manasi 
> > > + * information. The caller then needs to send a hotplug uevent for userspace to
> > > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> > 
> > extra space
> > 
> > > + *
> > > + * Note that a lot of existing userspace do not handle this property.
> > > + * Drivers can therefore not rely on userspace to fix up everything and
> > > + * should try to handle issues (like just re-training a link) without
> > > + * userspace's intervention. This should only be used when the current mode
> > > + * fails and userspace must select a different display mode.
> > 
> > Hmm, I suppose this answers my last question. It's too bad we can't
> > rely on this, since we'll
> > just end up with each driver rolling their own re-training logic on
> > top of possibly supporting
> > this (but probably not, since it's really just overhead). Perhaps this
> > is an overly pessimistic
> > view?
> 
> You can forgo any re-training of course, that should work too. It's just
> that DP spec and everyone else seem to recommend to at least do some
> minimal effort (or maybe even upfront link training) here. But totally not
> doing anything if the link is bad should be ok too (and probably really
> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
> function which checks link status and set link-status to bad&fires off the
> uevent if needed.
> 
> Again, do you have some sample prose to add here to clarify this?
> 
> Thanks for taking a look at this.
> 
> Cheers, Daniel
> 
> > > + * The DRM driver can chose to not modify property and keep link status
> > > + * as "GOOD" always to keep the user experience same as it currently is.
> > > + *
> > > + * The reason for adding this property is to handle link training failures, but
> > > + * it is not limited to DP or link training. For example, if we implement
> > > + * asynchronous setcrtc, this property can be used to report any failures in that.
> > > + */
> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > > +                                                uint64_t link_status)
> > > +{
> > > +       struct drm_device *dev = connector->dev;
> > > +
> > > +       /* Make sure the mutex is grabbed */
> > > +       lockdep_assert_held(&dev->mode_config.mutex);
> > > +       connector->link_status = link_status;
> > > +       drm_object_property_set_value(&connector->base,
> > > +                                     dev->mode_config.link_status_property,
> > > +                                     link_status);
> > > +}
> > > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> > > +
> > >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> > >                                     struct drm_property *property,
> > >                                     uint64_t value)
> > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > > index 34f9741..3d513ab 100644
> > > --- a/include/drm/drm_connector.h
> > > +++ b/include/drm/drm_connector.h
> > > @@ -213,6 +213,9 @@ struct drm_connector_state {
> > >
> > >         struct drm_encoder *best_encoder;
> > >
> > > +       /* Connector Link status */
> > > +       unsigned int link_status;
> > > +
> > >         struct drm_atomic_state *state;
> > >  };
> > >
> > > @@ -695,6 +698,12 @@ struct drm_connector {
> > >         uint8_t num_h_tile, num_v_tile;
> > >         uint8_t tile_h_loc, tile_v_loc;
> > >         uint16_t tile_h_size, tile_v_size;
> > > +
> > > +       /* Connector Link status
> > > +        * 0: If the link is Good
> > > +        * 1: If the link is Bad
> > > +        */
> > > +       int link_status;
> > >  };
> > >
> > >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> > > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> > >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> > >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
> > >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> > > -
> > 
> > lost a line here
> > 
> > >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
> > >                                          const char *path);
> > >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
> > >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> > >                                             const struct edid *edid);
> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > > +                                                uint64_t link_status);
> > >
> > >  /**
> > >   * struct drm_tile_group - Tile group metadata
> > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > > index bf9991b..86faee4 100644
> > > --- a/include/drm/drm_mode_config.h
> > > +++ b/include/drm/drm_mode_config.h
> > > @@ -431,6 +431,11 @@ struct drm_mode_config {
> > >          */
> > >         struct drm_property *tile_property;
> > >         /**
> > > +        * @link_status_property: Default connector property for link status
> > > +        * of a connector
> > > +        */
> > > +       struct drm_property *link_status_property;
> > > +       /**
> > >          * @plane_type_property: Default plane property to differentiate
> > >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
> > >          */
> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > index 728790b..309c478 100644
> > > --- a/include/uapi/drm/drm_mode.h
> > > +++ b/include/uapi/drm/drm_mode.h
> > > @@ -123,6 +123,10 @@
> > >  #define DRM_MODE_DIRTY_ON       1
> > >  #define DRM_MODE_DIRTY_ANNOTATE 2
> > >
> > > +/* Link Status options */
> > > +#define DRM_MODE_LINK_STATUS_GOOD      0
> > > +#define DRM_MODE_LINK_STATUS_BAD       1
> > > +
> > >  struct drm_mode_modeinfo {
> > >         __u32 clock;
> > >         __u16 hdisplay;
> > > --
> > > 1.9.1
> > >
> > > _______________________________________________
> > > dri-devel mailing list
> > > dri-devel@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v3] drm: Add a new connector atomic property for link status
  2016-11-24  7:51     ` Daniel Vetter
  2016-11-28 19:32       ` Manasi Navare
@ 2016-11-29  1:07       ` Manasi Navare
  2016-11-29  8:59         ` Daniel Vetter
  1 sibling, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-11-29  1:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, intel-gfx, dri-devel

On Thu, Nov 24, 2016 at 08:51:35AM +0100, Daniel Vetter wrote:
> On Wed, Nov 23, 2016 at 11:28:21PM -0800, Manasi Navare wrote:
> > This is RFC patch for adding a connector link-status property
> > and making it atomic by adding it to the drm_connector_state.
> > This is to make sure its wired properly in drm_atomic_connector_set_property
> > and drm_atomic_connector_get_property functions.
> > 
> > v3:
> > * Fixed a build error (Jani Saarinen)
> > v2:
> > * Removed connector->link_status (Daniel Vetter)
> > * Set connector->state->link_status in drm_mode_connector_set_link_status_property
> > (Daniel Vetter)
> > * Set the connector_changed flag to true if connector->state->link_status changed.
> > * Reset link_status to GOOD in update_output_state (Daniel Vetter)
> > * Never allow userspace to set link status from Good To Bad (Daniel Vetter)
> > 
> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Sean Paul <seanpaul@chromium.org>
> 
> You lost all the acked-by from AMD about the link-status property. We need
> those.
> 
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> 
> Yeah I think this should work, but obviously testing has the final say.
> Some nitpicks below, then it's r-b: me. But I think we also need to polish
> the kernel-doc a bit more to address Sean Paul's questions.
> -Daniel
>

I tested it with SNA driver with Chris's changes to read the link-status
property, but It is not able to detect the link-status property being set to BAD
and hence it does not trigger a new modeset.
Do we need to make any changes to the SNA driver now that this is made a ATOMIC
property so that GETCONNECTOR IOCTL can still read the correct value
of this property throught drm_atomic_get_property() interface?

Chris, Daniel, any thoughts? 

Manasi
> > ---
> >  drivers/gpu/drm/drm_atomic.c        | 10 ++++++
> >  drivers/gpu/drm/drm_atomic_helper.c |  8 +++++
> >  drivers/gpu/drm/drm_connector.c     | 61 ++++++++++++++++++++++++++++++++++++-
> >  include/drm/drm_connector.h         | 18 ++++++++++-
> >  include/drm/drm_mode_config.h       |  5 +++
> >  include/uapi/drm/drm_mode.h         |  4 +++
> >  6 files changed, 104 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 89737e4..990f013 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -1087,6 +1087,14 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> >  		 * now?) atomic writes to DPMS property:
> >  		 */
> >  		return -EINVAL;
> > +	} else if (property == config->link_status_property) {
> > +		/* Never downgrade from GOOD to BAD on userspace's request here,
> > +		 * only hw issues can do that.
> > +		 */
> > +		if (state->link_status == DRM_LINK_STATUS_GOOD)
> > +			return 0;
> > +		state->link_status = val;
> > +		return 0;
> >  	} else if (connector->funcs->atomic_set_property) {
> >  		return connector->funcs->atomic_set_property(connector,
> >  				state, property, val);
> > @@ -1135,6 +1143,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
> >  		*val = (state->crtc) ? state->crtc->base.id : 0;
> >  	} else if (property == config->dpms_property) {
> >  		*val = connector->dpms;
> > +	} else if (property == config->link_status_property) {
> > +		*val = state->link_status;
> >  	} else if (connector->funcs->atomic_get_property) {
> >  		return connector->funcs->atomic_get_property(connector,
> >  				state, property, val);
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > index 494680c..962ed66 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -519,6 +519,13 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
> >  					       connector_state);
> >  		if (ret)
> >  			return ret;
> > +		if (connector->state->crtc) {
> > +			crtc_state = drm_atomic_get_existing_crtc_state(state,
> > +									connector->state->crtc);
> > +			if (connector->state->link_status !=
> > +			    connector_state->link_status)
> > +				crtc_state->connectors_changed = true;
> > +		}
> 
> Why hide this here in handle_conflicting_encoders? This is a bit
> confusing. I'd move it into the connector loop in
> drm_atomic_helper_check_modeset().
> >  	}
> >  
> >  	/*
> > @@ -2258,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
> >  								NULL);
> >  			if (ret)
> >  				return ret;
> > +			conn_state->link_status = DRM_LINK_STATUS_GOOD;
> >  		}
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 5a45262..cd53c39 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
> >  	drm_object_attach_property(&connector->base,
> >  				      config->dpms_property, 0);
> >  
> > +	drm_object_attach_property(&connector->base,
> > +				   config->link_status_property,
> > +				   0);
> > +
> >  	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> >  		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
> >  	}
> > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
> >  };
> >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
> >  
> > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> > +	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },
> > +	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },
> > +};
> > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> > +
> >  /**
> >   * drm_display_info_set_bus_formats - set the supported bus formats
> >   * @info: display info to store bus formats in
> > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >   * 	tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
> >   * 	should update this value using drm_mode_connector_set_tile_property().
> >   * 	Userspace cannot change this property.
> > - *
> > + * link-status:
> > + *      Connector link-status property to indicate the status of link during
> > + *      the modeset. The default value of link-status is "GOOD". If something
> > + *      fails during modeset, the kernel driver can set this to "BAD", prune
> > + *      the mode list based on new link parameters and send a hotplug uevent
> > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> > + *      IOCTL and redo a modeset. Drivers should update this value using
> > + *      drm_mode_connector_set_link_status_property().
> 
> Please leave the empty line here after the definition list, for better
> layout. Also I thought there were some comments from Sean Paul that the
> kernel-doc was confusing, have you worked together with him to address
> this?
> 
> >   * Connectors also have one standardized atomic property:
> >   *
> >   * CRTC_ID:
> > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> >  		return -ENOMEM;
> >  	dev->mode_config.tile_property = prop;
> >  
> > +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> > +					drm_link_status_enum_list,
> > +					ARRAY_SIZE(drm_link_status_enum_list));
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	dev->mode_config.link_status_property = prop;
> > +
> >  	return 0;
> >  }
> >  
> > @@ -995,6 +1019,41 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >  }
> >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
> >  
> > +/**
> > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> > + * @connector: drm connector
> > + * @link_status: new value of link status property (0: Good, 1: Bad)
> > + *
> > + * In usual working scenario, this link status property will always be set to
> > + * "GOOD". If something fails during or after a mode set, the kernel driver should
> > + * set this link status property to "BAD" and prune the mode list based on new
> > + * information. The caller then needs to send a hotplug uevent for userspace to
> > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> > + *
> > + * Note that a lot of existing userspace do not handle this property.
> > + * Drivers can therefore not rely on userspace to fix up everything and
> > + * should try to handle issues (like just re-training a link) without
> > + * userspace's intervention. This should only be used when the current mode
> > + * fails and userspace must select a different display mode.
> > + * The DRM driver can chose to not modify property and keep link status
> > + * as "GOOD" always to keep the user experience same as it currently is.
> > + *
> > + * The reason for adding this property is to handle link training failures, but
> > + * it is not limited to DP or link training. For example, if we implement
> > + * asynchronous setcrtc, this property can be used to report any failures in that.
> > + */
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +						 uint64_t link_status)
> > +{
> > +	struct drm_device *dev = connector->dev;
> > +
> > +	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> > +	connector->state->link_status = link_status;
> > +	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> > +
> > +}
> > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> > +
> >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> >  				    struct drm_property *property,
> >  				    uint64_t value)
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index 34f9741..ba22ed1 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -90,6 +90,17 @@ enum subpixel_order {
> >  };
> >  
> >  /**
> > + * enum drm_link_status - connector's link_status property value
> > + *
> > + * This enum is used as the connector's link status property value.
> > + * It is set to the values defined in uapi.
> > + */
> > +enum drm_link_status {
> > +	DRM_LINK_STATUS_GOOD = DRM_MODE_LINK_STATUS_GOOD,
> > +	DRM_LINK_STATUS_BAD = DRM_MODE_LINK_STATUS_BAD,
> > +};
> > +
> > +/**
> >   * struct drm_display_info - runtime data about the connected sink
> >   *
> >   * Describes a given display (e.g. CRT or flat panel) and its limitations. For
> > @@ -213,6 +224,9 @@ struct drm_connector_state {
> >  
> >  	struct drm_encoder *best_encoder;
> >  
> > +	/* Connector Link status */
> > +	enum drm_link_status link_status;
> 
> make htmldocs should complain about the missing kernel-doc here. Just
> convert your inline comment into a proper kernel-doc:
> 
> 	/**
> 	 * @link_status: Connector link status
> 	 */
> 
> Also in general a comment that literally says the same as the code isn't
> useful. Comments should explain why the code does something, not what
> exactly it does - that should be self-evident.
> > +
> >  	struct drm_atomic_state *state;
> >  };
> >  
> > @@ -695,6 +709,7 @@ struct drm_connector {
> >  	uint8_t num_h_tile, num_v_tile;
> >  	uint8_t tile_h_loc, tile_v_loc;
> >  	uint16_t tile_h_size, tile_v_size;
> > +
> 
> Spurious whitespace change, pls check for these before submitting. I think
> this one here is new.
> 
> >  };
> >  
> >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> > @@ -767,12 +782,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
> >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> > -
> 
> Same.
> 
> >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
> >  					 const char *path);
> >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
> >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >  					    const struct edid *edid);
> > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> > +						 uint64_t link_status);
> >  
> >  /**
> >   * struct drm_tile_group - Tile group metadata
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index bf9991b..86faee4 100644
> > --- a/include/drm/drm_mode_config.h
> > +++ b/include/drm/drm_mode_config.h
> > @@ -431,6 +431,11 @@ struct drm_mode_config {
> >  	 */
> >  	struct drm_property *tile_property;
> >  	/**
> > +	 * @link_status_property: Default connector property for link status
> > +	 * of a connector
> > +	 */
> > +	struct drm_property *link_status_property;
> > +	/**
> >  	 * @plane_type_property: Default plane property to differentiate
> >  	 * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
> >  	 */
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 728790b..309c478 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -123,6 +123,10 @@
> >  #define DRM_MODE_DIRTY_ON       1
> >  #define DRM_MODE_DIRTY_ANNOTATE 2
> >  
> > +/* Link Status options */
> > +#define DRM_MODE_LINK_STATUS_GOOD	0
> > +#define DRM_MODE_LINK_STATUS_BAD	1
> > +
> >  struct drm_mode_modeinfo {
> >  	__u32 clock;
> >  	__u16 hdisplay;
> > -- 
> > 1.9.1
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v3] drm: Add a new connector atomic property for link status
  2016-11-29  1:07       ` Manasi Navare
@ 2016-11-29  8:59         ` Daniel Vetter
  2016-11-29 16:18           ` Manasi Navare
  0 siblings, 1 reply; 27+ messages in thread
From: Daniel Vetter @ 2016-11-29  8:59 UTC (permalink / raw)
  To: Manasi Navare; +Cc: Daniel Vetter, intel-gfx, dri-devel

On Mon, Nov 28, 2016 at 05:07:52PM -0800, Manasi Navare wrote:
> On Thu, Nov 24, 2016 at 08:51:35AM +0100, Daniel Vetter wrote:
> > On Wed, Nov 23, 2016 at 11:28:21PM -0800, Manasi Navare wrote:
> > > This is RFC patch for adding a connector link-status property
> > > and making it atomic by adding it to the drm_connector_state.
> > > This is to make sure its wired properly in drm_atomic_connector_set_property
> > > and drm_atomic_connector_get_property functions.
> > > 
> > > v3:
> > > * Fixed a build error (Jani Saarinen)
> > > v2:
> > > * Removed connector->link_status (Daniel Vetter)
> > > * Set connector->state->link_status in drm_mode_connector_set_link_status_property
> > > (Daniel Vetter)
> > > * Set the connector_changed flag to true if connector->state->link_status changed.
> > > * Reset link_status to GOOD in update_output_state (Daniel Vetter)
> > > * Never allow userspace to set link status from Good To Bad (Daniel Vetter)
> > > 
> > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > Cc: Sean Paul <seanpaul@chromium.org>
> > 
> > You lost all the acked-by from AMD about the link-status property. We need
> > those.
> > 
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > 
> > Yeah I think this should work, but obviously testing has the final say.
> > Some nitpicks below, then it's r-b: me. But I think we also need to polish
> > the kernel-doc a bit more to address Sean Paul's questions.
> > -Daniel
> >
> 
> I tested it with SNA driver with Chris's changes to read the link-status
> property, but It is not able to detect the link-status property being set to BAD
> and hence it does not trigger a new modeset.
> Do we need to make any changes to the SNA driver now that this is made a ATOMIC
> property so that GETCONNECTOR IOCTL can still read the correct value
> of this property throught drm_atomic_get_property() interface?
> 
> Chris, Daniel, any thoughts? 

We agreed that it must _not_ be a PROPERTY_ATOMIC property, so that old
userspace can see it.

> > > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> > >  		return -ENOMEM;
> > >  	dev->mode_config.tile_property = prop;
> > >  
> > > +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",

I.e. remote DRM_MODE_PROP_ATOMIC here. I thought we've discussed this a
lot already ...?

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-29  0:59     ` Manasi Navare
@ 2016-11-29 14:45       ` Sean Paul
  2016-11-29 19:43         ` Sean Paul
  0 siblings, 1 reply; 27+ messages in thread
From: Sean Paul @ 2016-11-29 14:45 UTC (permalink / raw)
  To: Manasi Navare; +Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Mon, Nov 28, 2016 at 7:59 PM, Manasi Navare
<manasi.d.navare@intel.com> wrote:
> On Wed, Nov 23, 2016 at 09:09:28AM +0100, Daniel Vetter wrote:
>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>> > On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>> > <manasi.d.navare@intel.com> wrote:
>> > > This is RFC patch for adding a connector link-status property
>> > > and making it atomic by adding it to the drm_connector_state.
>> > > This is to make sure its wired properly in drm_atomic_connector_set_property
>> > > and drm_atomic_connector_get_property functions.
>> > >
>> >
>> > Thanks for sending this. We ran into some re-training awkwardness
>> > recently, and I
>> > was hoping for such a patch.
>> >
>> > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
>> > > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>> > > ---
>> > >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>> > >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>> > >  include/drm/drm_connector.h     | 12 +++++++-
>> > >  include/drm/drm_mode_config.h   |  5 ++++
>> > >  include/uapi/drm/drm_mode.h     |  4 +++
>> > >  5 files changed, 88 insertions(+), 3 deletions(-)
>> > >
>> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> > > index 89737e4..644d19f 100644
>> > > --- a/drivers/gpu/drm/drm_atomic.c
>> > > +++ b/drivers/gpu/drm/drm_atomic.c
>> > > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>> > >                  * now?) atomic writes to DPMS property:
>> > >                  */
>> > >                 return -EINVAL;
>> > > +       } else if (property == config->link_status_property) {
>> > > +               state->link_status = val;
>>
>> I think we should have a check here to make sure userspace never tries to
>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
>> atomic userspace is supposed to be able to just restore everything to what
>> it was.
>>
>> I don't think trying to set it to "BAD" should cause an error though, just
>> silently keep the link status at "GOOG". So:
>>
>>       /* Never downgrade from GOOD to BAD on userspace's request here,
>>        * only hw issues can do that. */
>>       if (state->link_status == GOOD)
>>               return 0;
>>       state->link_status = val;
>>       return 0;
>>
>> > > +               return 0;
>> > >         } else if (connector->funcs->atomic_set_property) {
>> > >                 return connector->funcs->atomic_set_property(connector,
>> > >                                 state, property, val);
>> > > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>> > >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>> > >         } else if (property == config->dpms_property) {
>> > >                 *val = connector->dpms;
>> > > +       } else if (property == config->link_status_property) {
>> > > +               *val = state->link_status;
>> > >         } else if (connector->funcs->atomic_get_property) {
>> > >                 return connector->funcs->atomic_get_property(connector,
>> > >                                 state, property, val);
>> > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>> > > index 5a45262..4576c9f 100644
>> > > --- a/drivers/gpu/drm/drm_connector.c
>> > > +++ b/drivers/gpu/drm/drm_connector.c
>> > > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>> > >         drm_object_attach_property(&connector->base,
>> > >                                       config->dpms_property, 0);
>> > >
>> > > +       drm_object_attach_property(&connector->base,
>> > > +                                  config->link_status_property,
>> > > +                                  0);
>> > > +
>> > >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>> > >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>> > >         }
>> > > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>> > >  };
>> > >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>> > >
>> > > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>> > > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>> > > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>> > > +};
>> > > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>> > > +
>> > >  /**
>> > >   * drm_display_info_set_bus_formats - set the supported bus formats
>> > >   * @info: display info to store bus formats in
>> > > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> > >   *     path property the MST manager created. Userspace cannot change this
>> > >   *     property.
>> > >   * TILE:
>> > > - *     Connector tile group property to indicate how a set of DRM connector
>> > > + *      Connector tile group property to indicate how a set of DRM connector
>> >
>> > keyboard slip here
>> >
>> > >   *     compose together into one logical screen. This is used by both high-res
>> > >   *     external screens (often only using a single cable, but exposing multiple
>> > >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>> > > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>> > >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>> > >   *     should update this value using drm_mode_connector_set_tile_property().
>> > >   *     Userspace cannot change this property.
>> > > - *
>> > > + * link-status:
>> > > + *      Connector link-status property to indicate the status of link during
>> > > + *      the modeset. The default value of link-status is "GOOD". If something
>> > > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>> > > + *      the mode list based on new link parameters and send a hotplug uevent
>> > > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>> > > + *      IOCTL and redo a modeset. Drivers should update this value using
>> > > + *      drm_mode_connector_set_link_status_property().
>> > >   * Connectors also have one standardized atomic property:
>> > >   *
>> > >   * CRTC_ID:
>> > > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>> > >                 return -ENOMEM;
>> > >         dev->mode_config.tile_property = prop;
>> > >
>> > > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>> > > +                                       drm_link_status_enum_list,
>> > > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>> > > +       if (!prop)
>> > > +               return -ENOMEM;
>> > > +       dev->mode_config.link_status_property = prop;
>> > > +
>> > >         return 0;
>> > >  }
>> > >
>> > > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>> > >  }
>> > >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>> > >
>> > > +/**
>> > > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>> > > + * @connector: drm connector
>> > > + * @link_status: new value of link status property (0: Good, 1: Bad)
>> > > + *
>> > > + * In usual working scenario, this link status property will always be set to
>> > > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>> > > + * set this link status property to "BAD" and prune the mode list based on new
>> >
>> > Does the mode list really *need* to be pruned? In the case of needing
>> > to re-train a DP link,
>> > it seems like we should be able to set this BAD and keep the modelist
>> > as-is (since the sink
>> > hasn't changed)
>>
>> Well, if you prune it with the same constraints as before, no additional
>> modes will be removed and the same list is there. Pruning here refers to
>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>>
>> We might want to be a bit more explicit here perhaps? Have some good
>> proposal text to insert?
>> >
>
> Sean, do you have any recommendations on the text that can go in the kernel doc for
> this property to clarify that it depends on the kernel implementation whether we want
> to use this link-status property to do the retraining or not. Leaving it BAD and not doing
> anything will be fine too.
>

I'd prefer something like:

* In usual working scenario, this link status property will always be set to
* "GOOD". If something fails during or after a mode set, the driver may
* set this property to "BAD". The caller then needs to send a hotplug uevent
* for userspace to re-check the valid modes through GET_CONNECTOR_IOCTL and
* retry modeset.
*
* Note: Drivers can not rely on userspace to support this property and
* issue a modeset. As such, they may choose to handle issues (like re-training
* a link) without userspace's intervention.


The difference being that we don't need to mention modes since that
will be handled through the normal avenue and we don't necessarily
want to remove any modes from the list.

Sean


> Manasi
>> > > + * information. The caller then needs to send a hotplug uevent for userspace to
>> > > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>> >
>> > extra space
>> >
>> > > + *
>> > > + * Note that a lot of existing userspace do not handle this property.
>> > > + * Drivers can therefore not rely on userspace to fix up everything and
>> > > + * should try to handle issues (like just re-training a link) without
>> > > + * userspace's intervention. This should only be used when the current mode
>> > > + * fails and userspace must select a different display mode.
>> >
>> > Hmm, I suppose this answers my last question. It's too bad we can't
>> > rely on this, since we'll
>> > just end up with each driver rolling their own re-training logic on
>> > top of possibly supporting
>> > this (but probably not, since it's really just overhead). Perhaps this
>> > is an overly pessimistic
>> > view?
>>
>> You can forgo any re-training of course, that should work too. It's just
>> that DP spec and everyone else seem to recommend to at least do some
>> minimal effort (or maybe even upfront link training) here. But totally not
>> doing anything if the link is bad should be ok too (and probably really
>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
>> function which checks link status and set link-status to bad&fires off the
>> uevent if needed.
>>
>> Again, do you have some sample prose to add here to clarify this?
>>
>> Thanks for taking a look at this.
>>
>> Cheers, Daniel
>>
>> > > + * The DRM driver can chose to not modify property and keep link status
>> > > + * as "GOOD" always to keep the user experience same as it currently is.
>> > > + *
>> > > + * The reason for adding this property is to handle link training failures, but
>> > > + * it is not limited to DP or link training. For example, if we implement
>> > > + * asynchronous setcrtc, this property can be used to report any failures in that.
>> > > + */
>> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>> > > +                                                uint64_t link_status)
>> > > +{
>> > > +       struct drm_device *dev = connector->dev;
>> > > +
>> > > +       /* Make sure the mutex is grabbed */
>> > > +       lockdep_assert_held(&dev->mode_config.mutex);
>> > > +       connector->link_status = link_status;
>> > > +       drm_object_property_set_value(&connector->base,
>> > > +                                     dev->mode_config.link_status_property,
>> > > +                                     link_status);
>> > > +}
>> > > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>> > > +
>> > >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>> > >                                     struct drm_property *property,
>> > >                                     uint64_t value)
>> > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>> > > index 34f9741..3d513ab 100644
>> > > --- a/include/drm/drm_connector.h
>> > > +++ b/include/drm/drm_connector.h
>> > > @@ -213,6 +213,9 @@ struct drm_connector_state {
>> > >
>> > >         struct drm_encoder *best_encoder;
>> > >
>> > > +       /* Connector Link status */
>> > > +       unsigned int link_status;
>> > > +
>> > >         struct drm_atomic_state *state;
>> > >  };
>> > >
>> > > @@ -695,6 +698,12 @@ struct drm_connector {
>> > >         uint8_t num_h_tile, num_v_tile;
>> > >         uint8_t tile_h_loc, tile_v_loc;
>> > >         uint16_t tile_h_size, tile_v_size;
>> > > +
>> > > +       /* Connector Link status
>> > > +        * 0: If the link is Good
>> > > +        * 1: If the link is Bad
>> > > +        */
>> > > +       int link_status;
>> > >  };
>> > >
>> > >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>> > > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>> > >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>> > >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>> > >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>> > > -
>> >
>> > lost a line here
>> >
>> > >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>> > >                                          const char *path);
>> > >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>> > >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>> > >                                             const struct edid *edid);
>> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>> > > +                                                uint64_t link_status);
>> > >
>> > >  /**
>> > >   * struct drm_tile_group - Tile group metadata
>> > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>> > > index bf9991b..86faee4 100644
>> > > --- a/include/drm/drm_mode_config.h
>> > > +++ b/include/drm/drm_mode_config.h
>> > > @@ -431,6 +431,11 @@ struct drm_mode_config {
>> > >          */
>> > >         struct drm_property *tile_property;
>> > >         /**
>> > > +        * @link_status_property: Default connector property for link status
>> > > +        * of a connector
>> > > +        */
>> > > +       struct drm_property *link_status_property;
>> > > +       /**
>> > >          * @plane_type_property: Default plane property to differentiate
>> > >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>> > >          */
>> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>> > > index 728790b..309c478 100644
>> > > --- a/include/uapi/drm/drm_mode.h
>> > > +++ b/include/uapi/drm/drm_mode.h
>> > > @@ -123,6 +123,10 @@
>> > >  #define DRM_MODE_DIRTY_ON       1
>> > >  #define DRM_MODE_DIRTY_ANNOTATE 2
>> > >
>> > > +/* Link Status options */
>> > > +#define DRM_MODE_LINK_STATUS_GOOD      0
>> > > +#define DRM_MODE_LINK_STATUS_BAD       1
>> > > +
>> > >  struct drm_mode_modeinfo {
>> > >         __u32 clock;
>> > >         __u16 hdisplay;
>> > > --
>> > > 1.9.1
>> > >
>> > > _______________________________________________
>> > > dri-devel mailing list
>> > > dri-devel@lists.freedesktop.org
>> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>> > _______________________________________________
>> > dri-devel mailing list
>> > dri-devel@lists.freedesktop.org
>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>> --
>> Daniel Vetter
>> Software Engineer, Intel Corporation
>> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v3] drm: Add a new connector atomic property for link status
  2016-11-29  8:59         ` Daniel Vetter
@ 2016-11-29 16:18           ` Manasi Navare
  0 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-11-29 16:18 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, intel-gfx, dri-devel

On Tue, Nov 29, 2016 at 09:59:14AM +0100, Daniel Vetter wrote:
> On Mon, Nov 28, 2016 at 05:07:52PM -0800, Manasi Navare wrote:
> > On Thu, Nov 24, 2016 at 08:51:35AM +0100, Daniel Vetter wrote:
> > > On Wed, Nov 23, 2016 at 11:28:21PM -0800, Manasi Navare wrote:
> > > > This is RFC patch for adding a connector link-status property
> > > > and making it atomic by adding it to the drm_connector_state.
> > > > This is to make sure its wired properly in drm_atomic_connector_set_property
> > > > and drm_atomic_connector_get_property functions.
> > > > 
> > > > v3:
> > > > * Fixed a build error (Jani Saarinen)
> > > > v2:
> > > > * Removed connector->link_status (Daniel Vetter)
> > > > * Set connector->state->link_status in drm_mode_connector_set_link_status_property
> > > > (Daniel Vetter)
> > > > * Set the connector_changed flag to true if connector->state->link_status changed.
> > > > * Reset link_status to GOOD in update_output_state (Daniel Vetter)
> > > > * Never allow userspace to set link status from Good To Bad (Daniel Vetter)
> > > > 
> > > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > > Cc: Sean Paul <seanpaul@chromium.org>
> > > 
> > > You lost all the acked-by from AMD about the link-status property. We need
> > > those.
> > > 
> > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > 
> > > Yeah I think this should work, but obviously testing has the final say.
> > > Some nitpicks below, then it's r-b: me. But I think we also need to polish
> > > the kernel-doc a bit more to address Sean Paul's questions.
> > > -Daniel
> > >
> > 
> > I tested it with SNA driver with Chris's changes to read the link-status
> > property, but It is not able to detect the link-status property being set to BAD
> > and hence it does not trigger a new modeset.
> > Do we need to make any changes to the SNA driver now that this is made a ATOMIC
> > property so that GETCONNECTOR IOCTL can still read the correct value
> > of this property throught drm_atomic_get_property() interface?
> > 
> > Chris, Daniel, any thoughts? 
> 
> We agreed that it must _not_ be a PROPERTY_ATOMIC property, so that old
> userspace can see it.
> 
> > > > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> > > >  		return -ENOMEM;
> > > >  	dev->mode_config.tile_property = prop;
> > > >  
> > > > +	prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> 
> I.e. remote DRM_MODE_PROP_ATOMIC here. I thought we've discussed this a
> lot already ...?
> 
> Cheers, Daniel
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

Hi Daniel,

Yes this is where I was confused in the beginning that whether we need the flag.
Ok so this property will not have atomic flag, so drm-mode_object_get_properties should
call the drm_object_property_get_value() and that should expose
the value to userspace right?

Manasi
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-29 14:45       ` Sean Paul
@ 2016-11-29 19:43         ` Sean Paul
  2016-11-29 20:42           ` Manasi Navare
  0 siblings, 1 reply; 27+ messages in thread
From: Sean Paul @ 2016-11-29 19:43 UTC (permalink / raw)
  To: Manasi Navare; +Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Tue, Nov 29, 2016 at 9:45 AM, Sean Paul <seanpaul@chromium.org> wrote:
> On Mon, Nov 28, 2016 at 7:59 PM, Manasi Navare
> <manasi.d.navare@intel.com> wrote:
>> On Wed, Nov 23, 2016 at 09:09:28AM +0100, Daniel Vetter wrote:
>>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
>>> > On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
>>> > <manasi.d.navare@intel.com> wrote:
>>> > > This is RFC patch for adding a connector link-status property
>>> > > and making it atomic by adding it to the drm_connector_state.
>>> > > This is to make sure its wired properly in drm_atomic_connector_set_property
>>> > > and drm_atomic_connector_get_property functions.
>>> > >
>>> >
>>> > Thanks for sending this. We ran into some re-training awkwardness
>>> > recently, and I
>>> > was hoping for such a patch.
>>> >
>>> > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
>>> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
>>> > > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>>> > > ---
>>> > >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
>>> > >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
>>> > >  include/drm/drm_connector.h     | 12 +++++++-
>>> > >  include/drm/drm_mode_config.h   |  5 ++++
>>> > >  include/uapi/drm/drm_mode.h     |  4 +++
>>> > >  5 files changed, 88 insertions(+), 3 deletions(-)
>>> > >
>>> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>>> > > index 89737e4..644d19f 100644
>>> > > --- a/drivers/gpu/drm/drm_atomic.c
>>> > > +++ b/drivers/gpu/drm/drm_atomic.c
>>> > > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
>>> > >                  * now?) atomic writes to DPMS property:
>>> > >                  */
>>> > >                 return -EINVAL;
>>> > > +       } else if (property == config->link_status_property) {
>>> > > +               state->link_status = val;
>>>
>>> I think we should have a check here to make sure userspace never tries to
>>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
>>> atomic userspace is supposed to be able to just restore everything to what
>>> it was.
>>>
>>> I don't think trying to set it to "BAD" should cause an error though, just
>>> silently keep the link status at "GOOG". So:
>>>
>>>       /* Never downgrade from GOOD to BAD on userspace's request here,
>>>        * only hw issues can do that. */
>>>       if (state->link_status == GOOD)
>>>               return 0;
>>>       state->link_status = val;
>>>       return 0;
>>>
>>> > > +               return 0;
>>> > >         } else if (connector->funcs->atomic_set_property) {
>>> > >                 return connector->funcs->atomic_set_property(connector,
>>> > >                                 state, property, val);
>>> > > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
>>> > >                 *val = (state->crtc) ? state->crtc->base.id : 0;
>>> > >         } else if (property == config->dpms_property) {
>>> > >                 *val = connector->dpms;
>>> > > +       } else if (property == config->link_status_property) {
>>> > > +               *val = state->link_status;
>>> > >         } else if (connector->funcs->atomic_get_property) {
>>> > >                 return connector->funcs->atomic_get_property(connector,
>>> > >                                 state, property, val);
>>> > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>>> > > index 5a45262..4576c9f 100644
>>> > > --- a/drivers/gpu/drm/drm_connector.c
>>> > > +++ b/drivers/gpu/drm/drm_connector.c
>>> > > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
>>> > >         drm_object_attach_property(&connector->base,
>>> > >                                       config->dpms_property, 0);
>>> > >
>>> > > +       drm_object_attach_property(&connector->base,
>>> > > +                                  config->link_status_property,
>>> > > +                                  0);
>>> > > +
>>> > >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
>>> > >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
>>> > >         }
>>> > > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
>>> > >  };
>>> > >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
>>> > >
>>> > > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
>>> > > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
>>> > > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
>>> > > +};
>>> > > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
>>> > > +
>>> > >  /**
>>> > >   * drm_display_info_set_bus_formats - set the supported bus formats
>>> > >   * @info: display info to store bus formats in
>>> > > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>> > >   *     path property the MST manager created. Userspace cannot change this
>>> > >   *     property.
>>> > >   * TILE:
>>> > > - *     Connector tile group property to indicate how a set of DRM connector
>>> > > + *      Connector tile group property to indicate how a set of DRM connector
>>> >
>>> > keyboard slip here
>>> >
>>> > >   *     compose together into one logical screen. This is used by both high-res
>>> > >   *     external screens (often only using a single cable, but exposing multiple
>>> > >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
>>> > > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
>>> > >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
>>> > >   *     should update this value using drm_mode_connector_set_tile_property().
>>> > >   *     Userspace cannot change this property.
>>> > > - *
>>> > > + * link-status:
>>> > > + *      Connector link-status property to indicate the status of link during
>>> > > + *      the modeset. The default value of link-status is "GOOD". If something
>>> > > + *      fails during modeset, the kernel driver can set this to "BAD", prune
>>> > > + *      the mode list based on new link parameters and send a hotplug uevent
>>> > > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
>>> > > + *      IOCTL and redo a modeset. Drivers should update this value using
>>> > > + *      drm_mode_connector_set_link_status_property().

While I'm nitpicking documentation, I think this one needs work, too.
I'd prefer you just describe what the property conveys here instead of
getting into driver implementation specifics. So something like:

* link-status
*     Connector link-status property to indicate the status of link. The
*     default value is "GOOD". If something fails during, or after modeset,
*     the driver may set this to "BAD" and issue a hotplug uevent. Drivers
*     should update this value using
*     drm_mode_connector_set_link_status_property()

Sean

>>> > >   * Connectors also have one standardized atomic property:
>>> > >   *
>>> > >   * CRTC_ID:
>>> > > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
>>> > >                 return -ENOMEM;
>>> > >         dev->mode_config.tile_property = prop;
>>> > >
>>> > > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
>>> > > +                                       drm_link_status_enum_list,
>>> > > +                                       ARRAY_SIZE(drm_link_status_enum_list));
>>> > > +       if (!prop)
>>> > > +               return -ENOMEM;
>>> > > +       dev->mode_config.link_status_property = prop;
>>> > > +
>>> > >         return 0;
>>> > >  }
>>> > >
>>> > > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>> > >  }
>>> > >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
>>> > >
>>> > > +/**
>>> > > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
>>> > > + * @connector: drm connector
>>> > > + * @link_status: new value of link status property (0: Good, 1: Bad)
>>> > > + *
>>> > > + * In usual working scenario, this link status property will always be set to
>>> > > + * "GOOD". If something fails during or after a mode set, the kernel driver should
>>> > > + * set this link status property to "BAD" and prune the mode list based on new
>>> >
>>> > Does the mode list really *need* to be pruned? In the case of needing
>>> > to re-train a DP link,
>>> > it seems like we should be able to set this BAD and keep the modelist
>>> > as-is (since the sink
>>> > hasn't changed)
>>>
>>> Well, if you prune it with the same constraints as before, no additional
>>> modes will be removed and the same list is there. Pruning here refers to
>>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
>>>
>>> We might want to be a bit more explicit here perhaps? Have some good
>>> proposal text to insert?
>>> >
>>
>> Sean, do you have any recommendations on the text that can go in the kernel doc for
>> this property to clarify that it depends on the kernel implementation whether we want
>> to use this link-status property to do the retraining or not. Leaving it BAD and not doing
>> anything will be fine too.
>>
>
> I'd prefer something like:
>
> * In usual working scenario, this link status property will always be set to
> * "GOOD". If something fails during or after a mode set, the driver may
> * set this property to "BAD". The caller then needs to send a hotplug uevent
> * for userspace to re-check the valid modes through GET_CONNECTOR_IOCTL and
> * retry modeset.
> *
> * Note: Drivers can not rely on userspace to support this property and
> * issue a modeset. As such, they may choose to handle issues (like re-training
> * a link) without userspace's intervention.
>
>
> The difference being that we don't need to mention modes since that
> will be handled through the normal avenue and we don't necessarily
> want to remove any modes from the list.
>
> Sean
>
>
>> Manasi
>>> > > + * information. The caller then needs to send a hotplug uevent for userspace to
>>> > > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
>>> >
>>> > extra space
>>> >
>>> > > + *
>>> > > + * Note that a lot of existing userspace do not handle this property.
>>> > > + * Drivers can therefore not rely on userspace to fix up everything and
>>> > > + * should try to handle issues (like just re-training a link) without
>>> > > + * userspace's intervention. This should only be used when the current mode
>>> > > + * fails and userspace must select a different display mode.
>>> >
>>> > Hmm, I suppose this answers my last question. It's too bad we can't
>>> > rely on this, since we'll
>>> > just end up with each driver rolling their own re-training logic on
>>> > top of possibly supporting
>>> > this (but probably not, since it's really just overhead). Perhaps this
>>> > is an overly pessimistic
>>> > view?
>>>
>>> You can forgo any re-training of course, that should work too. It's just
>>> that DP spec and everyone else seem to recommend to at least do some
>>> minimal effort (or maybe even upfront link training) here. But totally not
>>> doing anything if the link is bad should be ok too (and probably really
>>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
>>> function which checks link status and set link-status to bad&fires off the
>>> uevent if needed.
>>>
>>> Again, do you have some sample prose to add here to clarify this?
>>>
>>> Thanks for taking a look at this.
>>>
>>> Cheers, Daniel
>>>
>>> > > + * The DRM driver can chose to not modify property and keep link status
>>> > > + * as "GOOD" always to keep the user experience same as it currently is.
>>> > > + *
>>> > > + * The reason for adding this property is to handle link training failures, but
>>> > > + * it is not limited to DP or link training. For example, if we implement
>>> > > + * asynchronous setcrtc, this property can be used to report any failures in that.
>>> > > + */
>>> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>> > > +                                                uint64_t link_status)
>>> > > +{
>>> > > +       struct drm_device *dev = connector->dev;
>>> > > +
>>> > > +       /* Make sure the mutex is grabbed */
>>> > > +       lockdep_assert_held(&dev->mode_config.mutex);
>>> > > +       connector->link_status = link_status;
>>> > > +       drm_object_property_set_value(&connector->base,
>>> > > +                                     dev->mode_config.link_status_property,
>>> > > +                                     link_status);
>>> > > +}
>>> > > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
>>> > > +
>>> > >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
>>> > >                                     struct drm_property *property,
>>> > >                                     uint64_t value)
>>> > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>>> > > index 34f9741..3d513ab 100644
>>> > > --- a/include/drm/drm_connector.h
>>> > > +++ b/include/drm/drm_connector.h
>>> > > @@ -213,6 +213,9 @@ struct drm_connector_state {
>>> > >
>>> > >         struct drm_encoder *best_encoder;
>>> > >
>>> > > +       /* Connector Link status */
>>> > > +       unsigned int link_status;
>>> > > +
>>> > >         struct drm_atomic_state *state;
>>> > >  };
>>> > >
>>> > > @@ -695,6 +698,12 @@ struct drm_connector {
>>> > >         uint8_t num_h_tile, num_v_tile;
>>> > >         uint8_t tile_h_loc, tile_v_loc;
>>> > >         uint16_t tile_h_size, tile_v_size;
>>> > > +
>>> > > +       /* Connector Link status
>>> > > +        * 0: If the link is Good
>>> > > +        * 1: If the link is Bad
>>> > > +        */
>>> > > +       int link_status;
>>> > >  };
>>> > >
>>> > >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
>>> > > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>>> > >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
>>> > >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
>>> > >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>>> > > -
>>> >
>>> > lost a line here
>>> >
>>> > >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
>>> > >                                          const char *path);
>>> > >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
>>> > >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
>>> > >                                             const struct edid *edid);
>>> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
>>> > > +                                                uint64_t link_status);
>>> > >
>>> > >  /**
>>> > >   * struct drm_tile_group - Tile group metadata
>>> > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>>> > > index bf9991b..86faee4 100644
>>> > > --- a/include/drm/drm_mode_config.h
>>> > > +++ b/include/drm/drm_mode_config.h
>>> > > @@ -431,6 +431,11 @@ struct drm_mode_config {
>>> > >          */
>>> > >         struct drm_property *tile_property;
>>> > >         /**
>>> > > +        * @link_status_property: Default connector property for link status
>>> > > +        * of a connector
>>> > > +        */
>>> > > +       struct drm_property *link_status_property;
>>> > > +       /**
>>> > >          * @plane_type_property: Default plane property to differentiate
>>> > >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
>>> > >          */
>>> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>>> > > index 728790b..309c478 100644
>>> > > --- a/include/uapi/drm/drm_mode.h
>>> > > +++ b/include/uapi/drm/drm_mode.h
>>> > > @@ -123,6 +123,10 @@
>>> > >  #define DRM_MODE_DIRTY_ON       1
>>> > >  #define DRM_MODE_DIRTY_ANNOTATE 2
>>> > >
>>> > > +/* Link Status options */
>>> > > +#define DRM_MODE_LINK_STATUS_GOOD      0
>>> > > +#define DRM_MODE_LINK_STATUS_BAD       1
>>> > > +
>>> > >  struct drm_mode_modeinfo {
>>> > >         __u32 clock;
>>> > >         __u16 hdisplay;
>>> > > --
>>> > > 1.9.1
>>> > >
>>> > > _______________________________________________
>>> > > dri-devel mailing list
>>> > > dri-devel@lists.freedesktop.org
>>> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>> > _______________________________________________
>>> > dri-devel mailing list
>>> > dri-devel@lists.freedesktop.org
>>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>
>>> --
>>> Daniel Vetter
>>> Software Engineer, Intel Corporation
>>> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC] drm: Add a new connector atomic property for link status
  2016-11-29 19:43         ` Sean Paul
@ 2016-11-29 20:42           ` Manasi Navare
  0 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-11-29 20:42 UTC (permalink / raw)
  To: Sean Paul; +Cc: Daniel Vetter, Intel Graphics Development, dri-devel

On Tue, Nov 29, 2016 at 02:43:55PM -0500, Sean Paul wrote:
> On Tue, Nov 29, 2016 at 9:45 AM, Sean Paul <seanpaul@chromium.org> wrote:
> > On Mon, Nov 28, 2016 at 7:59 PM, Manasi Navare
> > <manasi.d.navare@intel.com> wrote:
> >> On Wed, Nov 23, 2016 at 09:09:28AM +0100, Daniel Vetter wrote:
> >>> On Tue, Nov 22, 2016 at 09:27:35PM -0500, Sean Paul wrote:
> >>> > On Tue, Nov 22, 2016 at 8:30 PM, Manasi Navare
> >>> > <manasi.d.navare@intel.com> wrote:
> >>> > > This is RFC patch for adding a connector link-status property
> >>> > > and making it atomic by adding it to the drm_connector_state.
> >>> > > This is to make sure its wired properly in drm_atomic_connector_set_property
> >>> > > and drm_atomic_connector_get_property functions.
> >>> > >
> >>> >
> >>> > Thanks for sending this. We ran into some re-training awkwardness
> >>> > recently, and I
> >>> > was hoping for such a patch.
> >>> >
> >>> > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> >>> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> >>> > > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> >>> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> >>> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> >>> > > ---
> >>> > >  drivers/gpu/drm/drm_atomic.c    |  5 ++++
> >>> > >  drivers/gpu/drm/drm_connector.c | 65 +++++++++++++++++++++++++++++++++++++++--
> >>> > >  include/drm/drm_connector.h     | 12 +++++++-
> >>> > >  include/drm/drm_mode_config.h   |  5 ++++
> >>> > >  include/uapi/drm/drm_mode.h     |  4 +++
> >>> > >  5 files changed, 88 insertions(+), 3 deletions(-)
> >>> > >
> >>> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >>> > > index 89737e4..644d19f 100644
> >>> > > --- a/drivers/gpu/drm/drm_atomic.c
> >>> > > +++ b/drivers/gpu/drm/drm_atomic.c
> >>> > > @@ -1087,6 +1087,9 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
> >>> > >                  * now?) atomic writes to DPMS property:
> >>> > >                  */
> >>> > >                 return -EINVAL;
> >>> > > +       } else if (property == config->link_status_property) {
> >>> > > +               state->link_status = val;
> >>>
> >>> I think we should have a check here to make sure userspace never tries to
> >>> set this from "GOOD" to "BAD". "BAD" to "BAD" we need to allow, since with
> >>> atomic userspace is supposed to be able to just restore everything to what
> >>> it was.
> >>>
> >>> I don't think trying to set it to "BAD" should cause an error though, just
> >>> silently keep the link status at "GOOG". So:
> >>>
> >>>       /* Never downgrade from GOOD to BAD on userspace's request here,
> >>>        * only hw issues can do that. */
> >>>       if (state->link_status == GOOD)
> >>>               return 0;
> >>>       state->link_status = val;
> >>>       return 0;
> >>>
> >>> > > +               return 0;
> >>> > >         } else if (connector->funcs->atomic_set_property) {
> >>> > >                 return connector->funcs->atomic_set_property(connector,
> >>> > >                                 state, property, val);
> >>> > > @@ -1135,6 +1138,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
> >>> > >                 *val = (state->crtc) ? state->crtc->base.id : 0;
> >>> > >         } else if (property == config->dpms_property) {
> >>> > >                 *val = connector->dpms;
> >>> > > +       } else if (property == config->link_status_property) {
> >>> > > +               *val = state->link_status;
> >>> > >         } else if (connector->funcs->atomic_get_property) {
> >>> > >                 return connector->funcs->atomic_get_property(connector,
> >>> > >                                 state, property, val);
> >>> > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> >>> > > index 5a45262..4576c9f 100644
> >>> > > --- a/drivers/gpu/drm/drm_connector.c
> >>> > > +++ b/drivers/gpu/drm/drm_connector.c
> >>> > > @@ -243,6 +243,10 @@ int drm_connector_init(struct drm_device *dev,
> >>> > >         drm_object_attach_property(&connector->base,
> >>> > >                                       config->dpms_property, 0);
> >>> > >
> >>> > > +       drm_object_attach_property(&connector->base,
> >>> > > +                                  config->link_status_property,
> >>> > > +                                  0);
> >>> > > +
> >>> > >         if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> >>> > >                 drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
> >>> > >         }
> >>> > > @@ -506,6 +510,12 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order)
> >>> > >  };
> >>> > >  DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
> >>> > >
> >>> > > +static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
> >>> > > +       { DRM_MODE_LINK_STATUS_GOOD, "Good" },
> >>> > > +       { DRM_MODE_LINK_STATUS_BAD, "Bad" },
> >>> > > +};
> >>> > > +DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
> >>> > > +
> >>> > >  /**
> >>> > >   * drm_display_info_set_bus_formats - set the supported bus formats
> >>> > >   * @info: display info to store bus formats in
> >>> > > @@ -616,7 +626,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >>> > >   *     path property the MST manager created. Userspace cannot change this
> >>> > >   *     property.
> >>> > >   * TILE:
> >>> > > - *     Connector tile group property to indicate how a set of DRM connector
> >>> > > + *      Connector tile group property to indicate how a set of DRM connector
> >>> >
> >>> > keyboard slip here
> >>> >
> >>> > >   *     compose together into one logical screen. This is used by both high-res
> >>> > >   *     external screens (often only using a single cable, but exposing multiple
> >>> > >   *     DP MST sinks), or high-res integrated panels (like dual-link DSI) which
> >>> > > @@ -625,7 +635,14 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
> >>> > >   *     tiling and virtualize both &drm_crtc and &drm_plane if needed. Drivers
> >>> > >   *     should update this value using drm_mode_connector_set_tile_property().
> >>> > >   *     Userspace cannot change this property.
> >>> > > - *
> >>> > > + * link-status:
> >>> > > + *      Connector link-status property to indicate the status of link during
> >>> > > + *      the modeset. The default value of link-status is "GOOD". If something
> >>> > > + *      fails during modeset, the kernel driver can set this to "BAD", prune
> >>> > > + *      the mode list based on new link parameters and send a hotplug uevent
> >>> > > + *      to notify userspace to re-check the valid modes through GET_CONNECTOR
> >>> > > + *      IOCTL and redo a modeset. Drivers should update this value using
> >>> > > + *      drm_mode_connector_set_link_status_property().
> 
> While I'm nitpicking documentation, I think this one needs work, too.
> I'd prefer you just describe what the property conveys here instead of
> getting into driver implementation specifics. So something like:
> 
> * link-status
> *     Connector link-status property to indicate the status of link. The
> *     default value is "GOOD". If something fails during, or after modeset,
> *     the driver may set this to "BAD" and issue a hotplug uevent. Drivers
> *     should update this value using
> *     drm_mode_connector_set_link_status_property()
> 
> Sean
>

Thanks a lot for your feedback.
I will incorporate these changes here and the ones you pointed out
in the previous email and send a new revision.

Regards
Manasi

 
> >>> > >   * Connectors also have one standardized atomic property:
> >>> > >   *
> >>> > >   * CRTC_ID:
> >>> > > @@ -666,6 +683,13 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
> >>> > >                 return -ENOMEM;
> >>> > >         dev->mode_config.tile_property = prop;
> >>> > >
> >>> > > +       prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "link-status",
> >>> > > +                                       drm_link_status_enum_list,
> >>> > > +                                       ARRAY_SIZE(drm_link_status_enum_list));
> >>> > > +       if (!prop)
> >>> > > +               return -ENOMEM;
> >>> > > +       dev->mode_config.link_status_property = prop;
> >>> > > +
> >>> > >         return 0;
> >>> > >  }
> >>> > >
> >>> > > @@ -995,6 +1019,43 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >>> > >  }
> >>> > >  EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
> >>> > >
> >>> > > +/**
> >>> > > + * drm_mode_connector_set_link_status_property - Set link status property of a connector
> >>> > > + * @connector: drm connector
> >>> > > + * @link_status: new value of link status property (0: Good, 1: Bad)
> >>> > > + *
> >>> > > + * In usual working scenario, this link status property will always be set to
> >>> > > + * "GOOD". If something fails during or after a mode set, the kernel driver should
> >>> > > + * set this link status property to "BAD" and prune the mode list based on new
> >>> >
> >>> > Does the mode list really *need* to be pruned? In the case of needing
> >>> > to re-train a DP link,
> >>> > it seems like we should be able to set this BAD and keep the modelist
> >>> > as-is (since the sink
> >>> > hasn't changed)
> >>>
> >>> Well, if you prune it with the same constraints as before, no additional
> >>> modes will be removed and the same list is there. Pruning here refers to
> >>> the ->mode_valid step as done in e.g. drm_helper_probe_single_connector_modes.
> >>>
> >>> We might want to be a bit more explicit here perhaps? Have some good
> >>> proposal text to insert?
> >>> >
> >>
> >> Sean, do you have any recommendations on the text that can go in the kernel doc for
> >> this property to clarify that it depends on the kernel implementation whether we want
> >> to use this link-status property to do the retraining or not. Leaving it BAD and not doing
> >> anything will be fine too.
> >>
> >
> > I'd prefer something like:
> >
> > * In usual working scenario, this link status property will always be set to
> > * "GOOD". If something fails during or after a mode set, the driver may
> > * set this property to "BAD". The caller then needs to send a hotplug uevent
> > * for userspace to re-check the valid modes through GET_CONNECTOR_IOCTL and
> > * retry modeset.
> > *
> > * Note: Drivers can not rely on userspace to support this property and
> > * issue a modeset. As such, they may choose to handle issues (like re-training
> > * a link) without userspace's intervention.
> >
> >
> > The difference being that we don't need to mention modes since that
> > will be handled through the normal avenue and we don't necessarily
> > want to remove any modes from the list.
> >
> > Sean
> >
> >
> >> Manasi
> >>> > > + * information. The caller then needs to send a hotplug uevent for userspace to
> >>> > > + *  re-check the valid modes through GET_CONNECTOR_IOCTL and retry modeset.
> >>> >
> >>> > extra space
> >>> >
> >>> > > + *
> >>> > > + * Note that a lot of existing userspace do not handle this property.
> >>> > > + * Drivers can therefore not rely on userspace to fix up everything and
> >>> > > + * should try to handle issues (like just re-training a link) without
> >>> > > + * userspace's intervention. This should only be used when the current mode
> >>> > > + * fails and userspace must select a different display mode.
> >>> >
> >>> > Hmm, I suppose this answers my last question. It's too bad we can't
> >>> > rely on this, since we'll
> >>> > just end up with each driver rolling their own re-training logic on
> >>> > top of possibly supporting
> >>> > this (but probably not, since it's really just overhead). Perhaps this
> >>> > is an overly pessimistic
> >>> > view?
> >>>
> >>> You can forgo any re-training of course, that should work too. It's just
> >>> that DP spec and everyone else seem to recommend to at least do some
> >>> minimal effort (or maybe even upfront link training) here. But totally not
> >>> doing anything if the link is bad should be ok too (and probably really
> >>> simple to implement for drivers, maybe even with a dp_hpd_handler() helper
> >>> function which checks link status and set link-status to bad&fires off the
> >>> uevent if needed.
> >>>
> >>> Again, do you have some sample prose to add here to clarify this?
> >>>
> >>> Thanks for taking a look at this.
> >>>
> >>> Cheers, Daniel
> >>>
> >>> > > + * The DRM driver can chose to not modify property and keep link status
> >>> > > + * as "GOOD" always to keep the user experience same as it currently is.
> >>> > > + *
> >>> > > + * The reason for adding this property is to handle link training failures, but
> >>> > > + * it is not limited to DP or link training. For example, if we implement
> >>> > > + * asynchronous setcrtc, this property can be used to report any failures in that.
> >>> > > + */
> >>> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> >>> > > +                                                uint64_t link_status)
> >>> > > +{
> >>> > > +       struct drm_device *dev = connector->dev;
> >>> > > +
> >>> > > +       /* Make sure the mutex is grabbed */
> >>> > > +       lockdep_assert_held(&dev->mode_config.mutex);
> >>> > > +       connector->link_status = link_status;
> >>> > > +       drm_object_property_set_value(&connector->base,
> >>> > > +                                     dev->mode_config.link_status_property,
> >>> > > +                                     link_status);
> >>> > > +}
> >>> > > +EXPORT_SYMBOL(drm_mode_connector_set_link_status_property);
> >>> > > +
> >>> > >  int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
> >>> > >                                     struct drm_property *property,
> >>> > >                                     uint64_t value)
> >>> > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> >>> > > index 34f9741..3d513ab 100644
> >>> > > --- a/include/drm/drm_connector.h
> >>> > > +++ b/include/drm/drm_connector.h
> >>> > > @@ -213,6 +213,9 @@ struct drm_connector_state {
> >>> > >
> >>> > >         struct drm_encoder *best_encoder;
> >>> > >
> >>> > > +       /* Connector Link status */
> >>> > > +       unsigned int link_status;
> >>> > > +
> >>> > >         struct drm_atomic_state *state;
> >>> > >  };
> >>> > >
> >>> > > @@ -695,6 +698,12 @@ struct drm_connector {
> >>> > >         uint8_t num_h_tile, num_v_tile;
> >>> > >         uint8_t tile_h_loc, tile_v_loc;
> >>> > >         uint16_t tile_h_size, tile_v_size;
> >>> > > +
> >>> > > +       /* Connector Link status
> >>> > > +        * 0: If the link is Good
> >>> > > +        * 1: If the link is Bad
> >>> > > +        */
> >>> > > +       int link_status;
> >>> > >  };
> >>> > >
> >>> > >  #define obj_to_connector(x) container_of(x, struct drm_connector, base)
> >>> > > @@ -767,12 +776,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> >>> > >  int drm_mode_create_scaling_mode_property(struct drm_device *dev);
> >>> > >  int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
> >>> > >  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
> >>> > > -
> >>> >
> >>> > lost a line here
> >>> >
> >>> > >  int drm_mode_connector_set_path_property(struct drm_connector *connector,
> >>> > >                                          const char *path);
> >>> > >  int drm_mode_connector_set_tile_property(struct drm_connector *connector);
> >>> > >  int drm_mode_connector_update_edid_property(struct drm_connector *connector,
> >>> > >                                             const struct edid *edid);
> >>> > > +void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
> >>> > > +                                                uint64_t link_status);
> >>> > >
> >>> > >  /**
> >>> > >   * struct drm_tile_group - Tile group metadata
> >>> > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> >>> > > index bf9991b..86faee4 100644
> >>> > > --- a/include/drm/drm_mode_config.h
> >>> > > +++ b/include/drm/drm_mode_config.h
> >>> > > @@ -431,6 +431,11 @@ struct drm_mode_config {
> >>> > >          */
> >>> > >         struct drm_property *tile_property;
> >>> > >         /**
> >>> > > +        * @link_status_property: Default connector property for link status
> >>> > > +        * of a connector
> >>> > > +        */
> >>> > > +       struct drm_property *link_status_property;
> >>> > > +       /**
> >>> > >          * @plane_type_property: Default plane property to differentiate
> >>> > >          * CURSOR, PRIMARY and OVERLAY legacy uses of planes.
> >>> > >          */
> >>> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> >>> > > index 728790b..309c478 100644
> >>> > > --- a/include/uapi/drm/drm_mode.h
> >>> > > +++ b/include/uapi/drm/drm_mode.h
> >>> > > @@ -123,6 +123,10 @@
> >>> > >  #define DRM_MODE_DIRTY_ON       1
> >>> > >  #define DRM_MODE_DIRTY_ANNOTATE 2
> >>> > >
> >>> > > +/* Link Status options */
> >>> > > +#define DRM_MODE_LINK_STATUS_GOOD      0
> >>> > > +#define DRM_MODE_LINK_STATUS_BAD       1
> >>> > > +
> >>> > >  struct drm_mode_modeinfo {
> >>> > >         __u32 clock;
> >>> > >         __u16 hdisplay;
> >>> > > --
> >>> > > 1.9.1
> >>> > >
> >>> > > _______________________________________________
> >>> > > dri-devel mailing list
> >>> > > dri-devel@lists.freedesktop.org
> >>> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> >>> > _______________________________________________
> >>> > dri-devel mailing list
> >>> > dri-devel@lists.freedesktop.org
> >>> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> >>>
> >>> --
> >>> Daniel Vetter
> >>> Software Engineer, Intel Corporation
> >>> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2016-11-29 20:42 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-23  1:30 [PATCH RFC] drm: Add a new connector atomic property for link status Manasi Navare
2016-11-23  1:45 ` ✗ Fi.CI.BAT: warning for " Patchwork
2016-11-23  2:27 ` [PATCH RFC] " Sean Paul
2016-11-23  8:09   ` Daniel Vetter
2016-11-23 14:40     ` Sean Paul
2016-11-23 15:15       ` Jani Nikula
2016-11-23 15:32         ` Sean Paul
2016-11-23 15:43           ` Ville Syrjälä
2016-11-23 16:05             ` [Intel-gfx] " Sean Paul
2016-11-23 15:52           ` Jani Nikula
2016-11-23 16:09             ` Sean Paul
2016-11-23 16:11             ` Daniel Vetter
2016-11-29  0:59     ` Manasi Navare
2016-11-29 14:45       ` Sean Paul
2016-11-29 19:43         ` Sean Paul
2016-11-29 20:42           ` Manasi Navare
2016-11-23 10:00 ` Daniel Vetter
2016-11-23 19:07   ` Manasi Navare
2016-11-24  2:38 ` [PATCH RFC v2] " Manasi Navare
2016-11-24  7:28   ` [PATCH RFC v3] " Manasi Navare
2016-11-24  7:51     ` Daniel Vetter
2016-11-28 19:32       ` Manasi Navare
2016-11-29  1:07       ` Manasi Navare
2016-11-29  8:59         ` Daniel Vetter
2016-11-29 16:18           ` Manasi Navare
2016-11-24  4:01 ` ✗ Fi.CI.BAT: failure for drm: Add a new connector atomic property for link status (rev3) Patchwork
2016-11-24  8:45 ` ✓ Fi.CI.BAT: success for drm: Add a new connector atomic property for link status (rev4) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.