diff --git a/drivers/gpu/drm/apple/afk.c b/drivers/gpu/drm/apple/afk.c index a5c271254437..4ea4e00f0a45 100644 --- a/drivers/gpu/drm/apple/afk.c +++ b/drivers/gpu/drm/apple/afk.c @@ -1561,11 +1561,16 @@ static void afk_recv_handle_init(struct apple_dcp_afkep *ep, u32 channel, (ep->dcp->fw_compat == DCP_FIRMWARE_H17P || ep->dcp->fw_compat == DCP_FIRMWARE_V_27_0), ep->dcp->fw_compat == DCP_FIRMWARE_V_27_0); if (ret == -ENOENT && - ep->dcp->hw.iomfb_method_profile == DCP_IOMFB_METHODS_H17G) { + (ep->dcp->hw.iomfb_method_profile == DCP_IOMFB_METHODS_H17G || + (ep->dcp->fw_compat == DCP_FIRMWARE_V_27_0 && + ep->dcp->hw.firmware_compat == DCP_FIRMWARE_H17P))) { /* * M5 (H17G) announces powerlog-service with only - * ep-has-desc-mgr and interface-id; match it by the - * announced name, as for props-less announces. + * ep-has-desc-mgr and interface-id, on 26.x and on + * firmware 27 alike (the T8142, an H17P-generation + * processor, is the one that runs firmware 27); match + * it by the announced name, as for props-less + * announces. */ epic_name = NULL; epic_class = NULL; diff --git a/drivers/gpu/drm/apple/dcp_backlight.c b/drivers/gpu/drm/apple/dcp_backlight.c index 00f29157241f..c029cca6d300 100644 --- a/drivers/gpu/drm/apple/dcp_backlight.c +++ b/drivers/gpu/drm/apple/dcp_backlight.c @@ -429,9 +429,16 @@ int dcp_backlight_prepare(struct apple_dcp *dcp, bool have_surface, spin_lock_irqsave(&dcp->backlight.lock, flags); ret = dcp_bl_prepare(&dcp->backlight.state, have_surface, present); - /* No reservation: carry the last completed level on an ordinary present. */ - if (ret == -EALREADY) + /* + * No reservation: carry the last completed level on an ordinary + * present, and on one without a surface, which cannot apply a new + * level. A pending level waits for the next present with a surface. + */ + if (ret == -EALREADY || + (ret == -ENODATA && !have_surface && dcp->backlight.state.ready)) { present->nits = dcp->backlight.state.actual; + ret = -EALREADY; + } spin_unlock_irqrestore(&dcp->backlight.lock, flags); return ret; } diff --git a/drivers/gpu/drm/apple/iomfb_v14_7_backlight_test.c b/drivers/gpu/drm/apple/iomfb_v14_7_backlight_test.c index 3c1fc2f45d53..a84e45338793 100644 --- a/drivers/gpu/drm/apple/iomfb_v14_7_backlight_test.c +++ b/drivers/gpu/drm/apple/iomfb_v14_7_backlight_test.c @@ -554,6 +554,25 @@ static void v14_bl_t6030_work(struct kunit *test) KUNIT_EXPECT_TRUE(test, dcp_backlight_pending(f.dcp)); } +/* + * A present without a surface cannot apply a new level: it carries the last + * completed one and reserves nothing, so it is still sent, and the request + * waits for the next present with a surface. + */ +static void v14_bl_surfaceless_present(struct kunit *test) +{ + struct v14_bl_fixture f = v14_bl_fixture(test, &dcp_v14_board_t6030, true); + struct dcp_backlight_present p = { .nits = U32_MAX }; + + v14_bl_request(test, f.dcp, 250); + KUNIT_EXPECT_EQ(test, dcp_backlight_prepare(f.dcp, false, &p), -EALREADY); + KUNIT_EXPECT_EQ(test, p.nits, DCP_V14_NITS_DEFAULT); + KUNIT_EXPECT_TRUE(test, f.dcp->backlight.state.dirty); + KUNIT_EXPECT_FALSE(test, f.dcp->backlight.state.in_flight); + KUNIT_ASSERT_EQ(test, dcp_backlight_prepare(f.dcp, true, &p), 0); + KUNIT_EXPECT_EQ(test, p.nits, 250U); +} + static struct kunit_case v14_backlight_cases[] = { KUNIT_CASE(v14_bl_binary64), KUNIT_CASE(v14_bl_level_block), @@ -562,6 +581,7 @@ static struct kunit_case v14_backlight_cases[] = { KUNIT_CASE(v14_bl_gate_transitions), KUNIT_CASE(v14_bl_plan), KUNIT_CASE(v14_bl_policy), + KUNIT_CASE(v14_bl_surfaceless_present), KUNIT_CASE(v14_bl_other_boards_untouched), KUNIT_CASE(v14_bl_external_untouched), KUNIT_CASE(v14_bl_t6030_swap_levels), diff --git a/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py b/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py index 522740ab2bd3..602cf729aea4 100644 --- a/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py +++ b/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py @@ -98,7 +98,7 @@ def function(file,signature): struct apple_dcp { void *dev;int fw_compat;struct apple_dcp_afkep *dcpavservep;struct apple_connector *connector; bool external_physically_absent,hpd_mutex,quiescing,typec_cable_connected;u64 typec_generation;unsigned int nr_modes; - struct { int iomfb_method_profile; bool fw_14_7_endpoints; unsigned int num_dptx_ports; } hw; bool ext_dead,external_native; + struct { int iomfb_method_profile,firmware_compat; bool fw_14_7_endpoints; unsigned int num_dptx_ports; } hw; bool ext_dead,external_native; struct { bool lock,enabled;u64 epoch;int enable_completion;struct apple_epic_service *service,*opened; u64 opened_epoch,close_gen,terminated_epoch,close_epoch;bool opening;struct work_struct close_wq; } dcpavserv; };