drm/amd/display: Add CACP ACE curve area debugfs for IGT validation

[Why]
IGT test cases for CACP need a way to validate that the ACE
(Adaptive Contrast Enhancement) curve responds to the CACP
aggression level. No interface exists to read the resulting
curve back from firmware for automated validation.

[How]
Add a read-only "cacp_ace_curve_area" debugfs node on eDP
connectors that support CACP. It issues a
DMUB_CMD__CACP_GET_ACE_CURVE_AREA command and reports the area
under the ACE PWL curve returned by firmware, which is directly
comparable across CACP levels, so IGT tests can query it per panel.

Reviewed-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com>
Signed-off-by: James Lin <pinglei.lin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Chenyu Chen 2026-06-25 18:53:21 +08:00 committed by Alex Deucher
parent f1c8dd4e74
commit 5ea44e1347

View File

@ -3677,6 +3677,72 @@ DEFINE_DEBUGFS_ATTRIBUTE(ips_residency_cntl_fops, ips_residency_cntl_get,
DEFINE_SHOW_ATTRIBUTE(current_backlight);
DEFINE_SHOW_ATTRIBUTE(target_backlight);
/*
* CACP ACE curve area. Read only.
* Returns the area under the ACE PWL curve computed by DMUB firmware on
* eDP panels that support CACP. The value is in DMU-internal units (PWL
* area); it is only meaningful for relative comparison between CACP
* levels on the same panel. Level 0 returns the linear baseline (largest).
*
* Example usage: cat /sys/kernel/debug/dri/0/eDP-1/cacp_ace_curve_area
*/
static int cacp_ace_curve_area_show(struct seq_file *m, void *unused)
{
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
struct dc_link *link = aconnector->dc_link;
struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev);
struct dc *dc;
union dmub_rb_cmd cmd;
unsigned int panel_inst = 0;
bool reallow_idle = false;
int ret = 0;
if (!link || link->type == dc_connection_none)
return -ENODEV;
if (!(link->connector_signal & SIGNAL_TYPE_EDP))
return -ENODEV;
if (!link->panel_config.cacp.cacp_supported)
return -EOPNOTSUPP;
dc = link->ctx->dc;
if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
return -EINVAL;
memset(&cmd, 0, sizeof(cmd));
cmd.cacp_get_ace_curve_area.header.type = DMUB_CMD__CACP;
cmd.cacp_get_ace_curve_area.header.sub_type = DMUB_CMD__CACP_GET_ACE_CURVE_AREA;
cmd.cacp_get_ace_curve_area.header.payload_bytes =
sizeof(cmd.cacp_get_ace_curve_area) -
sizeof(cmd.cacp_get_ace_curve_area.header);
cmd.cacp_get_ace_curve_area.data.in.panel_inst = panel_inst;
mutex_lock(&adev->dm.dc_lock);
if (dc->idle_optimizations_allowed) {
dc_allow_idle_optimizations(dc, false);
reallow_idle = true;
}
if (!dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd,
DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) ||
cmd.cacp_get_ace_curve_area.header.ret_status)
ret = -EIO;
else
seq_printf(m, "%u\n", cmd.cacp_get_ace_curve_area.data.out.area);
if (reallow_idle)
dc_allow_idle_optimizations(dc, true);
mutex_unlock(&adev->dm.dc_lock);
return ret;
}
DEFINE_SHOW_ATTRIBUTE(cacp_ace_curve_area);
DEFINE_SHOW_ATTRIBUTE(ips_status);
DEFINE_SHOW_ATTRIBUTE(ips_residency);
@ -3877,6 +3943,8 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector)
&disallow_edp_enter_psr_fops);
debugfs_create_file("disallow_edp_enter_replay", 0644, dir, connector,
&disallow_edp_enter_replay_fops);
debugfs_create_file("cacp_ace_curve_area", 0444, dir, connector,
&cacp_ace_curve_area_fops);
}
for (i = 0; i < ARRAY_SIZE(connector_debugfs_entries); i++) {