Expose min_vfreq and max_vfreq in DRM without using DebugFS.

Jackson McNeill jacksonmcneill01 at gmail.com
Fri Jan 5 18:02:02 UTC 2024


Hello,

I'm currently trying to patch the DRM system to expose min_vfreq and max_vfreq.
This is useful information for game engines. I am trying to expose it
to SDL3: https://github.com/libsdl-org/SDL/issues/8772

I am aware of the DebugFS implementation however this requires debugFS and root.
>From my naive position, it seems like the properties system is the
appropriate place(?), however I'm not sure where to go from here.

This would be my first kernel patch. I'm not exactly sure how to test
it either, especially since it would need to be a bare-metal test.

Current patch:

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
index 133af994a..0fce6fb60 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h
@@ -177,6 +177,8 @@ TRACE_EVENT(amdgpu_dm_crtc_atomic_check,
                  __field(bool, no_vblank)
                  __field(bool, async_flip)
                  __field(bool, vrr_enabled)
+                 __field(u32, vrr_min_vfreq)
+                 __field(u32, vrr_max_vfreq)
                  __field(bool, self_refresh_active)
                  __field(u32, plane_mask)
                  __field(u32, connector_mask)
@@ -199,6 +201,8 @@ TRACE_EVENT(amdgpu_dm_crtc_atomic_check,
                __entry->no_vblank = state->no_vblank;
                __entry->async_flip = state->async_flip;
                __entry->vrr_enabled = state->vrr_enabled;
+               __entry->vrr_min_vfreq = state->vrr_min_vfreq;
+               __entry->vrr_max_vfreq = state->vrr_max_vfreq;
                __entry->self_refresh_active = state->self_refresh_active;
                __entry->plane_mask = state->plane_mask;
                __entry->connector_mask = state->connector_mask;
@@ -207,7 +211,7 @@ TRACE_EVENT(amdgpu_dm_crtc_atomic_check,

         TP_printk("crtc_id=%u crtc_state=%p state=%p commit=%p changed("
               "planes=%d mode=%d active=%d conn=%d zpos=%d color_mgmt=%d) "
-              "state(enable=%d active=%d async_flip=%d vrr_enabled=%d "
+              "state(enable=%d active=%d async_flip=%d vrr_enabled=%d
vrr_min_vfreq=%d vrr_max_vfreq=%d "
               "self_refresh_active=%d no_vblank=%d) mask(plane=%x conn=%x "
               "enc=%x)",
               __entry->crtc_id, __entry->crtc_state, __entry->state,
@@ -215,7 +219,7 @@ TRACE_EVENT(amdgpu_dm_crtc_atomic_check,
               __entry->mode_changed, __entry->active_changed,
               __entry->connectors_changed, __entry->zpos_changed,
               __entry->color_mgmt_changed, __entry->enable, __entry->active,
-              __entry->async_flip, __entry->vrr_enabled,
+              __entry->async_flip, __entry->vrr_enabled,
__entry->vrr_min_vfreq, __entry->vrr_max_vfreq,
               __entry->self_refresh_active, __entry->no_vblank,
               __entry->plane_mask, __entry->connector_mask,
               __entry->encoder_mask)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c
b/drivers/gpu/drm/drm_atomic_uapi.c
index 98d3b10c0..28ebd8d02 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -423,6 +423,10 @@ static int drm_atomic_crtc_set_property(struct
drm_crtc *crtc,
         return ret;
     } else if (property == config->prop_vrr_enabled) {
         state->vrr_enabled = val;
+    } else if (property == config->prop_vrr_min_vfreq) {
+        state->vrr_min_vfreq = val;
+    } else if (property == config->prop_vrr_max_vfreq) {
+        state->vrr_max_vfreq = val;
     } else if (property == config->degamma_lut_property) {
         ret = drm_atomic_replace_property_blob_from_id(dev,
                     &state->degamma_lut,
@@ -486,6 +490,10 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
         *val = (state->mode_blob) ? state->mode_blob->base.id : 0;
     else if (property == config->prop_vrr_enabled)
         *val = state->vrr_enabled;
+    else if (property == config->prop_vrr_min_vfreq)
+        *val = state->vrr_min_vfreq;
+    else if (property == config->prop_vrr_max_vfreq)
+        *val = state->vrr_max_vfreq;
     else if (property == config->degamma_lut_property)
         *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
     else if (property == config->ctm_property)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index cb90e70d8..4b5751ccf 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -316,6 +316,10 @@ static int __drm_crtc_init_with_planes(struct
drm_device *dev, struct drm_crtc *
                        config->prop_out_fence_ptr, 0);
         drm_object_attach_property(&crtc->base,
                        config->prop_vrr_enabled, 0);
+        drm_object_attach_property(&crtc->base,
+                       config->prop_vrr_min_vfreq, 0);
+        drm_object_attach_property(&crtc->base,
+                       config->prop_vrr_max_vfreq, 0);
     }

     return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c
b/drivers/gpu/drm/drm_mode_config.c
index 8525ef851..9659177e5 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -330,6 +330,18 @@ static int
drm_mode_create_standard_properties(struct drm_device *dev)
         return -ENOMEM;
     dev->mode_config.prop_vrr_enabled = prop;

+    prop = drm_property_create_bool(dev, 0,
+            "VRR_MIN_VFREQ");
+    if (!prop)
+        return -ENOMEM;
+    dev->mode_config.prop_vrr_min_vfreq = prop;
+
+    prop = drm_property_create_bool(dev, 0,
+            "VRR_MAX_VFREQ");
+    if (!prop)
+        return -ENOMEM;
+    dev->mode_config.prop_vrr_max_vfreq = prop;
+
     prop = drm_property_create(dev,
             DRM_MODE_PROP_BLOB,
             "DEGAMMA_LUT", 0);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 8b48a1974..290ff4e04 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -298,6 +298,20 @@ struct drm_crtc_state {
      * hardware capabiltiy - lacking support is not treated as failure.
      */
     bool vrr_enabled;
+
+    /**
+     * @vrr_min_vfreq:
+     *
+     * STUB COMMENT
+     */
+    u32 min_vrfreq;
+
+    /**
+     * @vrr_max_vfreq:
+     *
+     * STUB COMMENT
+     */
+    u32 max_vrfreq;

     /**
      * @self_refresh_active:
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 973119a91..09bf7d622 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -685,6 +685,16 @@ struct drm_mode_config {
      */
     struct drm_property *prop_vrr_enabled;

+    /**
+     * @prop_vrr_min_vfreq: STUB COMMENT
+     */
+    struct drm_property *prop_vrr_min_vfreq;
+
+    /**
+     * @prop_vrr_max_vfreq: STUB COMMENT
+     */
+    struct drm_property *prop_vrr_max_vfreq;
+
     /**
      * @dvi_i_subconnector_property: Optional DVI-I property to
      * differentiate between analog or digital mode.
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index 912f1e415..5e75b5193 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -60,7 +60,7 @@ struct drm_mode_object {
     void (*free_cb)(struct kref *kref);
 };

-#define DRM_OBJECT_MAX_PROPERTY 24
+#define DRM_OBJECT_MAX_PROPERTY 26
 /**
  * struct drm_object_properties - property tracking for &drm_mode_object
  */


More information about the dri-devel mailing list