From: Alex Hung <[email protected]>

[WHAT]
Add KUnit tests for three EDID paths in amdgpu_dm_helpers.c the SDC
panel PSR PHY power-down quirk in apply_edid_quirks(), the HDMI
compliance-auto branch of dm_helpers_parse_edid_caps(), and the VBIOS
fallback and corrupt-EDID paths of dm_helpers_read_local_edid().

[HOW]
apply_edid_quirks() is driven twice with the SDC panel ids, once on a
DisplayPort signal and once on eDP, showing the quirk is embedded-only.

dm_helpers_parse_edid_caps() runs against an HDMI connector whose
hdmi_comp_auto flag is set, so the FRL and FRL DSC debug options are
forced on and the quirk is recorded in the panel patch.

dm_helpers_read_local_edid() is given an embedded link with no DDC
line, so it falls back to the EDID hardcoded in the VBIOS embedded
panel info that the existing fake dc_bios supplies. A second test
corrupts the base block checksum served by the fake AUX DDC, so the
read fails, the real checksum is written back and EDID_BAD_CHECKSUM is
reported.

Assisted-by: Copilot:Claude-Opus-5
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
Signed-off-by: George Zhang <[email protected]>
---
 .../amdgpu_dm/tests/amdgpu_dm_helpers_test.c  | 120 ++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git 
a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
index 51c3995de76d..b433634e0390 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
@@ -176,6 +176,34 @@ static void 
dm_test_apply_edid_quirks_disable_colorimetry(struct kunit *test)
        KUNIT_EXPECT_TRUE(test, edid_caps.panel_patch.disable_colorimetry);
 }
 
+/**
+ * dm_test_apply_edid_quirks_psr_phy_power_down - Test SDC PSR PHY power-down 
quirk
+ * @test: The KUnit test context
+ *
+ * The quirk is embedded-only, so an external signal leaves the debug option
+ * alone and an embedded one forces PHY power down/up level 2.
+ */
+static void dm_test_apply_edid_quirks_psr_phy_power_down(struct kunit *test)
+{
+       struct dc_edid_caps edid_caps = {0};
+       struct dc_link *link = dm_test_quirk_link(test);
+       struct dc *dc = dm_kunit_alloc_dc_with_ctx(test);
+       struct edid *external = dm_test_edid_with_panel_id(test,
+                       drm_edid_encode_panel_id('S', 'D', 'C', 0x4197));
+       struct edid *embedded = dm_test_edid_with_panel_id(test,
+                       drm_edid_encode_panel_id('S', 'D', 'C', 0x4203));
+
+       link->ctx = dc->ctx;
+
+       link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
+       apply_edid_quirks(link, external, &edid_caps);
+       KUNIT_EXPECT_FALSE(test, 
dc->debug.psr_phy_force_phy_power_down_up_level_2);
+
+       link->connector_signal = SIGNAL_TYPE_EDP;
+       apply_edid_quirks(link, embedded, &edid_caps);
+       KUNIT_EXPECT_TRUE(test, 
dc->debug.psr_phy_force_phy_power_down_up_level_2);
+}
+
 /**
  * dm_test_apply_edid_quirks_skip_phy_ssc - Test DEL 0x4147 PHY SSC quirk
  * @test: The KUnit test context
@@ -463,6 +491,40 @@ static void dm_test_parse_edid_caps_hdmi_frl_dsc(struct 
kunit *test)
        KUNIT_EXPECT_TRUE(test, edid_caps->frl_dsc_10bpc);
 }
 
+/**
+ * dm_test_parse_edid_caps_hdmi_comp_auto - Test the HDMI compliance-auto 
branch
+ * @test: The KUnit test context
+ *
+ * A connector flagged for automated HDMI compliance forces the FRL and FRL DSC
+ * debug options on and records the quirk in the panel patch.
+ */
+static void dm_test_parse_edid_caps_hdmi_comp_auto(struct kunit *test)
+{
+       struct dc_link *link = dm_test_quirk_link(test);
+       struct amdgpu_dm_connector *aconnector = link->priv;
+       struct dc *dc = dm_kunit_alloc_dc_with_ctx(test);
+       struct dc_edid_caps *edid_caps;
+       struct dc_edid *dc_edid;
+
+       dc_edid = kunit_kzalloc(test, sizeof(*dc_edid), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, dc_edid);
+       edid_caps = kunit_kzalloc(test, sizeof(*edid_caps), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, edid_caps);
+
+       link->dc = dc;
+       link->ctx = dc->ctx;
+
+       dm_test_fill_base_edid(dc_edid, true);
+
+       aconnector->base.display_info.is_hdmi = true;
+       aconnector->hdmi_comp_auto = true;
+
+       KUNIT_EXPECT_EQ(test, dm_helpers_parse_edid_caps(link, dc_edid, 
edid_caps), EDID_OK);
+       KUNIT_EXPECT_TRUE(test, edid_caps->panel_patch.hdmi_comp_auto);
+       KUNIT_EXPECT_TRUE(test, dc->debug.force_frl_max);
+       KUNIT_EXPECT_TRUE(test, dc->debug.force_frl_dsc);
+}
+
 /*
  * Build a 2-block EDID: a valid base block plus a CTA-861 extension block
  * carrying one LPCM Short Audio Descriptor and, when @with_speaker is set, a
@@ -4570,6 +4632,60 @@ static void 
dm_test_read_local_edid_i2c_no_response(struct kunit *test)
        KUNIT_EXPECT_EQ(test, dm_test_prepare_ddc_calls, 1U);
 }
 
+/**
+ * dm_test_read_local_edid_vbios_embedded - Test the VBIOS hardcoded EDID path
+ * @test: The KUnit test context
+ *
+ * An embedded panel with no DDC line has no I2C adapter to read from, so the
+ * helper falls back to the EDID hardcoded in the VBIOS embedded panel info.
+ */
+static void dm_test_read_local_edid_vbios_embedded(struct kunit *test)
+{
+       struct dm_test_local_edid fixture = dm_test_setup_local_edid(test);
+       struct dm_test_vbios_edid *vbios;
+
+       vbios = kunit_kzalloc(test, sizeof(*vbios), GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, vbios);
+
+       vbios->bios.funcs = &dm_test_vbios_edid_funcs;
+       vbios->result = BP_RESULT_OK;
+       /* the fixture already holds a valid base EDID */
+       vbios->fake_edid = fixture.aux->edid;
+       vbios->fake_edid_size = EDID_LENGTH;
+
+       fixture.ctx->dc_bios = &vbios->bios;
+       fixture.link->ctx = fixture.ctx;
+       fixture.link->aux_mode = false;
+       fixture.link->ddc_hw_inst = GPIO_DDC_LINE_UNKNOWN;
+       fixture.link->connector_signal = SIGNAL_TYPE_EDP;
+
+       KUNIT_EXPECT_EQ(test,
+                       dm_helpers_read_local_edid(fixture.ctx, fixture.link, 
fixture.sink),
+                       EDID_OK);
+       KUNIT_EXPECT_EQ(test, fixture.sink->dc_edid.length, 
(uint32_t)EDID_LENGTH);
+       KUNIT_EXPECT_EQ(test, fixture.sink->edid_caps.manufacturer_id, 0xAC10);
+}
+
+/**
+ * dm_test_read_local_edid_corrupt_checksum - Test the corrupt-EDID compliance 
path
+ * @test: The KUnit test context
+ *
+ * The sink serves an EDID with a bad checksum, so the DDC read fails and marks
+ * the connector's EDID corrupt. The helper writes the real checksum back over
+ * AUX, clears the corrupt flag and reports EDID_BAD_CHECKSUM.
+ */
+static void dm_test_read_local_edid_corrupt_checksum(struct kunit *test)
+{
+       struct dm_test_local_edid fixture = dm_test_setup_local_edid(test);
+
+       fixture.aux->edid[EDID_LENGTH - 1] ^= 0xFF;
+
+       KUNIT_EXPECT_EQ(test,
+                       dm_helpers_read_local_edid(fixture.ctx, fixture.link, 
fixture.sink),
+                       EDID_BAD_CHECKSUM);
+       KUNIT_EXPECT_FALSE(test, fixture.aconnector->base.edid_corrupt);
+}
+
 static struct kunit_case amdgpu_dm_helpers_test_cases[] = {
        /* edid_extract_panel_id */
        KUNIT_CASE(dm_test_edid_extract_panel_id_basic),
@@ -4579,6 +4695,7 @@ static struct kunit_case amdgpu_dm_helpers_test_cases[] = 
{
        KUNIT_CASE(dm_test_apply_edid_quirks_disable_fams),
        KUNIT_CASE(dm_test_apply_edid_quirks_remove_sink_ext_caps),
        KUNIT_CASE(dm_test_apply_edid_quirks_disable_colorimetry),
+       KUNIT_CASE(dm_test_apply_edid_quirks_psr_phy_power_down),
        KUNIT_CASE(dm_test_apply_edid_quirks_skip_phy_ssc),
        KUNIT_CASE(dm_test_apply_edid_quirks_force_freesync_min),
        KUNIT_CASE(dm_test_apply_edid_quirks_unknown_noop),
@@ -4591,6 +4708,7 @@ static struct kunit_case amdgpu_dm_helpers_test_cases[] = 
{
        KUNIT_CASE(dm_test_parse_edid_caps_bad_checksum),
        KUNIT_CASE(dm_test_parse_edid_caps_hdmi_frl),
        KUNIT_CASE(dm_test_parse_edid_caps_hdmi_frl_dsc),
+       KUNIT_CASE(dm_test_parse_edid_caps_hdmi_comp_auto),
        KUNIT_CASE(dm_test_parse_edid_caps_cea_audio),
        KUNIT_CASE(dm_test_parse_edid_caps_cea_no_speaker),
        /* ACPI / VBIOS / local EDID readers */
@@ -4774,6 +4892,8 @@ static struct kunit_case amdgpu_dm_helpers_test_cases[] = 
{
        KUNIT_CASE(dm_test_read_local_edid_aux_mode),
        KUNIT_CASE(dm_test_read_local_edid_test_request),
        KUNIT_CASE(dm_test_read_local_edid_i2c_no_response),
+       KUNIT_CASE(dm_test_read_local_edid_vbios_embedded),
+       KUNIT_CASE(dm_test_read_local_edid_corrupt_checksum),
        {}
 };
 
-- 
2.55.0

Reply via email to