From: "Cheng, Tony" <[email protected]>

DMs still call dc_hardware_init and dc_hardware_release while Core 2
lands next to legacy. Those entry points live in dc/dc_api_dispatch:
LEGACY calls the old bodies directly, CORE2 uses core2_funcs. dc_create
allocates struct dc2 and returns the inner dc (TO_DC2). The shim only
records selection; dc_construct still constructs Core2. No dispatch
fields on public struct dc, and no architect spec edits.

TO_DC2 is a typed upcast (struct dc is the first member of struct dc2).
Shim headers are included for UNIT_TEST as well as production so TO_DC2
is defined when core_gtest compiles dc.c.

Assisted-by: Cursor:cursor
Signed-off-by: Cheng, Tony <[email protected]>
Signed-off-by: Fangzhi Zuo <[email protected]>
Reviewed-by: Jun Lei <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/Makefile       |  3 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 30 ++++++++++++----
 .../drm/amd/display/dc/core2/CMakeLists.txt   | 10 ++++++
 .../gpu/drm/amd/display/dc/core2/dc_core2.c   | 34 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/core2/dc_core2.h   | 19 +++++++++++
 .../drm/amd/display/dc/core2/dc_core2_init.c  | 13 +++++++
 .../drm/amd/display/dc/core2/dc_core2_init.h  | 10 ++++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  2 ++
 .../display/dc/dc_api_dispatch/CMakeLists.txt |  9 +++++
 .../amd/display/dc/dc_api_dispatch/api_shim.c | 32 +++++++++++++++++
 .../amd/display/dc/dc_api_dispatch/api_shim.h | 19 +++++++++++
 .../amd/display/dc/inc/dc_core_interface.h    | 31 +++++++++++++++++
 12 files changed, 206 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/core2/CMakeLists.txt
 create mode 100644 drivers/gpu/drm/amd/display/dc/core2/dc_core2.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/core2/dc_core2.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.h
 create mode 100644 
drivers/gpu/drm/amd/display/dc/dc_api_dispatch/CMakeLists.txt
 create mode 100644 drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/inc/dc_core_interface.h

diff --git a/drivers/gpu/drm/amd/display/dc/Makefile 
b/drivers/gpu/drm/amd/display/dc/Makefile
index 99aa8f75de7b..f868999515dd 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -69,6 +69,7 @@ FILES += dc_fused_io.o
 FILES += dc_helper.o
 FILES += dc_memory_pool.o
 FILES += core/dc.o
+FILES += dc_api_dispatch/api_shim.o
 FILES += core/dc_debug.o
 FILES += core/dc_hw_sequencer.o
 FILES += core/dc_link_enc_cfg.o
@@ -80,6 +81,8 @@ FILES += core/dc_state.o
 FILES += core/dc_stream.o
 FILES += core/dc_surface.o
 FILES += core/dc_vm_helper.o
+FILES += core2/dc_core2.o
+FILES += core2/dc_core2_init.o
 
 AMD_DISPLAY_FILES += $(addprefix $(AMDDALPATH)/dc/, $(FILES))
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 369569e3b701..17db12fe8022 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -90,6 +90,8 @@
 #endif
 
 #include "dce/dmub_outbox.h"
+#include "dc_api_dispatch/api_shim.h"
+#include "core2/dc_core2.h"
 
 #define CTX \
        dc->ctx
@@ -982,6 +984,8 @@ static void dc_destruct(struct dc *dc)
        kfree(dc->vm_helper);
        dc->vm_helper = NULL;
 
+       if (TO_DC2(dc)->selection == DC2_SELECTION_CORE2)
+               core2_destruct(dc);
 }
 
 static bool dc_construct_ctx(struct dc *dc,
@@ -1179,6 +1183,10 @@ static bool dc_construct(struct dc *dc,
                goto fail;
        }
 
+       api_shim_construct(dc, init_params);
+       if (TO_DC2(dc)->selection == DC2_SELECTION_CORE2)
+               core2_construct(dc);
+
        return true;
 
 fail:
@@ -1565,7 +1573,8 @@ static void disable_vbios_mode_if_required(
 
 struct dc *dc_create(const struct dc_init_data *init_params)
 {
-       struct dc *dc = kvzalloc_obj(*dc);
+       struct dc2 *dc2 = kvzalloc_obj(*dc2);
+       struct dc *dc = dc2 ? &dc2->dc : NULL;
        unsigned int full_pipe_count;
 
        if (!dc)
@@ -1613,7 +1622,7 @@ struct dc *dc_create(const struct dc_init_data 
*init_params)
 
 destruct_dc:
        dc_destruct(dc);
-       kvfree(dc);
+       kvfree(TO_DC2(dc));
        return NULL;
 }
 
@@ -1639,7 +1648,7 @@ static void detect_edp_presence(struct dc *dc)
        }
 }
 
-void dc_hardware_init(struct dc *dc)
+void legacy_hardware_init(struct dc *dc)
 {
 
        detect_edp_presence(dc);
@@ -1662,7 +1671,7 @@ void dc_deinit_callbacks(struct dc *dc)
 void dc_destroy(struct dc **dc)
 {
        dc_destruct(*dc);
-       kvfree(*dc);
+       kvfree(TO_DC2(*dc));
        *dc = NULL;
 }
 
@@ -6676,8 +6685,7 @@ bool dc_is_plane_eligible_for_idle_optimizations(struct 
dc *dc,
        return false;
 }
 
-/* cleanup on driver unload */
-void dc_hardware_release(struct dc *dc)
+void legacy_hardware_release(struct dc *dc)
 {
        dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(dc);
 
@@ -6685,6 +6693,16 @@ void dc_hardware_release(struct dc *dc)
                dc->hwss.hardware_release(dc);
 }
 
+static const struct dc2_funcs dc2_legacy_funcs_table = {
+       .hardware_init = legacy_hardware_init,
+       .hardware_release = legacy_hardware_release,
+};
+
+const struct dc2_funcs *dc2_legacy_funcs(void)
+{
+       return &dc2_legacy_funcs_table;
+}
+
 void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)
 {
        if (dc->current_state)
diff --git a/drivers/gpu/drm/amd/display/dc/core2/CMakeLists.txt 
b/drivers/gpu/drm/amd/display/dc/core2/CMakeLists.txt
new file mode 100644
index 000000000000..c20602c351b5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/core2/CMakeLists.txt
@@ -0,0 +1,10 @@
+#
+# @file  CMakeLists.txt
+# @brief Core 2 sources. Subdirectory files are listed relative to this dir.
+# @copyright Copyright © 2026 Advanced Micro Devices, Inc. All rights reserved.
+#
+
+dal3_subdirectory_sources(
+  dc_core2.c
+  dc_core2_init.c
+  )
diff --git a/drivers/gpu/drm/amd/display/dc/core2/dc_core2.c 
b/drivers/gpu/drm/amd/display/dc/core2/dc_core2.c
new file mode 100644
index 000000000000..f496e4d66575
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/core2/dc_core2.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#include "dm_services.h"
+#include "dc.h"
+#include "core2/dc_core2.h"
+#include "core2/dc_core2_init.h"
+
+static void core2_hardware_release(struct dc *dc)
+{
+       dc2_legacy_funcs()->hardware_release(dc);
+}
+
+static const struct dc2_funcs core2_funcs_table = {
+       .hardware_init = core2_hardware_init,
+       .hardware_release = core2_hardware_release,
+};
+
+const struct dc2_funcs *core2_funcs(void)
+{
+       return &core2_funcs_table;
+}
+
+void core2_construct(struct dc *dc)
+{
+       (void)dc;
+}
+
+void core2_destruct(struct dc *dc)
+{
+       (void)dc;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/core2/dc_core2.h 
b/drivers/gpu/drm/amd/display/dc/core2/dc_core2.h
new file mode 100644
index 000000000000..a761e85a9973
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/core2/dc_core2.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#pragma once
+
+#include "inc/dc_core_interface.h"
+
+struct dc;
+
+struct dc_core2 {
+       const struct dc2_funcs *legacy_funcs;
+};
+
+/* Core2-local; selection lives in the API shim, not here. */
+const struct dc2_funcs *core2_funcs(void);
+void core2_construct(struct dc *dc);
+void core2_destruct(struct dc *dc);
diff --git a/drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.c 
b/drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.c
new file mode 100644
index 000000000000..d4777cdbd569
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#include "dm_services.h"
+#include "dc.h"
+#include "core2/dc_core2_init.h"
+
+void core2_hardware_init(struct dc *dc)
+{
+       dc2_legacy_funcs()->hardware_init(dc);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.h 
b/drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.h
new file mode 100644
index 000000000000..a4fa0365cd4f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/core2/dc_core2_init.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#pragma once
+
+struct dc;
+
+void core2_hardware_init(struct dc *dc);
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index c8e6e949ce79..9c8e55715e47 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -51,6 +51,7 @@
 #include "dml/dml1_frl_cap_chk.h"
 
 #include "sspl/dc_spl_types.h"
+#include "inc/dc_core_interface.h"
 
 struct abm_save_restore;
 
@@ -1389,6 +1390,7 @@ struct dc_init_data {
        uint32_t *nbio_reg_offsets;
        uint32_t *clk_reg_offsets;
        void *bb_from_dmub;
+       enum dc2_selection dc2_selection;
 };
 
 struct dc_callback_init {
diff --git a/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/CMakeLists.txt 
b/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/CMakeLists.txt
new file mode 100644
index 000000000000..1654558a844d
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/CMakeLists.txt
@@ -0,0 +1,9 @@
+#
+# @file  CMakeLists.txt
+# @brief DC API dispatch / public shim. Subdirectory files are listed relative 
to this dir.
+# @copyright Copyright © 2026 Advanced Micro Devices, Inc. All rights reserved.
+#
+
+dal3_subdirectory_sources(
+  api_shim.c
+  )
diff --git a/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.c 
b/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.c
new file mode 100644
index 000000000000..3dcfde8308c5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#include "dm_services.h"
+#include "dc.h"
+#include "dc_api_dispatch/api_shim.h"
+#include "core2/dc_core2.h"
+#include "inc/dc_core_interface.h"
+
+void api_shim_construct(struct dc *dc, const struct dc_init_data *init_params)
+{
+       /* DM override today; ASIC allow-list later. Owned only by this shim. */
+       TO_DC2(dc)->selection = init_params->dc2_selection;
+}
+
+void dc_hardware_init(struct dc *dc)
+{
+       if (TO_DC2(dc)->selection == DC2_SELECTION_CORE2)
+               core2_funcs()->hardware_init(dc);
+       else
+               legacy_hardware_init(dc);
+}
+
+void dc_hardware_release(struct dc *dc)
+{
+       if (TO_DC2(dc)->selection == DC2_SELECTION_CORE2)
+               core2_funcs()->hardware_release(dc);
+       else
+               legacy_hardware_release(dc);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.h 
b/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.h
new file mode 100644
index 000000000000..fee03a5dd596
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dc_api_dispatch/api_shim.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#pragma once
+
+#include "dc.h"
+#include "inc/dc_core_interface.h"
+
+struct dc2 {
+       /* First member: TO_DC2 is a typed upcast, not container_of. */
+       struct dc dc;
+       enum dc2_selection selection;
+};
+
+#define TO_DC2(ptr) ((struct dc2 *)(ptr))
+
+void api_shim_construct(struct dc *dc, const struct dc_init_data *init_params);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_core_interface.h 
b/drivers/gpu/drm/amd/display/dc/inc/dc_core_interface.h
new file mode 100644
index 000000000000..35a6218c1285
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_core_interface.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#pragma once
+
+struct dc;
+
+/*
+ * Construction-time Core implementation selection. Zero is LEGACY so existing
+ * callers that leave dc uninitialized keep production behavior.
+ */
+enum dc2_selection {
+       DC2_SELECTION_LEGACY = 0,
+       DC2_SELECTION_CORE2,
+};
+
+enum dc2_hw_ownership {
+       DC2_HW_OWNERSHIP_RELEASED = 0,
+       DC2_HW_OWNERSHIP_OWNED,
+};
+
+struct dc2_funcs {
+       void (*hardware_init)(struct dc *dc);
+       void (*hardware_release)(struct dc *dc);
+};
+
+void legacy_hardware_init(struct dc *dc);
+void legacy_hardware_release(struct dc *dc);
+const struct dc2_funcs *dc2_legacy_funcs(void);
-- 
2.53.0

Reply via email to