* [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.