* [PATCH] drm/amd/display: add panel_power_savings sysfs entry to eDP connectors
@ 2024-01-26 22:22 Hamza Mahfooz
2024-01-26 22:34 ` Mario Limonciello
0 siblings, 1 reply; 3+ messages in thread
From: Hamza Mahfooz @ 2024-01-26 22:22 UTC (permalink / raw)
To: amd-gfx
Cc: Hamza Mahfooz, Mario Limonciello, Harry Wentland, Leo Li,
Rodrigo Siqueira, Alex Deucher, Christian König, Pan,
Xinhui, David Airlie, Daniel Vetter, Alex Hung,
Srinivasan Shanmugam, Wayne Lin, dri-devel, linux-kernel
We want programs besides the compositor to be able to enable or disable
panel power saving features. However, since they are currently only
configurable through DRM properties, that isn't possible. So, to remedy
that issue introduce a new "panel_power_savings" sysfs attribute.
Cc: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 59 +++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index cd98b3565178..b3fcd833015d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6534,6 +6534,58 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
return &new_state->base;
}
+static ssize_t panel_power_savings_show(struct device *device,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct drm_connector *connector = dev_get_drvdata(device);
+ struct drm_device *dev = connector->dev;
+ ssize_t val;
+
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+ val = to_dm_connector_state(connector->state)->abm_level;
+ drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+ return sysfs_emit(buf, "%lu\n", val);
+}
+
+static ssize_t panel_power_savings_store(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct drm_connector *connector = dev_get_drvdata(device);
+ struct drm_device *dev = connector->dev;
+ long val;
+ int ret;
+
+ ret = kstrtol(buf, 0, &val);
+
+ if (ret)
+ return ret;
+
+ if (val < 0 || val > 4)
+ return -EINVAL;
+
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+ to_dm_connector_state(connector->state)->abm_level = val ?:
+ ABM_LEVEL_IMMEDIATE_DISABLE;
+ drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(panel_power_savings);
+
+static struct attribute *amdgpu_attrs[] = {
+ &dev_attr_panel_power_savings.attr,
+ NULL
+};
+
+static const struct attribute_group amdgpu_group = {
+ .name = "amdgpu",
+ .attrs = amdgpu_attrs
+};
+
static int
amdgpu_dm_connector_late_register(struct drm_connector *connector)
{
@@ -6541,6 +6593,13 @@ amdgpu_dm_connector_late_register(struct drm_connector *connector)
to_amdgpu_dm_connector(connector);
int r;
+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ r = sysfs_create_group(&connector->kdev->kobj,
+ &amdgpu_group);
+ if (r)
+ return r;
+ }
+
amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] drm/amd/display: add panel_power_savings sysfs entry to eDP connectors
2024-01-26 22:22 [PATCH] drm/amd/display: add panel_power_savings sysfs entry to eDP connectors Hamza Mahfooz
@ 2024-01-26 22:34 ` Mario Limonciello
2024-01-28 5:38 ` Mario Limonciello
0 siblings, 1 reply; 3+ messages in thread
From: Mario Limonciello @ 2024-01-26 22:34 UTC (permalink / raw)
To: Hamza Mahfooz, amd-gfx
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, Pan, Xinhui, David Airlie, Daniel Vetter,
Alex Hung, Srinivasan Shanmugam, Wayne Lin, dri-devel,
linux-kernel
On 1/26/2024 16:22, Hamza Mahfooz wrote:
> We want programs besides the compositor to be able to enable or disable
> panel power saving features. However, since they are currently only
> configurable through DRM properties, that isn't possible. So, to remedy
> that issue introduce a new "panel_power_savings" sysfs attribute.
>
> Cc: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
> ---
> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 59 +++++++++++++++++++
> 1 file changed, 59 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index cd98b3565178..b3fcd833015d 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -6534,6 +6534,58 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
> return &new_state->base;
> }
>
> +static ssize_t panel_power_savings_show(struct device *device,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct drm_connector *connector = dev_get_drvdata(device);
> + struct drm_device *dev = connector->dev;
> + ssize_t val;
> +
> + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> + val = to_dm_connector_state(connector->state)->abm_level;
> + drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +
> + return sysfs_emit(buf, "%lu\n", val);
> +}
> +
> +static ssize_t panel_power_savings_store(struct device *device,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct drm_connector *connector = dev_get_drvdata(device);
> + struct drm_device *dev = connector->dev;
> + long val;
> + int ret;
> +
> + ret = kstrtol(buf, 0, &val);
> +
> + if (ret)
> + return ret;
> +
> + if (val < 0 || val > 4)
> + return -EINVAL;
> +
> + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
> + to_dm_connector_state(connector->state)->abm_level = val ?:
> + ABM_LEVEL_IMMEDIATE_DISABLE;
> + drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +
> + return count;
> +}
> +
To make this more discoverable I think you want some kerneldoc.
> +static DEVICE_ATTR_RW(panel_power_savings);
> +
> +static struct attribute *amdgpu_attrs[] = {
> + &dev_attr_panel_power_savings.attr,
> + NULL
> +};
> +
> +static const struct attribute_group amdgpu_group = {
> + .name = "amdgpu",
> + .attrs = amdgpu_attrs
> +};
> +
> static int
> amdgpu_dm_connector_late_register(struct drm_connector *connector)
> {
> @@ -6541,6 +6593,13 @@ amdgpu_dm_connector_late_register(struct drm_connector *connector)
> to_amdgpu_dm_connector(connector);
> int r;
>
> + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
> + r = sysfs_create_group(&connector->kdev->kobj,
> + &amdgpu_group);
> + if (r)
> + return r;
> + }
> +
I think there should be some matching code sysfs_remove_group(), maybe
in early_unregister() callback.
> amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
>
> if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] drm/amd/display: add panel_power_savings sysfs entry to eDP connectors
2024-01-26 22:34 ` Mario Limonciello
@ 2024-01-28 5:38 ` Mario Limonciello
0 siblings, 0 replies; 3+ messages in thread
From: Mario Limonciello @ 2024-01-28 5:38 UTC (permalink / raw)
To: Hamza Mahfooz, amd-gfx
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, Pan, Xinhui, David Airlie, Daniel Vetter,
Alex Hung, Srinivasan Shanmugam, Wayne Lin, dri-devel,
linux-kernel
On 1/26/2024 16:34, Mario Limonciello wrote:
> On 1/26/2024 16:22, Hamza Mahfooz wrote:
>> We want programs besides the compositor to be able to enable or disable
>> panel power saving features. However, since they are currently only
>> configurable through DRM properties, that isn't possible. So, to remedy
>> that issue introduce a new "panel_power_savings" sysfs attribute.
>>
>> Cc: Mario Limonciello <mario.limonciello@amd.com>
>> Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
>> ---
>> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 59 +++++++++++++++++++
>> 1 file changed, 59 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> index cd98b3565178..b3fcd833015d 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -6534,6 +6534,58 @@
>> amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector
>> *connector)
>> return &new_state->base;
>> }
>> +static ssize_t panel_power_savings_show(struct device *device,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct drm_connector *connector = dev_get_drvdata(device);
>> + struct drm_device *dev = connector->dev;
>> + ssize_t val;
>> +
>> + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
>> + val = to_dm_connector_state(connector->state)->abm_level;
>> + drm_modeset_unlock(&dev->mode_config.connection_mutex);
>> +
>> + return sysfs_emit(buf, "%lu\n", val);
When the system is first booted up with nothing on the kernel command
line, this emits the value for ABM_LEVEL_IMMEDIATE_DISABLE, which isn't
something we normally should be showing to people.
I think you should be special casing it similar to how the store special
case works.
>> +}
>> +
>> +static ssize_t panel_power_savings_store(struct device *device,
>> + struct device_attribute *attr,
>> + const char *buf, size_t count)
>> +{
>> + struct drm_connector *connector = dev_get_drvdata(device);
>> + struct drm_device *dev = connector->dev;
>> + long val;
>> + int ret;
>> +
>> + ret = kstrtol(buf, 0, &val);
>> +
>> + if (ret)
>> + return ret;
>> +
>> + if (val < 0 || val > 4)
>> + return -EINVAL;
>> +
>> + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
>> + to_dm_connector_state(connector->state)->abm_level = val ?:
>> + ABM_LEVEL_IMMEDIATE_DISABLE;
>> + drm_modeset_unlock(&dev->mode_config.connection_mutex);
>> +
It appears that the ABM doesn't actually take effect by writing this
value until the next modeset.
This is also reported by Dominik Förderer. I suggested he try to change
resolutions in his DE and that activated ABM.
So I think it's missing another call to flush out to the hardware.
>> + return count;
>> +}
>> +
>
> To make this more discoverable I think you want some kerneldoc.
>
>> +static DEVICE_ATTR_RW(panel_power_savings);
>> +
>> +static struct attribute *amdgpu_attrs[] = {
>> + &dev_attr_panel_power_savings.attr,
>> + NULL
>> +};
>> +
>> +static const struct attribute_group amdgpu_group = {
>> + .name = "amdgpu",
>> + .attrs = amdgpu_attrs
>> +};
>> +
>> static int
>> amdgpu_dm_connector_late_register(struct drm_connector *connector)
>> {
>> @@ -6541,6 +6593,13 @@ amdgpu_dm_connector_late_register(struct
>> drm_connector *connector)
>> to_amdgpu_dm_connector(connector);
>> int r;
>> + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
>> + r = sysfs_create_group(&connector->kdev->kobj,
>> + &amdgpu_group);
>> + if (r)
>> + return r;
>> + }
>> +
>
> I think there should be some matching code sysfs_remove_group(), maybe
> in early_unregister() callback.
>
>> amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
>> if ((connector->connector_type ==
>> DRM_MODE_CONNECTOR_DisplayPort) ||
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-01-28 5:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-26 22:22 [PATCH] drm/amd/display: add panel_power_savings sysfs entry to eDP connectors Hamza Mahfooz
2024-01-26 22:34 ` Mario Limonciello
2024-01-28 5:38 ` Mario Limonciello
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).