All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu
@ 2023-08-16 21:26 Alex Hung
  2023-08-16 21:26 ` [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC Alex Hung
                   ` (18 more replies)
  0 siblings, 19 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

This patchset adds drm_writeback connector supports and enables display
writeback block (DWB) in AMD hardware.

The function can be tested by IGT's kms_writeback test which also
requires a number of patches to enable 10bit (DRM_FORMAT_XRGB2101010).
Patches are available @ https://patchwork.freedesktop.org/series/122536/

Alex Hung (10):
  drm/amd/display: Initialize writeback connector
  drm/amd/display: Hande writeback request from userspace
  drm/amd/display: Add writeback enable/disable in dc
  drm/amd/display: Fix writeback_info never got updated
  drm/amd/display: Validate hw_points_num before using it
  drm/amd/display: Fix writeback_info is not removed
  drm/amd/display: Add writeback enable field (wb_enabled)
  drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer
  drm/amd/display: Add new set_fc_enable to struct dwbc_funcs
  drm/amd/display: Disable DWB frame capture to emulate oneshot

Harry Wentland (8):
  drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC
  drm/amd/display: Create one virtual connector in DC
  drm/amd/display: Skip writeback connector when we get
    amdgpu_dm_connector
  drm/amd/display: Return drm_connector from
    find_first_crtc_matching_connector
  drm/amd/display: Use drm_connector in create_stream_for_sink
  drm/amd/display: Use drm_connector in create_validate_stream_for_sink
  drm/amd/display: Create amdgpu_dm_wb_connector
  drm/amd/display: Create fake sink and stream for writeback connector

 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |   4 +
 .../gpu/drm/amd/display/amdgpu_dm/Makefile    |  14 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 375 ++++++++++++++++--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |   3 +
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  22 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   8 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c  | 215 ++++++++++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h  |  36 ++
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |  80 +++-
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |   4 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c  |  23 ++
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h  |   2 +
 .../drm/amd/display/dc/dcn30/dcn30_dwb_cm.c   |   3 +
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   4 +
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   3 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h   |   4 +
 17 files changed, 742 insertions(+), 70 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h

-- 
2.41.0


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 18:46   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 02/18] drm/amd/display: Create one virtual connector in DC Alex Hung
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHY]
Previously this only excluded build for a few amdgpu_dm
binaries which makes no sense.

[HOW]
Wrap the entire Makefile in "ifneq ($(CONFIG_DRM_AMD_DC),)"

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/Makefile | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
index 8bf94920d23e..063205ecb137 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
@@ -25,22 +25,24 @@
 
 
 
+ifneq ($(CONFIG_DRM_AMD_DC),)
 AMDGPUDM = \
 	amdgpu_dm.o \
 	amdgpu_dm_plane.o \
 	amdgpu_dm_crtc.o \
 	amdgpu_dm_irq.o \
 	amdgpu_dm_mst_types.o \
-	amdgpu_dm_color.o
+	amdgpu_dm_color.o \
+	amdgpu_dm_services.o \
+	amdgpu_dm_helpers.o \
+	amdgpu_dm_pp_smu.o \
+	amdgpu_dm_psr.o \
+	amdgpu_dm_replay.o
 
 ifdef CONFIG_DRM_AMD_DC_FP
 AMDGPUDM += dc_fpu.o
 endif
 
-ifneq ($(CONFIG_DRM_AMD_DC),)
-AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o amdgpu_dm_psr.o amdgpu_dm_replay.o
-endif
-
 AMDGPUDM += amdgpu_dm_hdcp.o
 
 ifneq ($(CONFIG_DEBUG_FS),)
@@ -52,3 +54,4 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc
 AMDGPU_DM = $(addprefix $(AMDDALPATH)/amdgpu_dm/,$(AMDGPUDM))
 
 AMD_DISPLAY_FILES += $(AMDGPU_DM)
+endif
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/18] drm/amd/display: Create one virtual connector in DC
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
  2023-08-16 21:26 ` [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-17 13:58   ` Alex Deucher
  2023-09-05 18:47   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 03/18] drm/amd/display: Initialize writeback connector Alex Hung
                   ` (16 subsequent siblings)
  18 siblings, 2 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHAT]
Prepare a virtual connector for writeback.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 11 +++++++++--
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c |  3 ++-
 2 files changed, 11 insertions(+), 3 deletions(-)

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 b1245b732cc9..00254fdfa1f7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1675,6 +1675,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 	init_data.dcn_reg_offsets = adev->reg_offset[DCE_HWIP][0];
 	init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0];
 
+	/* Enable DWB for tested platforms only */
+	if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0))
+		init_data.num_virtual_links = 1;
+
 	INIT_LIST_HEAD(&adev->dm.da_list);
 
 	retrieve_dmi_info(&adev->dm);
@@ -4385,6 +4389,11 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 			continue;
 		}
 
+		link = dc_get_link_at_index(dm->dc, i);
+
+		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
+			continue;
+
 		aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
 		if (!aconnector)
 			goto fail;
@@ -4403,8 +4412,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 			goto fail;
 		}
 
-		link = dc_get_link_at_index(dm->dc, i);
-
 		if (!dc_link_detect_connection_type(link, &new_connection_type))
 			DRM_ERROR("KMS: Failed to detect connector\n");
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
index 2a7f47642a44..65e8504e6063 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -96,7 +96,8 @@ static void enable_memory_low_power(struct dc *dc)
 	if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
 		// Power down VPGs
 		for (i = 0; i < dc->res_pool->stream_enc_count; i++)
-			dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
+			if (dc->res_pool->stream_enc[i]->vpg)
+				dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
 #if defined(CONFIG_DRM_AMD_DC_FP)
 		for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
 			dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/18] drm/amd/display: Initialize writeback connector
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
  2023-08-16 21:26 ` [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC Alex Hung
  2023-08-16 21:26 ` [PATCH 02/18] drm/amd/display: Create one virtual connector in DC Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 04/18] drm/amd/display: Skip writeback connector when we get amdgpu_dm_connector Alex Hung
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHAT]
Create a drm_writeback_connector when connector signal equals
SIGNAL_TYPE_VIRTUAL.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/Makefile    |   3 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  20 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c  | 209 ++++++++++++++++++
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h  |  35 +++
 4 files changed, 265 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
index 063205ecb137..ab2a97e354da 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
@@ -37,7 +37,8 @@ AMDGPUDM = \
 	amdgpu_dm_helpers.o \
 	amdgpu_dm_pp_smu.o \
 	amdgpu_dm_psr.o \
-	amdgpu_dm_replay.o
+	amdgpu_dm_replay.o \
+	amdgpu_dm_wb.o
 
 ifdef CONFIG_DRM_AMD_DC_FP
 AMDGPUDM += dc_fpu.o
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 00254fdfa1f7..445369afcead 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -54,6 +54,7 @@
 #include "amdgpu_dm_crtc.h"
 #include "amdgpu_dm_hdcp.h"
 #include <drm/display/drm_hdcp_helper.h>
+#include "amdgpu_dm_wb.h"
 #include "amdgpu_pm.h"
 #include "amdgpu_atombios.h"
 
@@ -4391,8 +4392,25 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 
 		link = dc_get_link_at_index(dm->dc, i);
 
-		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
+		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) {
+			struct drm_writeback_connector *wbcon = kzalloc(sizeof(*wbcon), GFP_KERNEL);
+
+			if (!wbcon) {
+				DRM_ERROR("KMS: Failed to allocate writeback connector\n");
+				continue;
+			}
+
+			if (amdgpu_dm_wb_connector_init(dm, wbcon)) {
+				DRM_ERROR("KMS: Failed to initialize writeback connector\n");
+				kfree(wbcon);
+				continue;
+			}
+
+			link->psr_settings.psr_feature_enabled = false;
+			link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
+
 			continue;
+		}
 
 		aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
 		if (!aconnector)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
new file mode 100644
index 000000000000..74e656696d8e
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services_types.h"
+
+#include "amdgpu.h"
+#include "amdgpu_dm.h"
+#include "amdgpu_dm_wb.h"
+#include "amdgpu_display.h"
+
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_modeset_helper_vtables.h>
+
+static const u32 amdgpu_dm_wb_formats[] = {
+	DRM_FORMAT_XRGB2101010,
+};
+
+static int amdgpu_dm_wb_encoder_atomic_check(struct drm_encoder *encoder,
+					struct drm_crtc_state *crtc_state,
+					struct drm_connector_state *conn_state)
+{
+	struct drm_framebuffer *fb;
+	const struct drm_display_mode *mode = &crtc_state->mode;
+	bool found = false;
+	uint8_t i;
+
+	if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+		return 0;
+
+	fb = conn_state->writeback_job->fb;
+	if (fb->width != mode->hdisplay || fb->height != mode->vdisplay) {
+		DRM_DEBUG_KMS("Invalid framebuffer size %ux%u\n",
+			      fb->width, fb->height);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < sizeof(amdgpu_dm_wb_formats) / sizeof(u32); i++) {
+		if (fb->format->format == amdgpu_dm_wb_formats[i])
+			found = true;
+	}
+
+	if (!found) {
+		DRM_DEBUG_KMS("Invalid pixel format %p4cc\n",
+			      &fb->format->format);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static int amdgpu_dm_wb_connector_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+
+	return drm_add_modes_noedid(connector, dev->mode_config.max_width,
+				    dev->mode_config.max_height);
+}
+
+static int amdgpu_dm_wb_prepare_job(struct drm_writeback_connector *wb_connector,
+			       struct drm_writeback_job *job)
+{
+	struct amdgpu_framebuffer *afb;
+	struct drm_gem_object *obj;
+	struct amdgpu_device *adev;
+	struct amdgpu_bo *rbo;
+	uint32_t domain;
+	int r;
+
+	if (!job->fb) {
+		DRM_DEBUG_KMS("No FB bound\n");
+		return 0;
+	}
+
+	afb = to_amdgpu_framebuffer(job->fb);
+	obj = job->fb->obj[0];
+	rbo = gem_to_amdgpu_bo(obj);
+	adev = amdgpu_ttm_adev(rbo->tbo.bdev);
+
+	r = amdgpu_bo_reserve(rbo, true);
+	if (r) {
+		dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
+		return r;
+	}
+
+	r = dma_resv_reserve_fences(rbo->tbo.base.resv, 1);
+	if (r) {
+		dev_err(adev->dev, "reserving fence slot failed (%d)\n", r);
+		goto error_unlock;
+	}
+
+	domain = amdgpu_display_supported_domains(adev, rbo->flags);
+
+	r = amdgpu_bo_pin(rbo, domain);
+	if (unlikely(r != 0)) {
+		if (r != -ERESTARTSYS)
+			DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
+		goto error_unlock;
+	}
+
+	r = amdgpu_ttm_alloc_gart(&rbo->tbo);
+	if (unlikely(r != 0)) {
+		DRM_ERROR("%p bind failed\n", rbo);
+		goto error_unpin;
+	}
+
+	amdgpu_bo_unreserve(rbo);
+
+	afb->address = amdgpu_bo_gpu_offset(rbo);
+
+	amdgpu_bo_ref(rbo);
+
+	return 0;
+
+error_unpin:
+	amdgpu_bo_unpin(rbo);
+
+error_unlock:
+	amdgpu_bo_unreserve(rbo);
+	return r;
+}
+
+static void amdgpu_dm_wb_cleanup_job(struct drm_writeback_connector *connector,
+				struct drm_writeback_job *job)
+{
+	struct amdgpu_bo *rbo;
+	int r;
+
+	if (!job->fb)
+		return;
+
+	rbo = gem_to_amdgpu_bo(job->fb->obj[0]);
+	r = amdgpu_bo_reserve(rbo, false);
+	if (unlikely(r)) {
+		DRM_ERROR("failed to reserve rbo before unpin\n");
+		return;
+	}
+
+	amdgpu_bo_unpin(rbo);
+	amdgpu_bo_unreserve(rbo);
+	amdgpu_bo_unref(&rbo);
+}
+
+static const struct drm_encoder_helper_funcs amdgpu_dm_wb_encoder_helper_funcs = {
+	.atomic_check = amdgpu_dm_wb_encoder_atomic_check,
+};
+
+static const struct drm_connector_funcs amdgpu_dm_wb_connector_funcs = {
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.reset = amdgpu_dm_connector_funcs_reset,
+	.atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs amdgpu_dm_wb_conn_helper_funcs = {
+	.get_modes = amdgpu_dm_wb_connector_get_modes,
+	.prepare_writeback_job = amdgpu_dm_wb_prepare_job,
+	.cleanup_writeback_job = amdgpu_dm_wb_cleanup_job,
+};
+
+int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
+				struct drm_writeback_connector *wbcon)
+{
+	int res = 0;
+
+	drm_connector_helper_add(&wbcon->base, &amdgpu_dm_wb_conn_helper_funcs);
+
+	res = drm_writeback_connector_init(&dm->adev->ddev, wbcon,
+					    &amdgpu_dm_wb_connector_funcs,
+					    &amdgpu_dm_wb_encoder_helper_funcs,
+					    amdgpu_dm_wb_formats,
+					    ARRAY_SIZE(amdgpu_dm_wb_formats),
+					    amdgpu_dm_get_encoder_crtc_mask(dm->adev));
+
+	if (res)
+		return res;
+	/*
+	 * Some of the properties below require access to state, like bpc.
+	 * Allocate some default initial connector state with our reset helper.
+	 */
+	if (wbcon->base.funcs->reset)
+		wbcon->base.funcs->reset(&wbcon->base);
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
new file mode 100644
index 000000000000..0bc9df7e7ee1
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2022 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __AMDGPU_DM_WB_H__
+#define __AMDGPU_DM_WB_H__
+
+#include <drm/drm_writeback.h>
+
+int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
+				struct drm_writeback_connector *wbcon);
+
+#endif
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/18] drm/amd/display: Skip writeback connector when we get amdgpu_dm_connector
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (2 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 03/18] drm/amd/display: Initialize writeback connector Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 18:47   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 05/18] drm/amd/display: Return drm_connector from find_first_crtc_matching_connector Alex Hung
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHY]
Writeback connectors are based on a different object:
drm_writeback_connector, and are therefore different from
amdgpu_dm_connector. We need to be careful to ensure code
designed for amdgpu_dm_connector doesn't inadvertently try
to operate on a drm_writeback_connector.

[HOW]
Skip them when connector type is DRM_MODE_CONNECTOR_WRITEBACK.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 62 +++++++++++++++++--
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |  3 +
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 22 +++++--
 3 files changed, 76 insertions(+), 11 deletions(-)

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 445369afcead..363d91d49a3a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -721,6 +721,10 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
 
 	drm_connector_list_iter_begin(dev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (link && aconnector->dc_link == link) {
 			if (notify->type == DMUB_NOTIFICATION_HPD)
@@ -945,6 +949,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
 
 	drm_connector_list_iter_begin(dev, &conn_iter);
 	drm_for_each_connector_iter(connector, &conn_iter) {
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (aconnector->audio_inst != port)
 			continue;
@@ -2270,6 +2278,10 @@ static int detect_mst_link_for_all_connectors(struct drm_device *dev)
 
 	drm_connector_list_iter_begin(dev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (aconnector->dc_link->type == dc_connection_mst_branch &&
 		    aconnector->mst_mgr.aux) {
@@ -2350,6 +2362,10 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
 
 	drm_connector_list_iter_begin(dev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (aconnector->dc_link->type != dc_connection_mst_branch ||
 		    aconnector->mst_root)
@@ -2865,6 +2881,10 @@ static int dm_resume(void *handle)
 	/* Do detection*/
 	drm_connector_list_iter_begin(ddev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 
 		if (!aconnector->dc_link)
@@ -3416,6 +3436,9 @@ static void register_hpd_handlers(struct amdgpu_device *adev)
 	list_for_each_entry(connector,
 			&dev->mode_config.connector_list, head)	{
 
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 		dc_link = aconnector->dc_link;
 
@@ -5413,10 +5436,13 @@ static void fill_stream_properties_from_drm_display_mode(
 {
 	struct dc_crtc_timing *timing_out = &stream->timing;
 	const struct drm_display_info *info = &connector->display_info;
-	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+	struct amdgpu_dm_connector *aconnector = NULL;
 	struct hdmi_vendor_infoframe hv_frame;
 	struct hdmi_avi_infoframe avi_frame;
 
+	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+		aconnector = to_amdgpu_dm_connector(connector);
+
 	memset(&hv_frame, 0, sizeof(hv_frame));
 	memset(&avi_frame, 0, sizeof(avi_frame));
 
@@ -6843,6 +6869,9 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
 
 	for_each_new_connector_in_state(state, connector, new_con_state, i) {
 
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 
 		if (!aconnector->mst_output_port)
@@ -8392,6 +8421,9 @@ static void amdgpu_dm_commit_audio(struct drm_device *dev,
 		if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
 			continue;
 
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 notify:
 		aconnector = to_amdgpu_dm_connector(connector);
 
@@ -8425,6 +8457,9 @@ static void amdgpu_dm_commit_audio(struct drm_device *dev,
 		if (!status)
 			continue;
 
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 
 		mutex_lock(&adev->dm.audio_lock);
@@ -8686,7 +8721,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 	for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 		struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
-		struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+		struct amdgpu_dm_connector *aconnector;
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
+		aconnector = to_amdgpu_dm_connector(connector);
 
 		if (!adev->dm.hdcp_workqueue)
 			continue;
@@ -9029,10 +9069,15 @@ static int dm_force_atomic_commit(struct drm_connector *connector)
 void dm_restore_drm_connector_state(struct drm_device *dev,
 				    struct drm_connector *connector)
 {
-	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+	struct amdgpu_dm_connector *aconnector;
 	struct amdgpu_crtc *disconnected_acrtc;
 	struct dm_crtc_state *acrtc_state;
 
+	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+		return;
+
+	aconnector = to_amdgpu_dm_connector(connector);
+
 	if (!aconnector->dc_sink || !connector->state || !connector->encoder)
 		return;
 
@@ -9109,12 +9154,16 @@ static void get_freesync_config_for_crtc(
 	struct dm_connector_state *new_con_state)
 {
 	struct mod_freesync_config config = {0};
-	struct amdgpu_dm_connector *aconnector =
-			to_amdgpu_dm_connector(new_con_state->base.connector);
+	struct amdgpu_dm_connector *aconnector;
 	struct drm_display_mode *mode = &new_crtc_state->base.mode;
 	int vrefresh = drm_mode_vrefresh(mode);
 	bool fs_vid_mode = false;
 
+	if (new_con_state->base.connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+		return;
+
+	aconnector = to_amdgpu_dm_connector(new_con_state->base.connector);
+
 	new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
 					vrefresh >= aconnector->min_vfreq &&
 					vrefresh <= aconnector->max_vfreq;
@@ -9898,6 +9947,9 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
 		if (conn_state->crtc != crtc)
 			continue;
 
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (!aconnector->mst_output_port || !aconnector->mst_root)
 			aconnector = NULL;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 52ecfa746b54..f936a35fa9eb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -326,6 +326,9 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 			if (!connector->state || connector->state->crtc != crtc)
 				continue;
 
+			if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+				continue;
+
 			aconn = to_amdgpu_dm_connector(connector);
 			break;
 		}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
index 51467f132c26..58b880acb087 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
@@ -894,10 +894,15 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
 
 	drm_connector_list_iter_begin(dev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
-		struct amdgpu_dm_connector *amdgpu_dm_connector =
-				to_amdgpu_dm_connector(connector);
+		struct amdgpu_dm_connector *amdgpu_dm_connector;
+		const struct dc_link *dc_link;
 
-		const struct dc_link *dc_link = amdgpu_dm_connector->dc_link;
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
+		amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
+
+		dc_link = amdgpu_dm_connector->dc_link;
 
 		if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
 			dc_interrupt_set(adev->dm.dc,
@@ -930,9 +935,14 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
 
 	drm_connector_list_iter_begin(dev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
-		struct amdgpu_dm_connector *amdgpu_dm_connector =
-				to_amdgpu_dm_connector(connector);
-		const struct dc_link *dc_link = amdgpu_dm_connector->dc_link;
+		struct amdgpu_dm_connector *amdgpu_dm_connector;
+		const struct dc_link *dc_link;
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
+		amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
+		dc_link = amdgpu_dm_connector->dc_link;
 
 		if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
 			dc_interrupt_set(adev->dm.dc,
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/18] drm/amd/display: Return drm_connector from find_first_crtc_matching_connector
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (3 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 04/18] drm/amd/display: Skip writeback connector when we get amdgpu_dm_connector Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 18:47   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 06/18] drm/amd/display: Use drm_connector in create_stream_for_sink Alex Hung
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHY]
We will be dealing with two types of connector: amdgpu_dm_connector
and drm_writeback_connector.

[HOW]
We want to find both and then cast to the appriopriate type afterwards.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c         | 8 +++++---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h         | 2 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c   | 4 +++-
 3 files changed, 9 insertions(+), 5 deletions(-)

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 363d91d49a3a..7bd3ec84ff2e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2630,7 +2630,7 @@ static int dm_suspend(void *handle)
 	return 0;
 }
 
-struct amdgpu_dm_connector *
+struct drm_connector *
 amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
 					     struct drm_crtc *crtc)
 {
@@ -2643,7 +2643,7 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
 		crtc_from_state = new_con_state->crtc;
 
 		if (crtc_from_state == crtc)
-			return to_amdgpu_dm_connector(connector);
+			return connector;
 	}
 
 	return NULL;
@@ -9263,6 +9263,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 	 * update changed items
 	 */
 	struct amdgpu_crtc *acrtc = NULL;
+	struct drm_connector *connector = NULL;
 	struct amdgpu_dm_connector *aconnector = NULL;
 	struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL;
 	struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL;
@@ -9272,7 +9273,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 	dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 	dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
 	acrtc = to_amdgpu_crtc(crtc);
-	aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
+	connector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
+	aconnector = to_amdgpu_dm_connector(connector);
 
 	/* TODO This hack should go away */
 	if (aconnector && enable) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index a2d34be82613..5a8d07a27e9b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -836,7 +836,7 @@ struct dc_stream_state *
 int dm_atomic_get_state(struct drm_atomic_state *state,
 			struct dm_atomic_state **dm_state);
 
-struct amdgpu_dm_connector *
+struct drm_connector *
 amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
 					     struct drm_crtc *crtc);
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 57230661132b..1975b9d96cb8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -1494,14 +1494,16 @@ int pre_validate_dsc(struct drm_atomic_state *state,
 		int ind = find_crtc_index_in_state_by_stream(state, stream);
 
 		if (ind >= 0) {
+			struct drm_connector *connector;
 			struct amdgpu_dm_connector *aconnector;
 			struct drm_connector_state *drm_new_conn_state;
 			struct dm_connector_state *dm_new_conn_state;
 			struct dm_crtc_state *dm_old_crtc_state;
 
-			aconnector =
+			connector =
 				amdgpu_dm_find_first_crtc_matching_connector(state,
 									     state->crtcs[ind].ptr);
+			aconnector = to_amdgpu_dm_connector(connector);
 			drm_new_conn_state =
 				drm_atomic_get_new_connector_state(state,
 								   &aconnector->base);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/18] drm/amd/display: Use drm_connector in create_stream_for_sink
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (4 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 05/18] drm/amd/display: Return drm_connector from find_first_crtc_matching_connector Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 18:48   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 07/18] drm/amd/display: Use drm_connector in create_validate_stream_for_sink Alex Hung
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHAT]
We need to use this function for both amdgpu_dm_connectors
and drm_writeback_connectors. Modify it to operate on
a drm_connector as a common base.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 65 +++++++++++--------
 1 file changed, 37 insertions(+), 28 deletions(-)

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 7bd3ec84ff2e..a7d2a3f35f74 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5455,6 +5455,7 @@ static void fill_stream_properties_from_drm_display_mode(
 			&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
 	else if (drm_mode_is_420_also(info, mode_in)
+			&& aconnector
 			&& aconnector->force_yuv420_output)
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
 	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
@@ -5490,7 +5491,7 @@ static void fill_stream_properties_from_drm_display_mode(
 		timing_out->hdmi_vic = hv_frame.vic;
 	}
 
-	if (is_freesync_video_mode(mode_in, aconnector)) {
+	if (aconnector && is_freesync_video_mode(mode_in, aconnector)) {
 		timing_out->h_addressable = mode_in->hdisplay;
 		timing_out->h_total = mode_in->htotal;
 		timing_out->h_sync_width = mode_in->hsync_end - mode_in->hsync_start;
@@ -5966,14 +5967,14 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
 }
 
 static struct dc_stream_state *
-create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+create_stream_for_sink(struct drm_connector *connector,
 		       const struct drm_display_mode *drm_mode,
 		       const struct dm_connector_state *dm_state,
 		       const struct dc_stream_state *old_stream,
 		       int requested_bpc)
 {
+	struct amdgpu_dm_connector *aconnector = NULL;
 	struct drm_display_mode *preferred_mode = NULL;
-	struct drm_connector *drm_connector;
 	const struct drm_connector_state *con_state = &dm_state->base;
 	struct dc_stream_state *stream = NULL;
 	struct drm_display_mode mode;
@@ -5992,20 +5993,22 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 	drm_mode_init(&mode, drm_mode);
 	memset(&saved_mode, 0, sizeof(saved_mode));
 
-	if (aconnector == NULL) {
-		DRM_ERROR("aconnector is NULL!\n");
+	if (connector == NULL) {
+		DRM_ERROR("connector is NULL!\n");
 		return stream;
 	}
 
-	drm_connector = &aconnector->base;
-
-	if (!aconnector->dc_sink) {
-		sink = create_fake_sink(aconnector);
-		if (!sink)
-			return stream;
-	} else {
-		sink = aconnector->dc_sink;
-		dc_sink_retain(sink);
+	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
+		aconnector = NULL;
+		aconnector = to_amdgpu_dm_connector(connector);
+		if (!aconnector->dc_sink) {
+			sink = create_fake_sink(aconnector);
+			if (!sink)
+				return stream;
+		} else {
+			sink = aconnector->dc_sink;
+			dc_sink_retain(sink);
+		}
 	}
 
 	stream = dc_create_stream_for_sink(sink);
@@ -6015,12 +6018,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 		goto finish;
 	}
 
+	/* We leave this NULL for writeback connectors */
 	stream->dm_stream_context = aconnector;
 
 	stream->timing.flags.LTE_340MCSC_SCRAMBLE =
-		drm_connector->display_info.hdmi.scdc.scrambling.low_rates;
+		connector->display_info.hdmi.scdc.scrambling.low_rates;
 
-	list_for_each_entry(preferred_mode, &aconnector->base.modes, head) {
+	list_for_each_entry(preferred_mode, &connector->modes, head) {
 		/* Search for preferred mode */
 		if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) {
 			native_mode_found = true;
@@ -6029,7 +6033,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 	}
 	if (!native_mode_found)
 		preferred_mode = list_first_entry_or_null(
-				&aconnector->base.modes,
+				&connector->modes,
 				struct drm_display_mode,
 				head);
 
@@ -6043,7 +6047,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 		 * and the modelist may not be filled in time.
 		 */
 		DRM_DEBUG_DRIVER("No preferred mode found\n");
-	} else {
+	} else if (aconnector) {
 		recalculate_timing = is_freesync_video_mode(&mode, aconnector);
 		if (recalculate_timing) {
 			freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
@@ -6068,13 +6072,17 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 	 */
 	if (!scale || mode_refresh != preferred_refresh)
 		fill_stream_properties_from_drm_display_mode(
-			stream, &mode, &aconnector->base, con_state, NULL,
+			stream, &mode, connector, con_state, NULL,
 			requested_bpc);
 	else
 		fill_stream_properties_from_drm_display_mode(
-			stream, &mode, &aconnector->base, con_state, old_stream,
+			stream, &mode, connector, con_state, old_stream,
 			requested_bpc);
 
+	/* The rest isn't needed for writeback connectors */
+	if (!aconnector)
+		goto finish;
+
 	if (aconnector->timing_changed) {
 		DC_LOG_DEBUG("%s: overriding timing for automated test, bpc %d, changing to %d\n",
 				__func__,
@@ -6092,7 +6100,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 
 	fill_audio_info(
 		&stream->audio_info,
-		drm_connector,
+		connector,
 		sink);
 
 	update_stream_signal(stream, sink);
@@ -6551,7 +6559,7 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 	enum dc_status dc_result = DC_OK;
 
 	do {
-		stream = create_stream_for_sink(aconnector, drm_mode,
+		stream = create_stream_for_sink(connector, drm_mode,
 						dm_state, old_stream,
 						requested_bpc);
 		if (stream == NULL) {
@@ -9274,15 +9282,16 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 	dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
 	acrtc = to_amdgpu_crtc(crtc);
 	connector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
-	aconnector = to_amdgpu_dm_connector(connector);
+	if (connector && connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+		aconnector = to_amdgpu_dm_connector(connector);
 
 	/* TODO This hack should go away */
-	if (aconnector && enable) {
+	if (connector && enable) {
 		/* Make sure fake sink is created in plug-in scenario */
 		drm_new_conn_state = drm_atomic_get_new_connector_state(state,
-							    &aconnector->base);
+									connector);
 		drm_old_conn_state = drm_atomic_get_old_connector_state(state,
-							    &aconnector->base);
+									connector);
 
 		if (IS_ERR(drm_new_conn_state)) {
 			ret = PTR_ERR_OR_ZERO(drm_new_conn_state);
@@ -9429,7 +9438,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 		 * added MST connectors not found in existing crtc_state in the chained mode
 		 * TODO: need to dig out the root cause of that
 		 */
-		if (!aconnector)
+		if (!connector)
 			goto skip_modeset;
 
 		if (modereset_required(new_crtc_state))
@@ -9472,7 +9481,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 	 * We want to do dc stream updates that do not require a
 	 * full modeset below.
 	 */
-	if (!(enable && aconnector && new_crtc_state->active))
+	if (!(enable && connector && new_crtc_state->active))
 		return 0;
 	/*
 	 * Given above conditions, the dc state cannot be NULL because:
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/18] drm/amd/display: Use drm_connector in create_validate_stream_for_sink
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (5 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 06/18] drm/amd/display: Use drm_connector in create_stream_for_sink Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 18:48   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 08/18] drm/amd/display: Create amdgpu_dm_wb_connector Alex Hung
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHAT]
Again, we need to use this function for writeback connectors,
which are not of type amdgpu_dm_connector. Use the common base
drm_connector instead.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 ++++++++++++++-----
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  6 ++---
 3 files changed, 19 insertions(+), 11 deletions(-)

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 a7d2a3f35f74..33e7c463a0d0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6546,18 +6546,21 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc,
 }
 
 struct dc_stream_state *
-create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+create_validate_stream_for_sink(struct drm_connector *connector,
 				const struct drm_display_mode *drm_mode,
 				const struct dm_connector_state *dm_state,
 				const struct dc_stream_state *old_stream)
 {
-	struct drm_connector *connector = &aconnector->base;
+	struct amdgpu_dm_connector *aconnector = NULL;
 	struct amdgpu_device *adev = drm_to_adev(connector->dev);
 	struct dc_stream_state *stream;
 	const struct drm_connector_state *drm_state = dm_state ? &dm_state->base : NULL;
 	int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8;
 	enum dc_status dc_result = DC_OK;
 
+	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+		aconnector = to_amdgpu_dm_connector(connector);
+
 	do {
 		stream = create_stream_for_sink(connector, drm_mode,
 						dm_state, old_stream,
@@ -6568,10 +6571,14 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 		}
 
 		dc_result = dc_validate_stream(adev->dm.dc, stream);
+
+		if (!aconnector) /* writeback connector */
+			return stream;
+
 		if (dc_result == DC_OK && stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
 			dc_result = dm_dp_mst_is_port_support_mode(aconnector, stream);
 
-		if (dc_result == DC_OK)
+		if (dc_result == DC_OK && connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
 			dc_result = dm_validate_stream_and_context(adev->dm.dc, stream);
 
 		if (dc_result != DC_OK) {
@@ -6593,7 +6600,7 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 		DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n");
 
 		aconnector->force_yuv420_output = true;
-		stream = create_validate_stream_for_sink(aconnector, drm_mode,
+		stream = create_validate_stream_for_sink(connector, drm_mode,
 						dm_state, old_stream);
 		aconnector->force_yuv420_output = false;
 	}
@@ -6608,6 +6615,9 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
 	struct dc_sink *dc_sink;
 	/* TODO: Unhardcode stream count */
 	struct dc_stream_state *stream;
+	/* we always have an amdgpu_dm_connector here since we got
+	 * here via the amdgpu_dm_connector_helper_funcs
+	 */
 	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 
 	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
@@ -6630,7 +6640,7 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
 		goto fail;
 	}
 
-	stream = create_validate_stream_for_sink(aconnector, mode,
+	stream = create_validate_stream_for_sink(connector, mode,
 						 to_dm_connector_state(connector->state),
 						 NULL);
 	if (stream) {
@@ -9304,7 +9314,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 		if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
 			goto skip_modeset;
 
-		new_stream = create_validate_stream_for_sink(aconnector,
+		new_stream = create_validate_stream_for_sink(connector,
 							     &new_crtc_state->mode,
 							     dm_new_conn_state,
 							     dm_old_crtc_state->stream);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 5a8d07a27e9b..a2d0ab881c44 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -828,7 +828,7 @@ int amdgpu_dm_process_dmub_set_config_sync(struct dc_context *ctx, unsigned int
 bool check_seamless_boot_capability(struct amdgpu_device *adev);
 
 struct dc_stream_state *
-	create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+	create_validate_stream_for_sink(struct drm_connector *connector,
 					const struct drm_display_mode *drm_mode,
 					const struct dm_connector_state *dm_state,
 					const struct dc_stream_state *old_stream);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 1975b9d96cb8..687dba32cde3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -1495,7 +1495,6 @@ int pre_validate_dsc(struct drm_atomic_state *state,
 
 		if (ind >= 0) {
 			struct drm_connector *connector;
-			struct amdgpu_dm_connector *aconnector;
 			struct drm_connector_state *drm_new_conn_state;
 			struct dm_connector_state *dm_new_conn_state;
 			struct dm_crtc_state *dm_old_crtc_state;
@@ -1503,15 +1502,14 @@ int pre_validate_dsc(struct drm_atomic_state *state,
 			connector =
 				amdgpu_dm_find_first_crtc_matching_connector(state,
 									     state->crtcs[ind].ptr);
-			aconnector = to_amdgpu_dm_connector(connector);
 			drm_new_conn_state =
 				drm_atomic_get_new_connector_state(state,
-								   &aconnector->base);
+								   connector);
 			dm_new_conn_state = to_dm_connector_state(drm_new_conn_state);
 			dm_old_crtc_state = to_dm_crtc_state(state->crtcs[ind].old_state);
 
 			local_dc_state->streams[i] =
-				create_validate_stream_for_sink(aconnector,
+				create_validate_stream_for_sink(connector,
 								&state->crtcs[ind].new_state->mode,
 								dm_new_conn_state,
 								dm_old_crtc_state->stream);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/18] drm/amd/display: Create amdgpu_dm_wb_connector
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (6 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 07/18] drm/amd/display: Use drm_connector in create_validate_stream_for_sink Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 18:48   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 09/18] drm/amd/display: Create fake sink and stream for writeback connector Alex Hung
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHY]
We need to track the dc_link and it would get confusing if
re-using the amdgpu_dm_connector.

[HOW]
Creating new amdgpu_dm_wb_connector.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c    |  5 +++--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h    |  8 ++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c | 16 +++++++++++-----
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h |  3 ++-
 4 files changed, 24 insertions(+), 8 deletions(-)

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 33e7c463a0d0..b12e8393fef3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4416,14 +4416,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 		link = dc_get_link_at_index(dm->dc, i);
 
 		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) {
-			struct drm_writeback_connector *wbcon = kzalloc(sizeof(*wbcon), GFP_KERNEL);
+			struct amdgpu_dm_wb_connector *wbcon = kzalloc(sizeof(*wbcon), GFP_KERNEL);
 
 			if (!wbcon) {
 				DRM_ERROR("KMS: Failed to allocate writeback connector\n");
 				continue;
 			}
 
-			if (amdgpu_dm_wb_connector_init(dm, wbcon)) {
+			if (amdgpu_dm_wb_connector_init(dm, wbcon, i)) {
 				DRM_ERROR("KMS: Failed to initialize writeback connector\n");
 				kfree(wbcon);
 				continue;
@@ -7487,6 +7487,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
 	struct dc_link *link = dc_get_link_at_index(dc, link_index);
 	struct amdgpu_i2c_adapter *i2c;
 
+	/* Not needed for writeback connector */
 	link->priv = aconnector;
 
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index a2d0ab881c44..46acf89e5a45 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -32,6 +32,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_plane.h>
 #include "link_service_types.h"
+#include <drm/drm_writeback.h>
 
 /*
  * This file contains the definition for amdgpu_display_manager
@@ -714,6 +715,13 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
 
 #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
 
+struct amdgpu_dm_wb_connector {
+	struct drm_writeback_connector base;
+	struct dc_link *link;
+};
+
+#define to_amdgpu_dm_wb_connector(x) container_of(x, struct amdgpu_dm_wb_connector, base)
+
 extern const struct amdgpu_ip_block_version dm_ip_block;
 
 struct dm_plane_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
index 74e656696d8e..b3e634b0f712 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
@@ -30,6 +30,7 @@
 #include "amdgpu_dm.h"
 #include "amdgpu_dm_wb.h"
 #include "amdgpu_display.h"
+#include "dc.h"
 
 #include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_modeset_helper_vtables.h>
@@ -183,13 +184,18 @@ static const struct drm_connector_helper_funcs amdgpu_dm_wb_conn_helper_funcs =
 };
 
 int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
-				struct drm_writeback_connector *wbcon)
+				struct amdgpu_dm_wb_connector *wbcon,
+				uint32_t link_index)
 {
+	struct dc *dc = dm->dc;
+	struct dc_link *link = dc_get_link_at_index(dc, link_index);
 	int res = 0;
 
-	drm_connector_helper_add(&wbcon->base, &amdgpu_dm_wb_conn_helper_funcs);
+	wbcon->link = link;
 
-	res = drm_writeback_connector_init(&dm->adev->ddev, wbcon,
+	drm_connector_helper_add(&wbcon->base.base, &amdgpu_dm_wb_conn_helper_funcs);
+
+	res = drm_writeback_connector_init(&dm->adev->ddev, &wbcon->base,
 					    &amdgpu_dm_wb_connector_funcs,
 					    &amdgpu_dm_wb_encoder_helper_funcs,
 					    amdgpu_dm_wb_formats,
@@ -202,8 +208,8 @@ int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
 	 * Some of the properties below require access to state, like bpc.
 	 * Allocate some default initial connector state with our reset helper.
 	 */
-	if (wbcon->base.funcs->reset)
-		wbcon->base.funcs->reset(&wbcon->base);
+	if (wbcon->base.base.funcs->reset)
+		wbcon->base.base.funcs->reset(&wbcon->base.base);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
index 0bc9df7e7ee1..13d31c857dee 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
@@ -30,6 +30,7 @@
 #include <drm/drm_writeback.h>
 
 int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
-				struct drm_writeback_connector *wbcon);
+				struct amdgpu_dm_wb_connector *dm_wbcon,
+				uint32_t link_index);
 
 #endif
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/18] drm/amd/display: Create fake sink and stream for writeback connector
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (7 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 08/18] drm/amd/display: Create amdgpu_dm_wb_connector Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 18:48   ` Alex Hung
  2023-08-16 21:26 ` [PATCH 10/18] drm/amd/display: Hande writeback request from userspace Alex Hung
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

From: Harry Wentland <harry.wentland@amd.com>

[WHAT]
Writeback connectors don't have a physical sink but DC still
needs a sink to function. Create a fake sink and stream for
writeback connectors

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 33 ++++++++++++-------
 1 file changed, 22 insertions(+), 11 deletions(-)

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 b12e8393fef3..82f00af14ada 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5611,13 +5611,13 @@ decide_crtc_timing_for_drm_display_mode(struct drm_display_mode *drm_mode,
 }
 
 static struct dc_sink *
-create_fake_sink(struct amdgpu_dm_connector *aconnector)
+create_fake_sink(struct dc_link *link)
 {
 	struct dc_sink_init_data sink_init_data = { 0 };
 	struct dc_sink *sink = NULL;
 
-	sink_init_data.link = aconnector->dc_link;
-	sink_init_data.sink_signal = aconnector->dc_link->connector_signal;
+	sink_init_data.link = link;
+	sink_init_data.sink_signal = link->connector_signal;
 
 	sink = dc_sink_create(&sink_init_data);
 	if (!sink) {
@@ -5988,6 +5988,7 @@ create_stream_for_sink(struct drm_connector *connector,
 	enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
 	struct dsc_dec_dpcd_caps dsc_caps;
 
+	struct dc_link *link = NULL;
 	struct dc_sink *sink = NULL;
 
 	drm_mode_init(&mode, drm_mode);
@@ -6001,14 +6002,24 @@ create_stream_for_sink(struct drm_connector *connector,
 	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
 		aconnector = NULL;
 		aconnector = to_amdgpu_dm_connector(connector);
-		if (!aconnector->dc_sink) {
-			sink = create_fake_sink(aconnector);
-			if (!sink)
-				return stream;
-		} else {
-			sink = aconnector->dc_sink;
-			dc_sink_retain(sink);
-		}
+		link = aconnector->dc_link;
+	} else {
+		struct drm_writeback_connector *wbcon = NULL;
+		struct amdgpu_dm_wb_connector *dm_wbcon = NULL;
+
+		wbcon = drm_connector_to_writeback(connector);
+		dm_wbcon = to_amdgpu_dm_wb_connector(wbcon);
+		link = dm_wbcon->link;
+	}
+
+	if (!aconnector || !aconnector->dc_sink) {
+		sink = create_fake_sink(link);
+		if (!sink)
+			return stream;
+
+	} else {
+		sink = aconnector->dc_sink;
+		dc_sink_retain(sink);
 	}
 
 	stream = dc_create_stream_for_sink(sink);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/18] drm/amd/display: Hande writeback request from userspace
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (8 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 09/18] drm/amd/display: Create fake sink and stream for writeback connector Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 11/18] drm/amd/display: Add writeback enable/disable in dc Alex Hung
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHAT]
Handle writeback requests and fill in the required information for DWB
programming and setup.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |   3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 159 ++++++++++++++++++
 2 files changed, 162 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 32fe05c810c6..a166d7684719 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -416,6 +416,9 @@ struct amdgpu_crtc {
 
 	int otg_inst;
 	struct drm_pending_vblank_event *event;
+
+	bool wb_pending;
+	struct drm_writeback_connector *wb_conn;
 };
 
 struct amdgpu_encoder_atom_dig {
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 82f00af14ada..fdfcafbaa668 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -572,6 +572,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
 {
 	struct common_irq_params *irq_params = interrupt_params;
 	struct amdgpu_device *adev = irq_params->adev;
+	struct drm_writeback_job *job;
 	struct amdgpu_crtc *acrtc;
 	unsigned long flags;
 	int vrr_active;
@@ -580,6 +581,21 @@ static void dm_crtc_high_irq(void *interrupt_params)
 	if (!acrtc)
 		return;
 
+	if (acrtc->wb_pending) {
+		if (acrtc->wb_conn) {
+			spin_lock_irqsave(&acrtc->wb_conn->job_lock, flags);
+			job = list_first_entry_or_null(&acrtc->wb_conn->job_queue,
+						       struct drm_writeback_job,
+						       list_entry);
+			spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags);
+
+			if (job)
+				drm_writeback_signal_completion(acrtc->wb_conn, 0);
+		} else
+			DRM_ERROR("%s: no amdgpu_crtc wb_conn\n", __func__);
+		acrtc->wb_pending = false;
+	}
+
 	vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc);
 
 	DC_LOG_VBLANK("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id,
@@ -8515,6 +8531,12 @@ static void amdgpu_dm_crtc_copy_transient_flags(struct drm_crtc_state *crtc_stat
 	stream_state->mode_changed = drm_atomic_crtc_needs_modeset(crtc_state);
 }
 
+static void dm_clear_writeback(struct amdgpu_display_manager *dm,
+			      struct dm_crtc_state *crtc_state)
+{
+	dc_stream_remove_writeback(dm->dc, crtc_state->stream, 0);
+}
+
 static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
 					struct dc_state *dc_state)
 {
@@ -8524,9 +8546,34 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 	struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
+	struct drm_connector_state *old_con_state;
+	struct drm_connector *connector;
 	bool mode_set_reset_required = false;
 	u32 i;
 
+	/* Disable writeback */
+	for_each_old_connector_in_state(state, connector, old_con_state, i) {
+		struct dm_connector_state *dm_old_con_state;
+		struct amdgpu_crtc *acrtc;
+
+		if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
+		old_crtc_state = NULL;
+
+		dm_old_con_state = to_dm_connector_state(old_con_state);
+		if (!dm_old_con_state->base.crtc)
+			continue;
+
+		acrtc = to_amdgpu_crtc(dm_old_con_state->base.crtc);
+		if (acrtc)
+			old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
+
+		dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
+
+		dm_clear_writeback(dm, dm_old_crtc_state);
+	}
+
 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
 				      new_crtc_state, i) {
 		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
@@ -8661,6 +8708,97 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
 	}
 }
 
+static void dm_set_writeback(struct amdgpu_display_manager *dm,
+			      struct dm_crtc_state *crtc_state,
+			      struct drm_connector *connector,
+			      struct drm_connector_state *new_con_state)
+{
+	struct drm_writeback_connector *wb_conn = drm_connector_to_writeback(connector);
+	struct amdgpu_crtc *acrtc;
+	struct dc_writeback_info *wb_info;
+	struct pipe_ctx *pipe = NULL;
+	struct amdgpu_framebuffer *afb;
+	int i = 0;
+
+	wb_info = kzalloc(sizeof(*wb_info), GFP_KERNEL);
+	if (!wb_info) {
+		DRM_ERROR("Failed to allocate wb_info\n");
+		return;
+	}
+
+	acrtc = to_amdgpu_crtc(wb_conn->encoder.crtc);
+	if (!acrtc) {
+		DRM_ERROR("no amdgpu_crtc found\n");
+		return;
+	}
+
+	afb = to_amdgpu_framebuffer(new_con_state->writeback_job->fb);
+	if (!afb) {
+		DRM_ERROR("No amdgpu_framebuffer found\n");
+		return;
+	}
+
+	for (i = 0; i < MAX_PIPES; i++) {
+		if (dm->dc->current_state->res_ctx.pipe_ctx[i].stream == crtc_state->stream) {
+			pipe = &dm->dc->current_state->res_ctx.pipe_ctx[i];
+			break;
+		}
+	}
+
+	/* fill in wb_info */
+	wb_info->wb_enabled = true;
+
+	wb_info->dwb_pipe_inst = 0;
+	wb_info->dwb_params.dwbscl_black_color = 0;
+	wb_info->dwb_params.hdr_mult = 0x1F000;
+	wb_info->dwb_params.csc_params.gamut_adjust_type = CM_GAMUT_ADJUST_TYPE_BYPASS;
+	wb_info->dwb_params.csc_params.gamut_coef_format = CM_GAMUT_REMAP_COEF_FORMAT_S2_13;
+	wb_info->dwb_params.output_depth = DWB_OUTPUT_PIXEL_DEPTH_10BPC;
+	wb_info->dwb_params.cnv_params.cnv_out_bpc = DWB_CNV_OUT_BPC_10BPC;
+
+	/* width & height from crtc */
+	wb_info->dwb_params.cnv_params.src_width = acrtc->base.mode.crtc_hdisplay;
+	wb_info->dwb_params.cnv_params.src_height = acrtc->base.mode.crtc_vdisplay;
+	wb_info->dwb_params.dest_width = acrtc->base.mode.crtc_hdisplay;
+	wb_info->dwb_params.dest_height = acrtc->base.mode.crtc_vdisplay;
+
+	wb_info->dwb_params.cnv_params.crop_en = false;
+	wb_info->dwb_params.stereo_params.stereo_enabled = false;
+
+	wb_info->dwb_params.cnv_params.out_max_pix_val = 0x3ff;	// 10 bits
+	wb_info->dwb_params.cnv_params.out_min_pix_val = 0;
+	wb_info->dwb_params.cnv_params.fc_out_format = DWB_OUT_FORMAT_32BPP_ARGB;
+	wb_info->dwb_params.cnv_params.out_denorm_mode = DWB_OUT_DENORM_BYPASS;
+
+	wb_info->dwb_params.out_format = dwb_scaler_mode_bypass444;
+
+	wb_info->dwb_params.capture_rate = dwb_capture_rate_0;
+
+	wb_info->dwb_params.scaler_taps.h_taps = 4;
+	wb_info->dwb_params.scaler_taps.v_taps = 4;
+	wb_info->dwb_params.scaler_taps.h_taps_c = 2;
+	wb_info->dwb_params.scaler_taps.v_taps_c = 2;
+	wb_info->dwb_params.subsample_position = DWB_INTERSTITIAL_SUBSAMPLING;
+
+	wb_info->mcif_buf_params.luma_pitch = afb->base.pitches[0];
+	wb_info->mcif_buf_params.chroma_pitch = afb->base.pitches[1];
+
+	for (i = 0; i < DWB_MCIF_BUF_COUNT; i++) {
+		wb_info->mcif_buf_params.luma_address[i] = afb->address;
+		wb_info->mcif_buf_params.chroma_address[i] = 0;
+	}
+
+	wb_info->mcif_buf_params.p_vmid = 1;
+	wb_info->mcif_warmup_params.p_vmid = 1;
+	wb_info->writeback_source_plane = pipe->plane_state;
+
+	dc_stream_add_writeback(dm->dc, crtc_state->stream, wb_info);
+
+	acrtc->wb_pending = true;
+	acrtc->wb_conn = wb_conn;
+	drm_writeback_queue_job(wb_conn, new_con_state);
+}
+
 /**
  * amdgpu_dm_atomic_commit_tail() - AMDgpu DM's commit tail implementation.
  * @state: The atomic state to commit
@@ -8982,6 +9120,27 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 			amdgpu_dm_commit_planes(state, dev, dm, crtc, wait_for_vblank);
 	}
 
+	/* Enable writeback */
+	for_each_new_connector_in_state(state, connector, new_con_state, i) {
+		struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
+		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
+
+		if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
+		if (!new_con_state->writeback_job)
+			continue;
+
+		new_crtc_state = NULL;
+
+		if (acrtc)
+			new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
+
+		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+
+		dm_set_writeback(dm, dm_new_crtc_state, connector, new_con_state);
+	}
+
 	/* Update audio instances for each connector. */
 	amdgpu_dm_commit_audio(dev, state);
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/18] drm/amd/display: Add writeback enable/disable in dc
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (9 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 10/18] drm/amd/display: Hande writeback request from userspace Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 12/18] drm/amd/display: Fix writeback_info never got updated Alex Hung
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHAT]
The enable and disable writeback calls need to be included in the
coressponding functions in dc_stream.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_stream.c   | 33 +++++++++++++++++++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |  4 +++
 2 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 01fe2d2fd241..0157d9e55ca0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -516,6 +516,25 @@ bool dc_stream_add_writeback(struct dc *dc,
 		struct dwbc *dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
 		dwb->otg_inst = stream_status->primary_otg_inst;
 	}
+
+	if (!dc->hwss.update_bandwidth(dc, dc->current_state)) {
+		dm_error("DC: update_bandwidth failed!\n");
+		return false;
+	}
+
+	/* enable writeback */
+	if (dc->hwss.enable_writeback) {
+		struct dwbc *dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
+
+		if (dwb->funcs->is_enabled(dwb)) {
+			/* writeback pipe already enabled, only need to update */
+			dc->hwss.update_writeback(dc, wb_info, dc->current_state);
+		} else {
+			/* Enable writeback pipe from scratch*/
+			dc->hwss.enable_writeback(dc, wb_info, dc->current_state);
+		}
+	}
+
 	return true;
 }
 
@@ -560,6 +579,20 @@ bool dc_stream_remove_writeback(struct dc *dc,
 	}
 	stream->num_wb_info = j;
 
+	/* recalculate and apply DML parameters */
+	if (!dc->hwss.update_bandwidth(dc, dc->current_state)) {
+		dm_error("DC: update_bandwidth failed!\n");
+		return false;
+	}
+
+	/* disable writeback */
+	if (dc->hwss.disable_writeback) {
+		struct dwbc *dwb = dc->res_pool->dwbc[dwb_pipe_inst];
+
+		if (dwb->funcs->is_enabled(dwb))
+			dc->hwss.disable_writeback(dc, dwb_pipe_inst);
+	}
+
 	return true;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 6cef62d7a2e5..d97c7da33b6e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -330,6 +330,10 @@ void dcn30_enable_writeback(
 	DC_LOG_DWB("%s dwb_pipe_inst = %d, mpcc_inst = %d",\
 		__func__, wb_info->dwb_pipe_inst,\
 		wb_info->mpcc_inst);
+
+	/* Warmup interface */
+	dcn30_mmhubbub_warmup(dc, 1, wb_info);
+
 	/* Update writeback pipe */
 	dcn30_set_writeback(dc, wb_info, context);
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/18] drm/amd/display: Fix writeback_info never got updated
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (10 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 11/18] drm/amd/display: Add writeback enable/disable in dc Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 13/18] drm/amd/display: Validate hw_points_num before using it Alex Hung
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHY]
wb_enabled field is set to false before it is used, and the following
code will never be executed.

[HOW]
Setting wb_enable to false after all removal work is completed.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 0157d9e55ca0..5b89df8fccca 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -558,18 +558,13 @@ bool dc_stream_remove_writeback(struct dc *dc,
 		return false;
 	}
 
-//	stream->writeback_info[dwb_pipe_inst].wb_enabled = false;
-	for (i = 0; i < stream->num_wb_info; i++) {
-		/*dynamic update*/
-		if (stream->writeback_info[i].wb_enabled &&
-			stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst) {
-			stream->writeback_info[i].wb_enabled = false;
-		}
-	}
-
 	/* remove writeback info for disabled writeback pipes from stream */
 	for (i = 0, j = 0; i < stream->num_wb_info; i++) {
 		if (stream->writeback_info[i].wb_enabled) {
+
+			if (stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst)
+				stream->writeback_info[i].wb_enabled = false;
+
 			if (j < i)
 				/* trim the array */
 				memcpy(&stream->writeback_info[j], &stream->writeback_info[i],
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 13/18] drm/amd/display: Validate hw_points_num before using it
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (11 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 12/18] drm/amd/display: Fix writeback_info never got updated Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 14/18] drm/amd/display: Fix writeback_info is not removed Alex Hung
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHAT]
hw_points_num is 0 before ogam LUT is programmed; however, function
"dwb3_program_ogam_pwl" assumes hw_points_num is always greater than 0,
i.e. substracting it by 1 as an array index.

[HOW]
Check hw_points_num is not equal to 0 before using it.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
index 701c7d8bc038..03a50c32fcfe 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c
@@ -243,6 +243,9 @@ static bool dwb3_program_ogam_lut(
 		return false;
 	}
 
+	if (params->hw_points_num == 0)
+		return false;
+
 	REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_MODE, 2);
 
 	current_mode = dwb3_get_ogam_current(dwbc30);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 14/18] drm/amd/display: Fix writeback_info is not removed
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (12 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 13/18] drm/amd/display: Validate hw_points_num before using it Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 15/18] drm/amd/display: Add writeback enable field (wb_enabled) Alex Hung
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHY]
Counter j was not updated to present the num of writeback_info when
writeback pipes are removed.

[HOW]
update j (num of writeback info) under the correct condition.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 5b89df8fccca..0e3ade920c4d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -565,11 +565,12 @@ bool dc_stream_remove_writeback(struct dc *dc,
 			if (stream->writeback_info[i].dwb_pipe_inst == dwb_pipe_inst)
 				stream->writeback_info[i].wb_enabled = false;
 
-			if (j < i)
-				/* trim the array */
+			/* trim the array */
+			if (j < i) {
 				memcpy(&stream->writeback_info[j], &stream->writeback_info[i],
 						sizeof(struct dc_writeback_info));
-			j++;
+				j++;
+			}
 		}
 	}
 	stream->num_wb_info = j;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 15/18] drm/amd/display: Add writeback enable field (wb_enabled)
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (13 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 14/18] drm/amd/display: Fix writeback_info is not removed Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 16/18] drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer Alex Hung
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHAT]
Add a new field to keep track whether a crtc is previously
writeback-enabled.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h          | 1 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index a166d7684719..d8083972e393 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -418,6 +418,7 @@ struct amdgpu_crtc {
 	struct drm_pending_vblank_event *event;
 
 	bool wb_pending;
+	bool wb_enabled;
 	struct drm_writeback_connector *wb_conn;
 };
 
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 fdfcafbaa668..e9efeb62d6b2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8569,9 +8569,13 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
 		if (acrtc)
 			old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
 
+		if (!acrtc->wb_enabled)
+			continue;
+
 		dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
 
 		dm_clear_writeback(dm, dm_old_crtc_state);
+		acrtc->wb_enabled = false;
 	}
 
 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
@@ -9136,9 +9140,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 		if (acrtc)
 			new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
 
+		if (acrtc->wb_enabled)
+			continue;
+
 		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
 
 		dm_set_writeback(dm, dm_new_crtc_state, connector, new_con_state);
+		acrtc->wb_enabled = true;
 	}
 
 	/* Update audio instances for each connector. */
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 16/18] drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (14 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 15/18] drm/amd/display: Add writeback enable field (wb_enabled) Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 17/18] drm/amd/display: Add new set_fc_enable to struct dwbc_funcs Alex Hung
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHY]
Hardware may require different warmup approaches - big buffer or
individual buffers.

[HOW]
Setup warmup for big buffer when it is required by specific hardware.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++
 1 file changed, 6 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 e9efeb62d6b2..9051497eeed9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8718,6 +8718,7 @@ static void dm_set_writeback(struct amdgpu_display_manager *dm,
 			      struct drm_connector_state *new_con_state)
 {
 	struct drm_writeback_connector *wb_conn = drm_connector_to_writeback(connector);
+	struct amdgpu_device *adev = dm->adev;
 	struct amdgpu_crtc *acrtc;
 	struct dc_writeback_info *wb_info;
 	struct pipe_ctx *pipe = NULL;
@@ -8793,6 +8794,11 @@ static void dm_set_writeback(struct amdgpu_display_manager *dm,
 	}
 
 	wb_info->mcif_buf_params.p_vmid = 1;
+	if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0)) {
+		wb_info->mcif_warmup_params.start_address.quad_part = afb->address;
+		wb_info->mcif_warmup_params.region_size =
+			wb_info->mcif_buf_params.luma_pitch * wb_info->dwb_params.dest_height;
+	}
 	wb_info->mcif_warmup_params.p_vmid = 1;
 	wb_info->writeback_source_plane = pipe->plane_state;
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 17/18] drm/amd/display: Add new set_fc_enable to struct dwbc_funcs
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (15 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 16/18] drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-08-16 21:26 ` [PATCH 18/18] drm/amd/display: Disable DWB frame capture to emulate oneshot Alex Hung
  2023-09-05 14:20 ` [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Harry Wentland
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHAT]
Add a function to enable and disable DWB's frame captures.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c  | 23 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h  |  2 ++
 drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h   |  4 ++++
 3 files changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c
index 0d98918bf0fc..1b9d9495f76d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c
@@ -130,6 +130,28 @@ bool dwb3_disable(struct dwbc *dwbc)
 	return true;
 }
 
+void dwb3_set_fc_enable(struct dwbc *dwbc, enum dwb_frame_capture_enable enable)
+{
+	struct dcn30_dwbc *dwbc30 = TO_DCN30_DWBC(dwbc);
+	unsigned int pre_locked;
+
+	REG_GET(DWB_UPDATE_CTRL, DWB_UPDATE_LOCK, &pre_locked);
+
+	/* Lock DWB registers */
+	if (pre_locked == 0)
+		REG_UPDATE(DWB_UPDATE_CTRL, DWB_UPDATE_LOCK, 1);
+
+	/* Disable FC */
+	REG_UPDATE(FC_MODE_CTRL, FC_FRAME_CAPTURE_EN, enable);
+
+	/* Unlock DWB registers */
+	if (pre_locked == 0)
+		REG_UPDATE(DWB_UPDATE_CTRL, DWB_UPDATE_LOCK, 0);
+
+	DC_LOG_DWB("%s dwb3_fc_disabled at inst = %d", __func__, dwbc->inst);
+}
+
+
 bool dwb3_update(struct dwbc *dwbc, struct dc_dwb_params *params)
 {
 	struct dcn30_dwbc *dwbc30 = TO_DCN30_DWBC(dwbc);
@@ -226,6 +248,7 @@ static const struct dwbc_funcs dcn30_dwbc_funcs = {
 	.disable		= dwb3_disable,
 	.update			= dwb3_update,
 	.is_enabled		= dwb3_is_enabled,
+	.set_fc_enable		= dwb3_set_fc_enable,
 	.set_stereo		= dwb3_set_stereo,
 	.set_new_content	= dwb3_set_new_content,
 	.dwb_program_output_csc	= NULL,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h
index fc00ec0a0881..72b9d9daa176 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h
@@ -879,6 +879,8 @@ bool dwb3_update(struct dwbc *dwbc, struct dc_dwb_params *params);
 
 bool dwb3_is_enabled(struct dwbc *dwbc);
 
+void dwb3_set_fc_enable(struct dwbc *dwbc, enum dwb_frame_capture_enable enable);
+
 void dwb3_set_stereo(struct dwbc *dwbc,
 	struct dwb_stereo_params *stereo_params);
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h
index 86b711dcc785..729ca0064e94 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h
@@ -188,6 +188,10 @@ struct dwbc_funcs {
 	bool (*is_enabled)(
 		struct dwbc *dwbc);
 
+	void (*set_fc_enable)(
+		struct dwbc *dwbc,
+		enum dwb_frame_capture_enable enable);
+
 	void (*set_stereo)(
 		struct dwbc *dwbc,
 		struct dwb_stereo_params *stereo_params);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 18/18] drm/amd/display: Disable DWB frame capture to emulate oneshot
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (16 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 17/18] drm/amd/display: Add new set_fc_enable to struct dwbc_funcs Alex Hung
@ 2023-08-16 21:26 ` Alex Hung
  2023-09-05 14:20 ` [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Harry Wentland
  18 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-08-16 21:26 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, Alex Hung, harry.wentland

[WHY]
drm_writeback requires to capture exact one frame in each writeback
call.

[HOW]
frame_capture is disabled after each writeback is completed.

Signed-off-by: Alex Hung <alex.hung@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++-
 .../gpu/drm/amd/display/dc/core/dc_stream.c   | 27 +++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  4 +++
 3 files changed, 44 insertions(+), 1 deletion(-)

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 9051497eeed9..3e3efacec9e9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -589,8 +589,20 @@ static void dm_crtc_high_irq(void *interrupt_params)
 						       list_entry);
 			spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags);
 
-			if (job)
+			if (job) {
+				unsigned int v_total, refresh_hz;
+				struct dc_stream_state *stream = acrtc->dm_irq_params.stream;
+
+				v_total = stream->adjust.v_total_max ?
+					  stream->adjust.v_total_max : stream->timing.v_total;
+				refresh_hz = div_u64((uint64_t) stream->timing.pix_clk_100hz *
+					     100LL, (v_total * stream->timing.h_total));
+				mdelay(1000 / refresh_hz);
+
 				drm_writeback_signal_completion(acrtc->wb_conn, 0);
+				dc_stream_fc_disable_writeback(adev->dm.dc,
+							       acrtc->dm_irq_params.stream, 0);
+			}
 		} else
 			DRM_ERROR("%s: no amdgpu_crtc wb_conn\n", __func__);
 		acrtc->wb_pending = false;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 0e3ade920c4d..b65d9645f6ff 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -538,6 +538,33 @@ bool dc_stream_add_writeback(struct dc *dc,
 	return true;
 }
 
+bool dc_stream_fc_disable_writeback(struct dc *dc,
+		struct dc_stream_state *stream,
+		uint32_t dwb_pipe_inst)
+{
+	struct dwbc *dwb = dc->res_pool->dwbc[dwb_pipe_inst];
+
+	if (stream == NULL) {
+		dm_error("DC: dc_stream is NULL!\n");
+		return false;
+	}
+
+	if (dwb_pipe_inst >= MAX_DWB_PIPES) {
+		dm_error("DC: writeback pipe is invalid!\n");
+		return false;
+	}
+
+	if (stream->num_wb_info > MAX_DWB_PIPES) {
+		dm_error("DC: num_wb_info is invalid!\n");
+		return false;
+	}
+
+	if (dwb->funcs->set_fc_enable)
+		dwb->funcs->set_fc_enable(dwb, DWB_FRAME_CAPTURE_DISABLE);
+
+	return true;
+}
+
 bool dc_stream_remove_writeback(struct dc *dc,
 		struct dc_stream_state *stream,
 		uint32_t dwb_pipe_inst)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 3697ea1d14c1..fac31a56b89d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -455,6 +455,10 @@ bool dc_stream_add_writeback(struct dc *dc,
 		struct dc_stream_state *stream,
 		struct dc_writeback_info *wb_info);
 
+bool dc_stream_fc_disable_writeback(struct dc *dc,
+		struct dc_stream_state *stream,
+		uint32_t dwb_pipe_inst);
+
 bool dc_stream_remove_writeback(struct dc *dc,
 		struct dc_stream_state *stream,
 		uint32_t dwb_pipe_inst);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/18] drm/amd/display: Create one virtual connector in DC
  2023-08-16 21:26 ` [PATCH 02/18] drm/amd/display: Create one virtual connector in DC Alex Hung
@ 2023-08-17 13:58   ` Alex Deucher
  2023-08-17 14:07     ` Harry Wentland
  2023-09-05 18:47   ` Alex Hung
  1 sibling, 1 reply; 31+ messages in thread
From: Alex Deucher @ 2023-08-17 13:58 UTC (permalink / raw
  To: Alex Hung; +Cc: alexander.deucher, harry.wentland, amd-gfx

On Thu, Aug 17, 2023 at 8:45 AM Alex Hung <alex.hung@amd.com> wrote:
>
> From: Harry Wentland <harry.wentland@amd.com>
>
> [WHAT]
> Prepare a virtual connector for writeback.

I presume the main point of virtual connectors in DC is for writeback?
 Would there be a case where the virtual type would be mis-interpreted
in DC as something else?

Alex

>
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 11 +++++++++--
>  drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c |  3 ++-
>  2 files changed, 11 insertions(+), 3 deletions(-)
>
> 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 b1245b732cc9..00254fdfa1f7 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -1675,6 +1675,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
>         init_data.dcn_reg_offsets = adev->reg_offset[DCE_HWIP][0];
>         init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0];
>
> +       /* Enable DWB for tested platforms only */
> +       if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0))
> +               init_data.num_virtual_links = 1;
> +
>         INIT_LIST_HEAD(&adev->dm.da_list);
>
>         retrieve_dmi_info(&adev->dm);
> @@ -4385,6 +4389,11 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
>                         continue;
>                 }
>
> +               link = dc_get_link_at_index(dm->dc, i);
> +
> +               if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
> +                       continue;
> +
>                 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
>                 if (!aconnector)
>                         goto fail;
> @@ -4403,8 +4412,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
>                         goto fail;
>                 }
>
> -               link = dc_get_link_at_index(dm->dc, i);
> -
>                 if (!dc_link_detect_connection_type(link, &new_connection_type))
>                         DRM_ERROR("KMS: Failed to detect connector\n");
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
> index 2a7f47642a44..65e8504e6063 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
> @@ -96,7 +96,8 @@ static void enable_memory_low_power(struct dc *dc)
>         if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
>                 // Power down VPGs
>                 for (i = 0; i < dc->res_pool->stream_enc_count; i++)
> -                       dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
> +                       if (dc->res_pool->stream_enc[i]->vpg)
> +                               dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
>  #if defined(CONFIG_DRM_AMD_DC_FP)
>                 for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
>                         dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
> --
> 2.41.0
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/18] drm/amd/display: Create one virtual connector in DC
  2023-08-17 13:58   ` Alex Deucher
@ 2023-08-17 14:07     ` Harry Wentland
  0 siblings, 0 replies; 31+ messages in thread
From: Harry Wentland @ 2023-08-17 14:07 UTC (permalink / raw
  To: Alex Deucher, Alex Hung; +Cc: alexander.deucher, amd-gfx



On 2023-08-17 09:58, Alex Deucher wrote:
> On Thu, Aug 17, 2023 at 8:45 AM Alex Hung <alex.hung@amd.com> wrote:
>>
>> From: Harry Wentland <harry.wentland@amd.com>
>>
>> [WHAT]
>> Prepare a virtual connector for writeback.
> 
> I presume the main point of virtual connectors in DC is for writeback?
>  Would there be a case where the virtual type would be mis-interpreted
> in DC as something else?
> 

Yes, the only purpose is writeback. In theory one could also use it to
expose a virtual connector, but I'd rather keep that as is, with
amdgpu_vkms handling it.

Without DM making use of it DC shouldn't really be doing anything with
it.

Harry

> Alex
> 
>>
>> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
>> Signed-off-by: Alex Hung <alex.hung@amd.com>
>> ---
>>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 11 +++++++++--
>>  drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c |  3 ++-
>>  2 files changed, 11 insertions(+), 3 deletions(-)
>>
>> 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 b1245b732cc9..00254fdfa1f7 100644
>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>> @@ -1675,6 +1675,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
>>         init_data.dcn_reg_offsets = adev->reg_offset[DCE_HWIP][0];
>>         init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0];
>>
>> +       /* Enable DWB for tested platforms only */
>> +       if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0))
>> +               init_data.num_virtual_links = 1;
>> +
>>         INIT_LIST_HEAD(&adev->dm.da_list);
>>
>>         retrieve_dmi_info(&adev->dm);
>> @@ -4385,6 +4389,11 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
>>                         continue;
>>                 }
>>
>> +               link = dc_get_link_at_index(dm->dc, i);
>> +
>> +               if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
>> +                       continue;
>> +
>>                 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
>>                 if (!aconnector)
>>                         goto fail;
>> @@ -4403,8 +4412,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
>>                         goto fail;
>>                 }
>>
>> -               link = dc_get_link_at_index(dm->dc, i);
>> -
>>                 if (!dc_link_detect_connection_type(link, &new_connection_type))
>>                         DRM_ERROR("KMS: Failed to detect connector\n");
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
>> index 2a7f47642a44..65e8504e6063 100644
>> --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
>> +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
>> @@ -96,7 +96,8 @@ static void enable_memory_low_power(struct dc *dc)
>>         if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
>>                 // Power down VPGs
>>                 for (i = 0; i < dc->res_pool->stream_enc_count; i++)
>> -                       dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
>> +                       if (dc->res_pool->stream_enc[i]->vpg)
>> +                               dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
>>  #if defined(CONFIG_DRM_AMD_DC_FP)
>>                 for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
>>                         dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
>> --
>> 2.41.0
>>


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu
  2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
                   ` (17 preceding siblings ...)
  2023-08-16 21:26 ` [PATCH 18/18] drm/amd/display: Disable DWB frame capture to emulate oneshot Alex Hung
@ 2023-09-05 14:20 ` Harry Wentland
  2023-09-05 18:50   ` Alex Hung
  18 siblings, 1 reply; 31+ messages in thread
From: Harry Wentland @ 2023-09-05 14:20 UTC (permalink / raw
  To: Alex Hung, amd-gfx; +Cc: alexander.deucher

Can we boot the system if we only apply patces 1-3? If not, we might
want to move patch 2 to the end of the series.

A bunch of these patches are from me. Would be good if they can get a
Reviewed-by from you (or someone else, other than me) before merging.

Series is
Reviewed-by: Harry Wentland <harry.wentland@amd.com>

Harry

On 2023-08-16 17:26, Alex Hung wrote:
> This patchset adds drm_writeback connector supports and enables display
> writeback block (DWB) in AMD hardware.
> 
> The function can be tested by IGT's kms_writeback test which also
> requires a number of patches to enable 10bit (DRM_FORMAT_XRGB2101010).
> Patches are available @ https://patchwork.freedesktop.org/series/122536/
> 
> Alex Hung (10):
>   drm/amd/display: Initialize writeback connector
>   drm/amd/display: Hande writeback request from userspace
>   drm/amd/display: Add writeback enable/disable in dc
>   drm/amd/display: Fix writeback_info never got updated
>   drm/amd/display: Validate hw_points_num before using it
>   drm/amd/display: Fix writeback_info is not removed
>   drm/amd/display: Add writeback enable field (wb_enabled)
>   drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer
>   drm/amd/display: Add new set_fc_enable to struct dwbc_funcs
>   drm/amd/display: Disable DWB frame capture to emulate oneshot
> 
> Harry Wentland (8):
>   drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC
>   drm/amd/display: Create one virtual connector in DC
>   drm/amd/display: Skip writeback connector when we get
>     amdgpu_dm_connector
>   drm/amd/display: Return drm_connector from
>     find_first_crtc_matching_connector
>   drm/amd/display: Use drm_connector in create_stream_for_sink
>   drm/amd/display: Use drm_connector in create_validate_stream_for_sink
>   drm/amd/display: Create amdgpu_dm_wb_connector
>   drm/amd/display: Create fake sink and stream for writeback connector
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |   4 +
>  .../gpu/drm/amd/display/amdgpu_dm/Makefile    |  14 +-
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 375 ++++++++++++++++--
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |   3 +
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  22 +-
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   8 +-
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c  | 215 ++++++++++
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h  |  36 ++
>  .../gpu/drm/amd/display/dc/core/dc_stream.c   |  80 +++-
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |   4 +
>  .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c  |  23 ++
>  .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h  |   2 +
>  .../drm/amd/display/dc/dcn30/dcn30_dwb_cm.c   |   3 +
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   4 +
>  .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   3 +-
>  drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h   |   4 +
>  17 files changed, 742 insertions(+), 70 deletions(-)
>  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
>  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
> 


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC
  2023-08-16 21:26 ` [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC Alex Hung
@ 2023-09-05 18:46   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:46 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHY]
> Previously this only excluded build for a few amdgpu_dm
> binaries which makes no sense.
> 
> [HOW]
> Wrap the entire Makefile in "ifneq ($(CONFIG_DRM_AMD_DC),)"
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   drivers/gpu/drm/amd/display/amdgpu_dm/Makefile | 13 ++++++++-----
>   1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> index 8bf94920d23e..063205ecb137 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> @@ -25,22 +25,24 @@
>   
>   
>   
> +ifneq ($(CONFIG_DRM_AMD_DC),)
>   AMDGPUDM = \
>   	amdgpu_dm.o \
>   	amdgpu_dm_plane.o \
>   	amdgpu_dm_crtc.o \
>   	amdgpu_dm_irq.o \
>   	amdgpu_dm_mst_types.o \
> -	amdgpu_dm_color.o
> +	amdgpu_dm_color.o \
> +	amdgpu_dm_services.o \
> +	amdgpu_dm_helpers.o \
> +	amdgpu_dm_pp_smu.o \
> +	amdgpu_dm_psr.o \
> +	amdgpu_dm_replay.o
>   
>   ifdef CONFIG_DRM_AMD_DC_FP
>   AMDGPUDM += dc_fpu.o
>   endif
>   
> -ifneq ($(CONFIG_DRM_AMD_DC),)
> -AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o amdgpu_dm_psr.o amdgpu_dm_replay.o
> -endif
> -
>   AMDGPUDM += amdgpu_dm_hdcp.o
>   
>   ifneq ($(CONFIG_DEBUG_FS),)
> @@ -52,3 +54,4 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc
>   AMDGPU_DM = $(addprefix $(AMDDALPATH)/amdgpu_dm/,$(AMDGPUDM))
>   
>   AMD_DISPLAY_FILES += $(AMDGPU_DM)
> +endif

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/18] drm/amd/display: Create one virtual connector in DC
  2023-08-16 21:26 ` [PATCH 02/18] drm/amd/display: Create one virtual connector in DC Alex Hung
  2023-08-17 13:58   ` Alex Deucher
@ 2023-09-05 18:47   ` Alex Hung
  1 sibling, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:47 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHAT]
> Prepare a virtual connector for writeback.
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 11 +++++++++--
>   drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c |  3 ++-
>   2 files changed, 11 insertions(+), 3 deletions(-)
> 
> 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 b1245b732cc9..00254fdfa1f7 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -1675,6 +1675,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
>   	init_data.dcn_reg_offsets = adev->reg_offset[DCE_HWIP][0];
>   	init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0];
>   
> +	/* Enable DWB for tested platforms only */
> +	if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0))
> +		init_data.num_virtual_links = 1;
> +
>   	INIT_LIST_HEAD(&adev->dm.da_list);
>   
>   	retrieve_dmi_info(&adev->dm);
> @@ -4385,6 +4389,11 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
>   			continue;
>   		}
>   
> +		link = dc_get_link_at_index(dm->dc, i);
> +
> +		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
> +			continue;
> +
>   		aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
>   		if (!aconnector)
>   			goto fail;
> @@ -4403,8 +4412,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
>   			goto fail;
>   		}
>   
> -		link = dc_get_link_at_index(dm->dc, i);
> -
>   		if (!dc_link_detect_connection_type(link, &new_connection_type))
>   			DRM_ERROR("KMS: Failed to detect connector\n");
>   
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
> index 2a7f47642a44..65e8504e6063 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
> @@ -96,7 +96,8 @@ static void enable_memory_low_power(struct dc *dc)
>   	if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
>   		// Power down VPGs
>   		for (i = 0; i < dc->res_pool->stream_enc_count; i++)
> -			dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
> +			if (dc->res_pool->stream_enc[i]->vpg)
> +				dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
>   #if defined(CONFIG_DRM_AMD_DC_FP)
>   		for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
>   			dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/18] drm/amd/display: Skip writeback connector when we get amdgpu_dm_connector
  2023-08-16 21:26 ` [PATCH 04/18] drm/amd/display: Skip writeback connector when we get amdgpu_dm_connector Alex Hung
@ 2023-09-05 18:47   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:47 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHY]
> Writeback connectors are based on a different object:
> drm_writeback_connector, and are therefore different from
> amdgpu_dm_connector. We need to be careful to ensure code
> designed for amdgpu_dm_connector doesn't inadvertently try
> to operate on a drm_writeback_connector.
> 
> [HOW]
> Skip them when connector type is DRM_MODE_CONNECTOR_WRITEBACK.
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 62 +++++++++++++++++--
>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |  3 +
>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 22 +++++--
>   3 files changed, 76 insertions(+), 11 deletions(-)
> 
> 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 445369afcead..363d91d49a3a 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -721,6 +721,10 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
>   
>   	drm_connector_list_iter_begin(dev, &iter);
>   	drm_for_each_connector_iter(connector, &iter) {
> +
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   		if (link && aconnector->dc_link == link) {
>   			if (notify->type == DMUB_NOTIFICATION_HPD)
> @@ -945,6 +949,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device *kdev, int port,
>   
>   	drm_connector_list_iter_begin(dev, &conn_iter);
>   	drm_for_each_connector_iter(connector, &conn_iter) {
> +
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   		if (aconnector->audio_inst != port)
>   			continue;
> @@ -2270,6 +2278,10 @@ static int detect_mst_link_for_all_connectors(struct drm_device *dev)
>   
>   	drm_connector_list_iter_begin(dev, &iter);
>   	drm_for_each_connector_iter(connector, &iter) {
> +
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   		if (aconnector->dc_link->type == dc_connection_mst_branch &&
>   		    aconnector->mst_mgr.aux) {
> @@ -2350,6 +2362,10 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
>   
>   	drm_connector_list_iter_begin(dev, &iter);
>   	drm_for_each_connector_iter(connector, &iter) {
> +
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   		if (aconnector->dc_link->type != dc_connection_mst_branch ||
>   		    aconnector->mst_root)
> @@ -2865,6 +2881,10 @@ static int dm_resume(void *handle)
>   	/* Do detection*/
>   	drm_connector_list_iter_begin(ddev, &iter);
>   	drm_for_each_connector_iter(connector, &iter) {
> +
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   
>   		if (!aconnector->dc_link)
> @@ -3416,6 +3436,9 @@ static void register_hpd_handlers(struct amdgpu_device *adev)
>   	list_for_each_entry(connector,
>   			&dev->mode_config.connector_list, head)	{
>   
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   		dc_link = aconnector->dc_link;
>   
> @@ -5413,10 +5436,13 @@ static void fill_stream_properties_from_drm_display_mode(
>   {
>   	struct dc_crtc_timing *timing_out = &stream->timing;
>   	const struct drm_display_info *info = &connector->display_info;
> -	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
> +	struct amdgpu_dm_connector *aconnector = NULL;
>   	struct hdmi_vendor_infoframe hv_frame;
>   	struct hdmi_avi_infoframe avi_frame;
>   
> +	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> +		aconnector = to_amdgpu_dm_connector(connector);
> +
>   	memset(&hv_frame, 0, sizeof(hv_frame));
>   	memset(&avi_frame, 0, sizeof(avi_frame));
>   
> @@ -6843,6 +6869,9 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
>   
>   	for_each_new_connector_in_state(state, connector, new_con_state, i) {
>   
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   
>   		if (!aconnector->mst_output_port)
> @@ -8392,6 +8421,9 @@ static void amdgpu_dm_commit_audio(struct drm_device *dev,
>   		if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
>   			continue;
>   
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   notify:
>   		aconnector = to_amdgpu_dm_connector(connector);
>   
> @@ -8425,6 +8457,9 @@ static void amdgpu_dm_commit_audio(struct drm_device *dev,
>   		if (!status)
>   			continue;
>   
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   
>   		mutex_lock(&adev->dm.audio_lock);
> @@ -8686,7 +8721,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
>   	for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
>   		struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
>   		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
> -		struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
> +		struct amdgpu_dm_connector *aconnector;
> +
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
> +		aconnector = to_amdgpu_dm_connector(connector);
>   
>   		if (!adev->dm.hdcp_workqueue)
>   			continue;
> @@ -9029,10 +9069,15 @@ static int dm_force_atomic_commit(struct drm_connector *connector)
>   void dm_restore_drm_connector_state(struct drm_device *dev,
>   				    struct drm_connector *connector)
>   {
> -	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
> +	struct amdgpu_dm_connector *aconnector;
>   	struct amdgpu_crtc *disconnected_acrtc;
>   	struct dm_crtc_state *acrtc_state;
>   
> +	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +		return;
> +
> +	aconnector = to_amdgpu_dm_connector(connector);
> +
>   	if (!aconnector->dc_sink || !connector->state || !connector->encoder)
>   		return;
>   
> @@ -9109,12 +9154,16 @@ static void get_freesync_config_for_crtc(
>   	struct dm_connector_state *new_con_state)
>   {
>   	struct mod_freesync_config config = {0};
> -	struct amdgpu_dm_connector *aconnector =
> -			to_amdgpu_dm_connector(new_con_state->base.connector);
> +	struct amdgpu_dm_connector *aconnector;
>   	struct drm_display_mode *mode = &new_crtc_state->base.mode;
>   	int vrefresh = drm_mode_vrefresh(mode);
>   	bool fs_vid_mode = false;
>   
> +	if (new_con_state->base.connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +		return;
> +
> +	aconnector = to_amdgpu_dm_connector(new_con_state->base.connector);
> +
>   	new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
>   					vrefresh >= aconnector->min_vfreq &&
>   					vrefresh <= aconnector->max_vfreq;
> @@ -9898,6 +9947,9 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
>   		if (conn_state->crtc != crtc)
>   			continue;
>   
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
>   		aconnector = to_amdgpu_dm_connector(connector);
>   		if (!aconnector->mst_output_port || !aconnector->mst_root)
>   			aconnector = NULL;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
> index 52ecfa746b54..f936a35fa9eb 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
> @@ -326,6 +326,9 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
>   			if (!connector->state || connector->state->crtc != crtc)
>   				continue;
>   
> +			if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +				continue;
> +
>   			aconn = to_amdgpu_dm_connector(connector);
>   			break;
>   		}
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
> index 51467f132c26..58b880acb087 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
> @@ -894,10 +894,15 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
>   
>   	drm_connector_list_iter_begin(dev, &iter);
>   	drm_for_each_connector_iter(connector, &iter) {
> -		struct amdgpu_dm_connector *amdgpu_dm_connector =
> -				to_amdgpu_dm_connector(connector);
> +		struct amdgpu_dm_connector *amdgpu_dm_connector;
> +		const struct dc_link *dc_link;
>   
> -		const struct dc_link *dc_link = amdgpu_dm_connector->dc_link;
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
> +		amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
> +
> +		dc_link = amdgpu_dm_connector->dc_link;
>   
>   		if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
>   			dc_interrupt_set(adev->dm.dc,
> @@ -930,9 +935,14 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
>   
>   	drm_connector_list_iter_begin(dev, &iter);
>   	drm_for_each_connector_iter(connector, &iter) {
> -		struct amdgpu_dm_connector *amdgpu_dm_connector =
> -				to_amdgpu_dm_connector(connector);
> -		const struct dc_link *dc_link = amdgpu_dm_connector->dc_link;
> +		struct amdgpu_dm_connector *amdgpu_dm_connector;
> +		const struct dc_link *dc_link;
> +
> +		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +			continue;
> +
> +		amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
> +		dc_link = amdgpu_dm_connector->dc_link;
>   
>   		if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
>   			dc_interrupt_set(adev->dm.dc,

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 05/18] drm/amd/display: Return drm_connector from find_first_crtc_matching_connector
  2023-08-16 21:26 ` [PATCH 05/18] drm/amd/display: Return drm_connector from find_first_crtc_matching_connector Alex Hung
@ 2023-09-05 18:47   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:47 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHY]
> We will be dealing with two types of connector: amdgpu_dm_connector
> and drm_writeback_connector.
> 
> [HOW]
> We want to find both and then cast to the appriopriate type afterwards.
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c         | 8 +++++---
>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h         | 2 +-
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c   | 4 +++-
>   3 files changed, 9 insertions(+), 5 deletions(-)
> 
> 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 363d91d49a3a..7bd3ec84ff2e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -2630,7 +2630,7 @@ static int dm_suspend(void *handle)
>   	return 0;
>   }
>   
> -struct amdgpu_dm_connector *
> +struct drm_connector *
>   amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
>   					     struct drm_crtc *crtc)
>   {
> @@ -2643,7 +2643,7 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
>   		crtc_from_state = new_con_state->crtc;
>   
>   		if (crtc_from_state == crtc)
> -			return to_amdgpu_dm_connector(connector);
> +			return connector;
>   	}
>   
>   	return NULL;
> @@ -9263,6 +9263,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   	 * update changed items
>   	 */
>   	struct amdgpu_crtc *acrtc = NULL;
> +	struct drm_connector *connector = NULL;
>   	struct amdgpu_dm_connector *aconnector = NULL;
>   	struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL;
>   	struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL;
> @@ -9272,7 +9273,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   	dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
>   	dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
>   	acrtc = to_amdgpu_crtc(crtc);
> -	aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
> +	connector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
> +	aconnector = to_amdgpu_dm_connector(connector);
>   
>   	/* TODO This hack should go away */
>   	if (aconnector && enable) {
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index a2d34be82613..5a8d07a27e9b 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -836,7 +836,7 @@ struct dc_stream_state *
>   int dm_atomic_get_state(struct drm_atomic_state *state,
>   			struct dm_atomic_state **dm_state);
>   
> -struct amdgpu_dm_connector *
> +struct drm_connector *
>   amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
>   					     struct drm_crtc *crtc);
>   
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 57230661132b..1975b9d96cb8 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -1494,14 +1494,16 @@ int pre_validate_dsc(struct drm_atomic_state *state,
>   		int ind = find_crtc_index_in_state_by_stream(state, stream);
>   
>   		if (ind >= 0) {
> +			struct drm_connector *connector;
>   			struct amdgpu_dm_connector *aconnector;
>   			struct drm_connector_state *drm_new_conn_state;
>   			struct dm_connector_state *dm_new_conn_state;
>   			struct dm_crtc_state *dm_old_crtc_state;
>   
> -			aconnector =
> +			connector =
>   				amdgpu_dm_find_first_crtc_matching_connector(state,
>   									     state->crtcs[ind].ptr);
> +			aconnector = to_amdgpu_dm_connector(connector);
>   			drm_new_conn_state =
>   				drm_atomic_get_new_connector_state(state,
>   								   &aconnector->base);

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/18] drm/amd/display: Use drm_connector in create_stream_for_sink
  2023-08-16 21:26 ` [PATCH 06/18] drm/amd/display: Use drm_connector in create_stream_for_sink Alex Hung
@ 2023-09-05 18:48   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:48 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHAT]
> We need to use this function for both amdgpu_dm_connectors
> and drm_writeback_connectors. Modify it to operate on
> a drm_connector as a common base.
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 65 +++++++++++--------
>   1 file changed, 37 insertions(+), 28 deletions(-)
> 
> 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 7bd3ec84ff2e..a7d2a3f35f74 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5455,6 +5455,7 @@ static void fill_stream_properties_from_drm_display_mode(
>   			&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
>   		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
>   	else if (drm_mode_is_420_also(info, mode_in)
> +			&& aconnector
>   			&& aconnector->force_yuv420_output)
>   		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
>   	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
> @@ -5490,7 +5491,7 @@ static void fill_stream_properties_from_drm_display_mode(
>   		timing_out->hdmi_vic = hv_frame.vic;
>   	}
>   
> -	if (is_freesync_video_mode(mode_in, aconnector)) {
> +	if (aconnector && is_freesync_video_mode(mode_in, aconnector)) {
>   		timing_out->h_addressable = mode_in->hdisplay;
>   		timing_out->h_total = mode_in->htotal;
>   		timing_out->h_sync_width = mode_in->hsync_end - mode_in->hsync_start;
> @@ -5966,14 +5967,14 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
>   }
>   
>   static struct dc_stream_state *
> -create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
> +create_stream_for_sink(struct drm_connector *connector,
>   		       const struct drm_display_mode *drm_mode,
>   		       const struct dm_connector_state *dm_state,
>   		       const struct dc_stream_state *old_stream,
>   		       int requested_bpc)
>   {
> +	struct amdgpu_dm_connector *aconnector = NULL;
>   	struct drm_display_mode *preferred_mode = NULL;
> -	struct drm_connector *drm_connector;
>   	const struct drm_connector_state *con_state = &dm_state->base;
>   	struct dc_stream_state *stream = NULL;
>   	struct drm_display_mode mode;
> @@ -5992,20 +5993,22 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   	drm_mode_init(&mode, drm_mode);
>   	memset(&saved_mode, 0, sizeof(saved_mode));
>   
> -	if (aconnector == NULL) {
> -		DRM_ERROR("aconnector is NULL!\n");
> +	if (connector == NULL) {
> +		DRM_ERROR("connector is NULL!\n");
>   		return stream;
>   	}
>   
> -	drm_connector = &aconnector->base;
> -
> -	if (!aconnector->dc_sink) {
> -		sink = create_fake_sink(aconnector);
> -		if (!sink)
> -			return stream;
> -	} else {
> -		sink = aconnector->dc_sink;
> -		dc_sink_retain(sink);
> +	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
> +		aconnector = NULL;
> +		aconnector = to_amdgpu_dm_connector(connector);
> +		if (!aconnector->dc_sink) {
> +			sink = create_fake_sink(aconnector);
> +			if (!sink)
> +				return stream;
> +		} else {
> +			sink = aconnector->dc_sink;
> +			dc_sink_retain(sink);
> +		}
>   	}
>   
>   	stream = dc_create_stream_for_sink(sink);
> @@ -6015,12 +6018,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   		goto finish;
>   	}
>   
> +	/* We leave this NULL for writeback connectors */
>   	stream->dm_stream_context = aconnector;
>   
>   	stream->timing.flags.LTE_340MCSC_SCRAMBLE =
> -		drm_connector->display_info.hdmi.scdc.scrambling.low_rates;
> +		connector->display_info.hdmi.scdc.scrambling.low_rates;
>   
> -	list_for_each_entry(preferred_mode, &aconnector->base.modes, head) {
> +	list_for_each_entry(preferred_mode, &connector->modes, head) {
>   		/* Search for preferred mode */
>   		if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) {
>   			native_mode_found = true;
> @@ -6029,7 +6033,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   	}
>   	if (!native_mode_found)
>   		preferred_mode = list_first_entry_or_null(
> -				&aconnector->base.modes,
> +				&connector->modes,
>   				struct drm_display_mode,
>   				head);
>   
> @@ -6043,7 +6047,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   		 * and the modelist may not be filled in time.
>   		 */
>   		DRM_DEBUG_DRIVER("No preferred mode found\n");
> -	} else {
> +	} else if (aconnector) {
>   		recalculate_timing = is_freesync_video_mode(&mode, aconnector);
>   		if (recalculate_timing) {
>   			freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
> @@ -6068,13 +6072,17 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   	 */
>   	if (!scale || mode_refresh != preferred_refresh)
>   		fill_stream_properties_from_drm_display_mode(
> -			stream, &mode, &aconnector->base, con_state, NULL,
> +			stream, &mode, connector, con_state, NULL,
>   			requested_bpc);
>   	else
>   		fill_stream_properties_from_drm_display_mode(
> -			stream, &mode, &aconnector->base, con_state, old_stream,
> +			stream, &mode, connector, con_state, old_stream,
>   			requested_bpc);
>   
> +	/* The rest isn't needed for writeback connectors */
> +	if (!aconnector)
> +		goto finish;
> +
>   	if (aconnector->timing_changed) {
>   		DC_LOG_DEBUG("%s: overriding timing for automated test, bpc %d, changing to %d\n",
>   				__func__,
> @@ -6092,7 +6100,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   
>   	fill_audio_info(
>   		&stream->audio_info,
> -		drm_connector,
> +		connector,
>   		sink);
>   
>   	update_stream_signal(stream, sink);
> @@ -6551,7 +6559,7 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   	enum dc_status dc_result = DC_OK;
>   
>   	do {
> -		stream = create_stream_for_sink(aconnector, drm_mode,
> +		stream = create_stream_for_sink(connector, drm_mode,
>   						dm_state, old_stream,
>   						requested_bpc);
>   		if (stream == NULL) {
> @@ -9274,15 +9282,16 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   	dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
>   	acrtc = to_amdgpu_crtc(crtc);
>   	connector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
> -	aconnector = to_amdgpu_dm_connector(connector);
> +	if (connector && connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
> +		aconnector = to_amdgpu_dm_connector(connector);
>   
>   	/* TODO This hack should go away */
> -	if (aconnector && enable) {
> +	if (connector && enable) {
>   		/* Make sure fake sink is created in plug-in scenario */
>   		drm_new_conn_state = drm_atomic_get_new_connector_state(state,
> -							    &aconnector->base);
> +									connector);
>   		drm_old_conn_state = drm_atomic_get_old_connector_state(state,
> -							    &aconnector->base);
> +									connector);
>   
>   		if (IS_ERR(drm_new_conn_state)) {
>   			ret = PTR_ERR_OR_ZERO(drm_new_conn_state);
> @@ -9429,7 +9438,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   		 * added MST connectors not found in existing crtc_state in the chained mode
>   		 * TODO: need to dig out the root cause of that
>   		 */
> -		if (!aconnector)
> +		if (!connector)
>   			goto skip_modeset;
>   
>   		if (modereset_required(new_crtc_state))
> @@ -9472,7 +9481,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   	 * We want to do dc stream updates that do not require a
>   	 * full modeset below.
>   	 */
> -	if (!(enable && aconnector && new_crtc_state->active))
> +	if (!(enable && connector && new_crtc_state->active))
>   		return 0;
>   	/*
>   	 * Given above conditions, the dc state cannot be NULL because:

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 07/18] drm/amd/display: Use drm_connector in create_validate_stream_for_sink
  2023-08-16 21:26 ` [PATCH 07/18] drm/amd/display: Use drm_connector in create_validate_stream_for_sink Alex Hung
@ 2023-09-05 18:48   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:48 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHAT]
> Again, we need to use this function for writeback connectors,
> which are not of type amdgpu_dm_connector. Use the common base
> drm_connector instead.
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 ++++++++++++++-----
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
>   .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  6 ++---
>   3 files changed, 19 insertions(+), 11 deletions(-)
> 
> 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 a7d2a3f35f74..33e7c463a0d0 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -6546,18 +6546,21 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc,
>   }
>   
>   struct dc_stream_state *
> -create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
> +create_validate_stream_for_sink(struct drm_connector *connector,
>   				const struct drm_display_mode *drm_mode,
>   				const struct dm_connector_state *dm_state,
>   				const struct dc_stream_state *old_stream)
>   {
> -	struct drm_connector *connector = &aconnector->base;
> +	struct amdgpu_dm_connector *aconnector = NULL;
>   	struct amdgpu_device *adev = drm_to_adev(connector->dev);
>   	struct dc_stream_state *stream;
>   	const struct drm_connector_state *drm_state = dm_state ? &dm_state->base : NULL;
>   	int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8;
>   	enum dc_status dc_result = DC_OK;
>   
> +	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +		aconnector = to_amdgpu_dm_connector(connector);
> +
>   	do {
>   		stream = create_stream_for_sink(connector, drm_mode,
>   						dm_state, old_stream,
> @@ -6568,10 +6571,14 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   		}
>   
>   		dc_result = dc_validate_stream(adev->dm.dc, stream);
> +
> +		if (!aconnector) /* writeback connector */
> +			return stream;
> +
>   		if (dc_result == DC_OK && stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
>   			dc_result = dm_dp_mst_is_port_support_mode(aconnector, stream);
>   
> -		if (dc_result == DC_OK)
> +		if (dc_result == DC_OK && connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
>   			dc_result = dm_validate_stream_and_context(adev->dm.dc, stream);
>   
>   		if (dc_result != DC_OK) {
> @@ -6593,7 +6600,7 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>   		DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n");
>   
>   		aconnector->force_yuv420_output = true;
> -		stream = create_validate_stream_for_sink(aconnector, drm_mode,
> +		stream = create_validate_stream_for_sink(connector, drm_mode,
>   						dm_state, old_stream);
>   		aconnector->force_yuv420_output = false;
>   	}
> @@ -6608,6 +6615,9 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
>   	struct dc_sink *dc_sink;
>   	/* TODO: Unhardcode stream count */
>   	struct dc_stream_state *stream;
> +	/* we always have an amdgpu_dm_connector here since we got
> +	 * here via the amdgpu_dm_connector_helper_funcs
> +	 */
>   	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
>   
>   	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
> @@ -6630,7 +6640,7 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
>   		goto fail;
>   	}
>   
> -	stream = create_validate_stream_for_sink(aconnector, mode,
> +	stream = create_validate_stream_for_sink(connector, mode,
>   						 to_dm_connector_state(connector->state),
>   						 NULL);
>   	if (stream) {
> @@ -9304,7 +9314,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   		if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
>   			goto skip_modeset;
>   
> -		new_stream = create_validate_stream_for_sink(aconnector,
> +		new_stream = create_validate_stream_for_sink(connector,
>   							     &new_crtc_state->mode,
>   							     dm_new_conn_state,
>   							     dm_old_crtc_state->stream);
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index 5a8d07a27e9b..a2d0ab881c44 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -828,7 +828,7 @@ int amdgpu_dm_process_dmub_set_config_sync(struct dc_context *ctx, unsigned int
>   bool check_seamless_boot_capability(struct amdgpu_device *adev);
>   
>   struct dc_stream_state *
> -	create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
> +	create_validate_stream_for_sink(struct drm_connector *connector,
>   					const struct drm_display_mode *drm_mode,
>   					const struct dm_connector_state *dm_state,
>   					const struct dc_stream_state *old_stream);
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> index 1975b9d96cb8..687dba32cde3 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
> @@ -1495,7 +1495,6 @@ int pre_validate_dsc(struct drm_atomic_state *state,
>   
>   		if (ind >= 0) {
>   			struct drm_connector *connector;
> -			struct amdgpu_dm_connector *aconnector;
>   			struct drm_connector_state *drm_new_conn_state;
>   			struct dm_connector_state *dm_new_conn_state;
>   			struct dm_crtc_state *dm_old_crtc_state;
> @@ -1503,15 +1502,14 @@ int pre_validate_dsc(struct drm_atomic_state *state,
>   			connector =
>   				amdgpu_dm_find_first_crtc_matching_connector(state,
>   									     state->crtcs[ind].ptr);
> -			aconnector = to_amdgpu_dm_connector(connector);
>   			drm_new_conn_state =
>   				drm_atomic_get_new_connector_state(state,
> -								   &aconnector->base);
> +								   connector);
>   			dm_new_conn_state = to_dm_connector_state(drm_new_conn_state);
>   			dm_old_crtc_state = to_dm_crtc_state(state->crtcs[ind].old_state);
>   
>   			local_dc_state->streams[i] =
> -				create_validate_stream_for_sink(aconnector,
> +				create_validate_stream_for_sink(connector,
>   								&state->crtcs[ind].new_state->mode,
>   								dm_new_conn_state,
>   								dm_old_crtc_state->stream);

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/18] drm/amd/display: Create amdgpu_dm_wb_connector
  2023-08-16 21:26 ` [PATCH 08/18] drm/amd/display: Create amdgpu_dm_wb_connector Alex Hung
@ 2023-09-05 18:48   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:48 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHY]
> We need to track the dc_link and it would get confusing if
> re-using the amdgpu_dm_connector.
> 
> [HOW]
> Creating new amdgpu_dm_wb_connector.
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c    |  5 +++--
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h    |  8 ++++++++
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c | 16 +++++++++++-----
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h |  3 ++-
>   4 files changed, 24 insertions(+), 8 deletions(-)
> 
> 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 33e7c463a0d0..b12e8393fef3 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4416,14 +4416,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
>   		link = dc_get_link_at_index(dm->dc, i);
>   
>   		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) {
> -			struct drm_writeback_connector *wbcon = kzalloc(sizeof(*wbcon), GFP_KERNEL);
> +			struct amdgpu_dm_wb_connector *wbcon = kzalloc(sizeof(*wbcon), GFP_KERNEL);
>   
>   			if (!wbcon) {
>   				DRM_ERROR("KMS: Failed to allocate writeback connector\n");
>   				continue;
>   			}
>   
> -			if (amdgpu_dm_wb_connector_init(dm, wbcon)) {
> +			if (amdgpu_dm_wb_connector_init(dm, wbcon, i)) {
>   				DRM_ERROR("KMS: Failed to initialize writeback connector\n");
>   				kfree(wbcon);
>   				continue;
> @@ -7487,6 +7487,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
>   	struct dc_link *link = dc_get_link_at_index(dc, link_index);
>   	struct amdgpu_i2c_adapter *i2c;
>   
> +	/* Not needed for writeback connector */
>   	link->priv = aconnector;
>   
>   
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index a2d0ab881c44..46acf89e5a45 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -32,6 +32,7 @@
>   #include <drm/drm_crtc.h>
>   #include <drm/drm_plane.h>
>   #include "link_service_types.h"
> +#include <drm/drm_writeback.h>
>   
>   /*
>    * This file contains the definition for amdgpu_display_manager
> @@ -714,6 +715,13 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
>   
>   #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
>   
> +struct amdgpu_dm_wb_connector {
> +	struct drm_writeback_connector base;
> +	struct dc_link *link;
> +};
> +
> +#define to_amdgpu_dm_wb_connector(x) container_of(x, struct amdgpu_dm_wb_connector, base)
> +
>   extern const struct amdgpu_ip_block_version dm_ip_block;
>   
>   struct dm_plane_state {
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
> index 74e656696d8e..b3e634b0f712 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
> @@ -30,6 +30,7 @@
>   #include "amdgpu_dm.h"
>   #include "amdgpu_dm_wb.h"
>   #include "amdgpu_display.h"
> +#include "dc.h"
>   
>   #include <drm/drm_atomic_state_helper.h>
>   #include <drm/drm_modeset_helper_vtables.h>
> @@ -183,13 +184,18 @@ static const struct drm_connector_helper_funcs amdgpu_dm_wb_conn_helper_funcs =
>   };
>   
>   int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
> -				struct drm_writeback_connector *wbcon)
> +				struct amdgpu_dm_wb_connector *wbcon,
> +				uint32_t link_index)
>   {
> +	struct dc *dc = dm->dc;
> +	struct dc_link *link = dc_get_link_at_index(dc, link_index);
>   	int res = 0;
>   
> -	drm_connector_helper_add(&wbcon->base, &amdgpu_dm_wb_conn_helper_funcs);
> +	wbcon->link = link;
>   
> -	res = drm_writeback_connector_init(&dm->adev->ddev, wbcon,
> +	drm_connector_helper_add(&wbcon->base.base, &amdgpu_dm_wb_conn_helper_funcs);
> +
> +	res = drm_writeback_connector_init(&dm->adev->ddev, &wbcon->base,
>   					    &amdgpu_dm_wb_connector_funcs,
>   					    &amdgpu_dm_wb_encoder_helper_funcs,
>   					    amdgpu_dm_wb_formats,
> @@ -202,8 +208,8 @@ int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
>   	 * Some of the properties below require access to state, like bpc.
>   	 * Allocate some default initial connector state with our reset helper.
>   	 */
> -	if (wbcon->base.funcs->reset)
> -		wbcon->base.funcs->reset(&wbcon->base);
> +	if (wbcon->base.base.funcs->reset)
> +		wbcon->base.base.funcs->reset(&wbcon->base.base);
>   
>   	return 0;
>   }
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
> index 0bc9df7e7ee1..13d31c857dee 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
> @@ -30,6 +30,7 @@
>   #include <drm/drm_writeback.h>
>   
>   int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,
> -				struct drm_writeback_connector *wbcon);
> +				struct amdgpu_dm_wb_connector *dm_wbcon,
> +				uint32_t link_index);
>   
>   #endif

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 09/18] drm/amd/display: Create fake sink and stream for writeback connector
  2023-08-16 21:26 ` [PATCH 09/18] drm/amd/display: Create fake sink and stream for writeback connector Alex Hung
@ 2023-09-05 18:48   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:48 UTC (permalink / raw
  To: amd-gfx; +Cc: alexander.deucher, harry.wentland

Reviewed-by: Alex Hung <alex.hung@amd.com>

On 2023-08-16 15:26, Alex Hung wrote:
> From: Harry Wentland <harry.wentland@amd.com>
> 
> [WHAT]
> Writeback connectors don't have a physical sink but DC still
> needs a sink to function. Create a fake sink and stream for
> writeback connectors
> 
> Signed-off-by: Harry Wentland <harry.wentland@amd.com>
> Signed-off-by: Alex Hung <alex.hung@amd.com>
> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 33 ++++++++++++-------
>   1 file changed, 22 insertions(+), 11 deletions(-)
> 
> 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 b12e8393fef3..82f00af14ada 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5611,13 +5611,13 @@ decide_crtc_timing_for_drm_display_mode(struct drm_display_mode *drm_mode,
>   }
>   
>   static struct dc_sink *
> -create_fake_sink(struct amdgpu_dm_connector *aconnector)
> +create_fake_sink(struct dc_link *link)
>   {
>   	struct dc_sink_init_data sink_init_data = { 0 };
>   	struct dc_sink *sink = NULL;
>   
> -	sink_init_data.link = aconnector->dc_link;
> -	sink_init_data.sink_signal = aconnector->dc_link->connector_signal;
> +	sink_init_data.link = link;
> +	sink_init_data.sink_signal = link->connector_signal;
>   
>   	sink = dc_sink_create(&sink_init_data);
>   	if (!sink) {
> @@ -5988,6 +5988,7 @@ create_stream_for_sink(struct drm_connector *connector,
>   	enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
>   	struct dsc_dec_dpcd_caps dsc_caps;
>   
> +	struct dc_link *link = NULL;
>   	struct dc_sink *sink = NULL;
>   
>   	drm_mode_init(&mode, drm_mode);
> @@ -6001,14 +6002,24 @@ create_stream_for_sink(struct drm_connector *connector,
>   	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
>   		aconnector = NULL;
>   		aconnector = to_amdgpu_dm_connector(connector);
> -		if (!aconnector->dc_sink) {
> -			sink = create_fake_sink(aconnector);
> -			if (!sink)
> -				return stream;
> -		} else {
> -			sink = aconnector->dc_sink;
> -			dc_sink_retain(sink);
> -		}
> +		link = aconnector->dc_link;
> +	} else {
> +		struct drm_writeback_connector *wbcon = NULL;
> +		struct amdgpu_dm_wb_connector *dm_wbcon = NULL;
> +
> +		wbcon = drm_connector_to_writeback(connector);
> +		dm_wbcon = to_amdgpu_dm_wb_connector(wbcon);
> +		link = dm_wbcon->link;
> +	}
> +
> +	if (!aconnector || !aconnector->dc_sink) {
> +		sink = create_fake_sink(link);
> +		if (!sink)
> +			return stream;
> +
> +	} else {
> +		sink = aconnector->dc_sink;
> +		dc_sink_retain(sink);
>   	}
>   
>   	stream = dc_create_stream_for_sink(sink);

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu
  2023-09-05 14:20 ` [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Harry Wentland
@ 2023-09-05 18:50   ` Alex Hung
  0 siblings, 0 replies; 31+ messages in thread
From: Alex Hung @ 2023-09-05 18:50 UTC (permalink / raw
  To: Harry Wentland, amd-gfx; +Cc: alexander.deucher



On 2023-09-05 08:20, Harry Wentland wrote:
> Can we boot the system if we only apply patces 1-3? If not, we might
> want to move patch 2 to the end of the series.

The system boots with the first three patches namely

drm/amd/display: Initialize writeback connector
drm/amd/display: Create one virtual connector in DC
drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC


> 
> A bunch of these patches are from me. Would be good if they can get a
> Reviewed-by from you (or someone else, other than me) before merging.

"Reviewed-by" are sent to Harry's patches.

> 
> Series is
> Reviewed-by: Harry Wentland <harry.wentland@amd.com>
> 
> Harry
> 
> On 2023-08-16 17:26, Alex Hung wrote:
>> This patchset adds drm_writeback connector supports and enables display
>> writeback block (DWB) in AMD hardware.
>>
>> The function can be tested by IGT's kms_writeback test which also
>> requires a number of patches to enable 10bit (DRM_FORMAT_XRGB2101010).
>> Patches are available @ https://patchwork.freedesktop.org/series/122536/
>>
>> Alex Hung (10):
>>    drm/amd/display: Initialize writeback connector
>>    drm/amd/display: Hande writeback request from userspace
>>    drm/amd/display: Add writeback enable/disable in dc
>>    drm/amd/display: Fix writeback_info never got updated
>>    drm/amd/display: Validate hw_points_num before using it
>>    drm/amd/display: Fix writeback_info is not removed
>>    drm/amd/display: Add writeback enable field (wb_enabled)
>>    drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer
>>    drm/amd/display: Add new set_fc_enable to struct dwbc_funcs
>>    drm/amd/display: Disable DWB frame capture to emulate oneshot
>>
>> Harry Wentland (8):
>>    drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC
>>    drm/amd/display: Create one virtual connector in DC
>>    drm/amd/display: Skip writeback connector when we get
>>      amdgpu_dm_connector
>>    drm/amd/display: Return drm_connector from
>>      find_first_crtc_matching_connector
>>    drm/amd/display: Use drm_connector in create_stream_for_sink
>>    drm/amd/display: Use drm_connector in create_validate_stream_for_sink
>>    drm/amd/display: Create amdgpu_dm_wb_connector
>>    drm/amd/display: Create fake sink and stream for writeback connector
>>
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |   4 +
>>   .../gpu/drm/amd/display/amdgpu_dm/Makefile    |  14 +-
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 375 ++++++++++++++++--
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
>>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |   3 +
>>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  22 +-
>>   .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   8 +-
>>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c  | 215 ++++++++++
>>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h  |  36 ++
>>   .../gpu/drm/amd/display/dc/core/dc_stream.c   |  80 +++-
>>   drivers/gpu/drm/amd/display/dc/dc_stream.h    |   4 +
>>   .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c  |  23 ++
>>   .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h  |   2 +
>>   .../drm/amd/display/dc/dcn30/dcn30_dwb_cm.c   |   3 +
>>   .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   4 +
>>   .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   3 +-
>>   drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h   |   4 +
>>   17 files changed, 742 insertions(+), 70 deletions(-)
>>   create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
>>   create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
>>
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2023-09-05 18:50 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-16 21:26 [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Alex Hung
2023-08-16 21:26 ` [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC Alex Hung
2023-09-05 18:46   ` Alex Hung
2023-08-16 21:26 ` [PATCH 02/18] drm/amd/display: Create one virtual connector in DC Alex Hung
2023-08-17 13:58   ` Alex Deucher
2023-08-17 14:07     ` Harry Wentland
2023-09-05 18:47   ` Alex Hung
2023-08-16 21:26 ` [PATCH 03/18] drm/amd/display: Initialize writeback connector Alex Hung
2023-08-16 21:26 ` [PATCH 04/18] drm/amd/display: Skip writeback connector when we get amdgpu_dm_connector Alex Hung
2023-09-05 18:47   ` Alex Hung
2023-08-16 21:26 ` [PATCH 05/18] drm/amd/display: Return drm_connector from find_first_crtc_matching_connector Alex Hung
2023-09-05 18:47   ` Alex Hung
2023-08-16 21:26 ` [PATCH 06/18] drm/amd/display: Use drm_connector in create_stream_for_sink Alex Hung
2023-09-05 18:48   ` Alex Hung
2023-08-16 21:26 ` [PATCH 07/18] drm/amd/display: Use drm_connector in create_validate_stream_for_sink Alex Hung
2023-09-05 18:48   ` Alex Hung
2023-08-16 21:26 ` [PATCH 08/18] drm/amd/display: Create amdgpu_dm_wb_connector Alex Hung
2023-09-05 18:48   ` Alex Hung
2023-08-16 21:26 ` [PATCH 09/18] drm/amd/display: Create fake sink and stream for writeback connector Alex Hung
2023-09-05 18:48   ` Alex Hung
2023-08-16 21:26 ` [PATCH 10/18] drm/amd/display: Hande writeback request from userspace Alex Hung
2023-08-16 21:26 ` [PATCH 11/18] drm/amd/display: Add writeback enable/disable in dc Alex Hung
2023-08-16 21:26 ` [PATCH 12/18] drm/amd/display: Fix writeback_info never got updated Alex Hung
2023-08-16 21:26 ` [PATCH 13/18] drm/amd/display: Validate hw_points_num before using it Alex Hung
2023-08-16 21:26 ` [PATCH 14/18] drm/amd/display: Fix writeback_info is not removed Alex Hung
2023-08-16 21:26 ` [PATCH 15/18] drm/amd/display: Add writeback enable field (wb_enabled) Alex Hung
2023-08-16 21:26 ` [PATCH 16/18] drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer Alex Hung
2023-08-16 21:26 ` [PATCH 17/18] drm/amd/display: Add new set_fc_enable to struct dwbc_funcs Alex Hung
2023-08-16 21:26 ` [PATCH 18/18] drm/amd/display: Disable DWB frame capture to emulate oneshot Alex Hung
2023-09-05 14:20 ` [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu Harry Wentland
2023-09-05 18:50   ` Alex Hung

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.