drm/panel: Add an API to allow drm to set orientation from panel
authorHsin-Yi Wang <hsinyi@chromium.org>
Thu, 9 Jun 2022 07:27:15 +0000 (15:27 +0800)
committerDouglas Anderson <dianders@chromium.org>
Tue, 21 Jun 2022 15:40:30 +0000 (08:40 -0700)
Panels usually call drm_connector_set_panel_orientation(), which is
later than drm/kms driver calling drm_dev_register(). This leads to a
WARN().

The orientation property is known earlier. For example, some panels
parse the property through device tree during probe.

Add an API to return the property from panel to drm/kms driver, so the
drivers are able to call drm_connector_set_orientation_from_panel() before
drm_dev_register().

Suggested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
[dianders: removed space before tab]
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220609072722.3488207-2-hsinyi@chromium.org
drivers/gpu/drm/drm_connector.c
include/drm/drm_connector.h
include/drm/drm_panel.h

index 1c48d16..28ea0f8 100644 (file)
@@ -24,6 +24,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
+#include <drm/drm_panel.h>
 #include <drm/drm_utils.h>
 #include <drm/drm_print.h>
 #include <drm/drm_drv.h>
@@ -2320,6 +2321,9 @@ EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
  * It is allowed to call this function with a panel_orientation of
  * DRM_MODE_PANEL_ORIENTATION_UNKNOWN, in which case it is a no-op.
  *
+ * The function shouldn't be called in panel after drm is registered (i.e.
+ * drm_dev_register() is called in drm).
+ *
  * Returns:
  * Zero on success, negative errno on failure.
  */
@@ -2389,6 +2393,33 @@ int drm_connector_set_panel_orientation_with_quirk(
 }
 EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk);
 
+/**
+ * drm_connector_set_orientation_from_panel -
+ *     set the connector's panel_orientation from panel's callback.
+ * @connector: connector for which to init the panel-orientation property.
+ * @panel: panel that can provide orientation information.
+ *
+ * Drm drivers should call this function before drm_dev_register().
+ * Orientation is obtained from panel's .get_orientation() callback.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_set_orientation_from_panel(
+       struct drm_connector *connector,
+       struct drm_panel *panel)
+{
+       enum drm_panel_orientation orientation;
+
+       if (panel && panel->funcs && panel->funcs->get_orientation)
+               orientation = panel->funcs->get_orientation(panel);
+       else
+               orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+
+       return drm_connector_set_panel_orientation(connector, orientation);
+}
+EXPORT_SYMBOL(drm_connector_set_orientation_from_panel);
+
 static const struct drm_prop_enum_list privacy_screen_enum[] = {
        { PRIVACY_SCREEN_DISABLED,              "Disabled" },
        { PRIVACY_SCREEN_ENABLED,               "Enabled" },
index 3ac4bf8..94b422b 100644 (file)
@@ -38,6 +38,7 @@ struct drm_modeset_acquire_ctx;
 struct drm_device;
 struct drm_crtc;
 struct drm_encoder;
+struct drm_panel;
 struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
@@ -1802,6 +1803,9 @@ int drm_connector_set_panel_orientation_with_quirk(
        struct drm_connector *connector,
        enum drm_panel_orientation panel_orientation,
        int width, int height);
+int drm_connector_set_orientation_from_panel(
+       struct drm_connector *connector,
+       struct drm_panel *panel);
 int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
                                          int min, int max);
 void drm_connector_create_privacy_screen_properties(struct drm_connector *conn);
index d279ee4..3a27112 100644 (file)
@@ -117,6 +117,15 @@ struct drm_panel_funcs {
                         struct drm_connector *connector);
 
        /**
+        * @get_orientation:
+        *
+        * Return the panel orientation set by device tree or EDID.
+        *
+        * This function is optional.
+        */
+       enum drm_panel_orientation (*get_orientation)(struct drm_panel *panel);
+
+       /**
         * @get_timings:
         *
         * Copy display timings into the provided array and return