From c84f512387fcda784b907c4754b8c4088432fa5d Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Wed, 28 Jun 2023 11:55:50 -0400 Subject: drm/amd/display: Add Replay supported/enabled checks - Add checks for Cursor update and dirty rects (sending updates to dmub) - Add checks for dc_notify_vsync, and fbc and subvp Signed-off-by: Bhawanpreet Lakha Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ++++++ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 3 +++ drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 5 +++++ 3 files changed, 14 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 8504e6ee9582..508d5ea89b8b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3289,6 +3289,9 @@ static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_s && stream->ctx->dce_version >= DCN_VERSION_3_1) return true; + if (stream->link->replay_settings.config.replay_supported) + return true; + return false; } @@ -5173,6 +5176,9 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo if (link->psr_settings.psr_feature_enabled) return; + if (link->replay_settings.replay_feature_enabled) + return; + /*find primary pipe associated with stream*/ for (i = 0; i < MAX_PIPES; i++) { pipe = &dc->current_state->res_ctx.pipe_ctx[i]; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 8c75f7510880..530b85a50b03 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -897,6 +897,9 @@ static bool dc_dmub_should_update_cursor_data(struct pipe_ctx *pipe_ctx) pipe_ctx->stream->ctx->dce_version >= DCN_VERSION_3_1) return true; + if (pipe_ctx->stream->link->replay_settings.config.replay_supported) + return true; + return false; } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 50088608a68a..ad967b58d7be 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1590,6 +1590,7 @@ static enum dc_status apply_single_controller_ctx_to_hw( */ if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) { pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; + pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false; } return DC_OK; } @@ -2021,6 +2022,10 @@ static bool should_enable_fbc(struct dc *dc, if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled) return false; + /* Replay should not be enabled */ + if (pipe_ctx->stream->link->replay_settings.replay_feature_enabled) + return false; + /* Nothing to compress */ if (!pipe_ctx->plane_state) return false; -- cgit From 4c452b5c7d73dadd8161a55a7a3f30599e4318aa Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Wed, 9 Aug 2023 10:59:40 +0530 Subject: drm/amdgpu: Fix missing comment for mb() in 'amdgpu_device_aper_access' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the missing code comment for memory barrier WARNING: memory barrier without comment + mb(); WARNING: memory barrier without comment + mb(); Cc: Guchun Chen Cc: Christian König Cc: Alex Deucher Cc: "Pan, Xinhui" Signed-off-by: Srinivasan Shanmugam Reviewed-by: Guchun Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 91d7f9e4fefc..97d202db1ce5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -305,10 +305,16 @@ size_t amdgpu_device_aper_access(struct amdgpu_device *adev, loff_t pos, if (write) { memcpy_toio(addr, buf, count); + /* Make sure HDP write cache flush happens without any reordering + * after the system memory contents are sent over PCIe device + */ mb(); amdgpu_device_flush_hdp(adev, NULL); } else { amdgpu_device_invalidate_hdp(adev, NULL); + /* Make sure HDP read cache is invalidated before issuing a read + * to the PCIe device + */ mb(); memcpy_fromio(buf, addr, count); } -- cgit From a34cab44094b77667584663df541300a4a033211 Mon Sep 17 00:00:00 2001 From: Jay Cornwall Date: Wed, 9 Aug 2023 16:13:40 -0500 Subject: drm/amdkfd: Add missing tba_hi programming on aldebaran Previously asymptomatic because high 32 bits were zero. Fixes: 96c211f1f9ef ("drm/amdkfd: Relocate TBA/TMA to opposite side of VM hole") Signed-off-by: Jay Cornwall Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c index 8fda16e6fee6..8ce6f5200905 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c @@ -121,6 +121,7 @@ static int pm_map_process_aldebaran(struct packet_manager *pm, packet->sh_mem_bases = qpd->sh_mem_bases; if (qpd->tba_addr) { packet->sq_shader_tba_lo = lower_32_bits(qpd->tba_addr >> 8); + packet->sq_shader_tba_hi = upper_32_bits(qpd->tba_addr >> 8); packet->sq_shader_tma_lo = lower_32_bits(qpd->tma_addr >> 8); packet->sq_shader_tma_hi = upper_32_bits(qpd->tma_addr >> 8); } -- cgit From a57c6c365d0e1bcd0713a3442a28c8c4a502cb02 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Wed, 9 Aug 2023 18:06:05 +0800 Subject: drm/amd/pm: disallow the fan setting if there is no fan on smu 13.0.0 drm/amd/pm: disallow the fan setting if there is no fan on smu 13.0.0 V2: depend on pm.no_fan to check Signed-off-by: Kenneth Feng Reviewed-by: Alex Deucher Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index fddcd834bcec..0fb6be11a0cc 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -331,6 +331,7 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) struct smu_13_0_0_powerplay_table *powerplay_table = table_context->power_play_table; struct smu_baco_context *smu_baco = &smu->smu_baco; + PPTable_t *pptable = smu->smu_table.driver_pptable; #if 0 PPTable_t *pptable = smu->smu_table.driver_pptable; const OverDriveLimits_t * const overdrive_upperlimits = @@ -371,6 +372,9 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) table_context->thermal_controller_type = powerplay_table->thermal_controller_type; + smu->adev->pm.no_fan = + !(pptable->SkuTable.FeaturesToRun[0] & (1 << FEATURE_FAN_CONTROL_BIT)); + return 0; } -- cgit From 707b570f4288d54e1e7fdf0ed6a872cc84c6464f Mon Sep 17 00:00:00 2001 From: Asad Kamal Date: Mon, 7 Aug 2023 12:24:29 +0800 Subject: drm/amd/pm: Add vclk and dclk sysnode for GC 9.4.3 Expose sysfs vclck and dclk entries for GC version 9.4.3 Signed-off-by: Asad Kamal Reviewed-by: Lijo Lazar Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index d4e5d670653b..5aed023f7402 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2095,7 +2095,8 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ gc_ver == IP_VERSION(10, 1, 2) || gc_ver == IP_VERSION(11, 0, 0) || gc_ver == IP_VERSION(11, 0, 2) || - gc_ver == IP_VERSION(11, 0, 3))) + gc_ver == IP_VERSION(11, 0, 3) || + gc_ver == IP_VERSION(9, 4, 3))) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_vclk1)) { if (!((gc_ver == IP_VERSION(10, 3, 1) || @@ -2109,7 +2110,8 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ gc_ver == IP_VERSION(10, 1, 2) || gc_ver == IP_VERSION(11, 0, 0) || gc_ver == IP_VERSION(11, 0, 2) || - gc_ver == IP_VERSION(11, 0, 3))) + gc_ver == IP_VERSION(11, 0, 3) || + gc_ver == IP_VERSION(9, 4, 3))) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_dclk1)) { if (!((gc_ver == IP_VERSION(10, 3, 1) || -- cgit From ba4c1d772c26ee91ea308c1b68f4f58a38de2aa5 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Wed, 9 Aug 2023 15:12:31 +0530 Subject: drm/radeon: Fix multiple line dereference in 'atom_iio_execute' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following: WARNING: Avoid multiple line dereference - prefer 'ctx->io_attr' + ((ctx-> + io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - Cc: Guchun Chen Cc: Christian König Cc: Alex Deucher Cc: "Pan, Xinhui" Signed-off-by: Srinivasan Shanmugam Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atom.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 93acb0e42bd6..ceb6d772ef94 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -163,13 +163,9 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << CU8(base + 3)); temp |= - ((ctx-> - io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - - CU8 - (base - + - 1)))) - << CU8(base + 3); + ((ctx->io_attr >> CU8(base + 2)) & + (0xFFFFFFFF >> (32 - CU8(base + 1)))) << + CU8(base + 3); base += 4; break; case ATOM_IIO_END: -- cgit From 1e9e15dcf414bef97489573e3521589b692f7231 Mon Sep 17 00:00:00 2001 From: Jiadong Zhu Date: Tue, 8 Aug 2023 10:59:25 +0800 Subject: drm/amdgpu: disable mcbp if parameter zero is set The parameter amdgpu_mcbp shall have priority against the default value calculated from the chip version. User could disable mcbp by setting the parameter mcbp as zero. v2: do not trigger preemption in sw ring muxer when mcbp is disabled. Signed-off-by: Jiadong Zhu Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 9 +++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 97d202db1ce5..1b3bd77d82da 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3493,10 +3493,11 @@ static void amdgpu_device_set_mcbp(struct amdgpu_device *adev) { if (amdgpu_mcbp == 1) adev->gfx.mcbp = true; - - if ((adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 0, 0)) && - (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 0, 0)) && - adev->gfx.num_gfx_rings) + else if (amdgpu_mcbp == 0) + adev->gfx.mcbp = false; + else if ((adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 0, 0)) && + (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 0, 0)) && + adev->gfx.num_gfx_rings) adev->gfx.mcbp = true; if (amdgpu_sriov_vf(adev)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c index b779ee4bbaa7..e1ee1c7117fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c @@ -397,7 +397,7 @@ void amdgpu_sw_ring_ib_begin(struct amdgpu_ring *ring) struct amdgpu_ring_mux *mux = &adev->gfx.muxer; WARN_ON(!ring->is_sw_ring); - if (ring->hw_prio > AMDGPU_RING_PRIO_DEFAULT) { + if (adev->gfx.mcbp && ring->hw_prio > AMDGPU_RING_PRIO_DEFAULT) { if (amdgpu_mcbp_scan(mux) > 0) amdgpu_mcbp_trigger_preempt(mux); return; -- cgit From 475968fe4a05b060864524a403e0d4a53f79aed0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 4 Aug 2023 15:29:17 +0200 Subject: drm/amdkfd: fix build failure without CONFIG_DYNAMIC_DEBUG When CONFIG_DYNAMIC_DEBUG is disabled altogether, calling _dynamic_func_call_no_desc() does not work: drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_svm.c: In function 'svm_range_set_attr': drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_svm.c:52:9: error: implicit declaration of function '_dynamic_func_call_no_desc' [-Werror=implicit-function-declaration] 52 | _dynamic_func_call_no_desc("svm_range_dump", svm_range_debug_dump, svms) | ^~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_svm.c:3564:9: note: in expansion of macro 'dynamic_svm_range_dump' 3564 | dynamic_svm_range_dump(svms); | ^~~~~~~~~~~~~~~~~~~~~~ Add a compile-time conditional in addition to the runtime check. Fixes: 8923137dbe4b ("drm/amdkfd: avoid svm dump when dynamic debug disabled") Signed-off-by: Arnd Bergmann Reviewed-by: Felix Kuehling Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 243ef74708e3..dbbe6559d6bc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -48,8 +49,13 @@ * page table is updated. */ #define AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING (2UL * NSEC_PER_MSEC) +#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG) #define dynamic_svm_range_dump(svms) \ _dynamic_func_call_no_desc("svm_range_dump", svm_range_debug_dump, svms) +#else +#define dynamic_svm_range_dump(svms) \ + do { if (0) svm_range_debug_dump(svms); } while (0) +#endif /* Giant svm range split into smaller ranges based on this, it is decided using * minimum of all dGPU/APU 1/32 VRAM size, between 2MB to 1GB and alignment to -- cgit From 8b3a7a707c6c5f7ccde47cf2427a560675cc5202 Mon Sep 17 00:00:00 2001 From: Hawking Zhang Date: Wed, 9 Aug 2023 19:07:50 +0800 Subject: drm/amdgpu: Remove unnecessary ras cap check RAS global isr will only be invoked by hardware interrupt. Don't need to query ras capability in isr In addition, amdgpu_ras_interrupt_fatal_error_handler ensures the isr won't be called from guest linux side by accident. The RAS cap check in isr that introduced to fix sriov crash is not needed any more Signed-off-by: Hawking Zhang Reviewed-by: Tao Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 886c7c6f1c3b..da52d7c6d210 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -2970,10 +2970,6 @@ int amdgpu_ras_fini(struct amdgpu_device *adev) void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev) { - amdgpu_ras_check_supported(adev); - if (!adev->ras_hw_enabled) - return; - if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) { struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); -- cgit From bd6040b0ea04aca3f90bc81ccd2aa816d20292d7 Mon Sep 17 00:00:00 2001 From: Atul Raut Date: Tue, 8 Aug 2023 22:30:18 -0700 Subject: drm/amdkfd: Use memdup_user() rather than duplicating its implementation To prevent its redundant implementation and streamline code, use memdup_user. This fixes warnings reported by Coccinelle: ./drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c:2811:13-20: WARNING opportunity for memdup_user Signed-off-by: Atul Raut Reviewed-by: Felix Kuehling Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 24ea3a596b38..7aa05f4068fc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -2817,19 +2817,11 @@ static void copy_context_work_handler (struct work_struct *work) static uint32_t *get_queue_ids(uint32_t num_queues, uint32_t *usr_queue_id_array) { size_t array_size = num_queues * sizeof(uint32_t); - uint32_t *queue_ids = NULL; if (!usr_queue_id_array) return NULL; - queue_ids = kzalloc(array_size, GFP_KERNEL); - if (!queue_ids) - return ERR_PTR(-ENOMEM); - - if (copy_from_user(queue_ids, usr_queue_id_array, array_size)) - return ERR_PTR(-EFAULT); - - return queue_ids; + return memdup_user(usr_queue_id_array, array_size); } int resume_queues(struct kfd_process *p, -- cgit From e01eeffc3f861425b3e8238f3d848b25ef9c1243 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Tue, 30 May 2023 17:08:08 +0800 Subject: drm/amd/pm: avoid driver getting empty metrics table for the first time add metrics.AccumulationCouter check to avoid driver getting an empty metrics data since metrics table not updated completely in pmfw side. Signed-off-by: Yang Wang Reviewed-by: Lijo Lazar Reviewed-by: Asad Kamal Tested-by: Asad Kamal Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 244e6d31560d..2898e9c0295e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -325,14 +325,24 @@ static int smu_v13_0_6_setup_driver_pptable(struct smu_context *smu) MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table; struct PPTable_t *pptable = (struct PPTable_t *)smu_table->driver_pptable; - int ret; - int i; + int ret, i, retry = 100; /* Store one-time values in driver PPTable */ if (!pptable->Init) { - ret = smu_v13_0_6_get_metrics_table(smu, NULL, false); - if (ret) - return ret; + while (retry--) { + ret = smu_v13_0_6_get_metrics_table(smu, NULL, true); + if (ret) + return ret; + + /* Ensure that metrics have been updated */ + if (metrics->AccumulationCounter) + break; + + usleep_range(1000, 1100); + } + + if (!retry) + return -ETIME; pptable->MaxSocketPowerLimit = SMUQ10_TO_UINT(metrics->MaxSocketPowerLimit); -- cgit From 1b98a5f8e04b944ba93444a8004690391a60fcf1 Mon Sep 17 00:00:00 2001 From: YiPeng Chai Date: Tue, 8 Aug 2023 10:02:30 +0800 Subject: drm/amdgpu: mode1 reset needs to recover mp1 for mp0 v13_0_10 Mode1 reset needs to recover mp1 in fatal error case for mp0 v13_0_10. v2: Define a macro to wrap psp function calls. Signed-off-by: YiPeng Chai Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 5 +++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 ++ drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 24 +++++++++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 3c7d9051b8c6..3384eb94fde0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -132,6 +132,7 @@ struct psp_funcs { int (*read_usbc_pd_fw)(struct psp_context *psp, uint32_t *fw_ver); int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr); int (*vbflash_stat)(struct psp_context *psp); + int (*fatal_error_recovery_quirk)(struct psp_context *psp); }; struct ta_funcs { @@ -445,6 +446,10 @@ struct amdgpu_psp_funcs { ((psp)->funcs->vbflash_stat ? \ (psp)->funcs->vbflash_stat((psp)) : -EINVAL) +#define psp_fatal_error_recovery_quirk(psp) \ + ((psp)->funcs->fatal_error_recovery_quirk ? \ + (psp)->funcs->fatal_error_recovery_quirk((psp)) : 0) + extern const struct amd_ip_funcs psp_ip_funcs; extern const struct amdgpu_ip_block_version psp_v3_1_ip_block; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index da52d7c6d210..7689395e44fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -2064,6 +2064,8 @@ static void amdgpu_ras_do_recovery(struct work_struct *work) if (ras->gpu_reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET) { ras->gpu_reset_flags &= ~AMDGPU_RAS_GPU_RESET_MODE1_RESET; set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); + + psp_fatal_error_recovery_quirk(&adev->psp); } } diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index 58db1ee631b3..10b17bd5aebe 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -691,6 +691,27 @@ static int psp_v13_0_vbflash_status(struct psp_context *psp) return RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_115); } +static int psp_v13_0_fatal_error_recovery_quirk(struct psp_context *psp) +{ + struct amdgpu_device *adev = psp->adev; + + if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 10)) { + uint32_t reg_data; + /* MP1 fatal error: trigger PSP dram read to unhalt PSP + * during MP1 triggered sync flood. + */ + reg_data = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_67); + WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_67, reg_data + 0x10); + + /* delay 1000ms for the mode1 reset for fatal error + * to be recovered back. + */ + msleep(1000); + } + + return 0; +} + static const struct psp_funcs psp_v13_0_funcs = { .init_microcode = psp_v13_0_init_microcode, .bootloader_load_kdb = psp_v13_0_bootloader_load_kdb, @@ -710,7 +731,8 @@ static const struct psp_funcs psp_v13_0_funcs = { .load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw, .read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw, .update_spirom = psp_v13_0_update_spirom, - .vbflash_stat = psp_v13_0_vbflash_status + .vbflash_stat = psp_v13_0_vbflash_status, + .fatal_error_recovery_quirk = psp_v13_0_fatal_error_recovery_quirk, }; void psp_v13_0_set_psp_funcs(struct psp_context *psp) -- cgit From e4538bc78b5198f9a7d94348e868f3fc588cf843 Mon Sep 17 00:00:00 2001 From: Umio Yasuno Date: Tue, 8 Aug 2023 06:40:42 +0000 Subject: drm/amdgpu/pm: fix throttle_status for other than MP1 11.0.7 Use the right metrics table version based on the firmware. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2720 Reviewed-by: Evan Quan Signed-off-by: Umio Yasuno Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 0cda3b276f61..f0800c0c5168 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -588,7 +588,9 @@ err0_out: return -ENOMEM; } -static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu) +static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu, + bool use_metrics_v3, + bool use_metrics_v2) { struct smu_table_context *smu_table= &smu->smu_table; SmuMetricsExternal_t *metrics_ext = @@ -596,13 +598,11 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s uint32_t throttler_status = 0; int i; - if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu->smc_fw_version >= 0x3A4900)) { + if (use_metrics_v3) { for (i = 0; i < THROTTLER_COUNT; i++) throttler_status |= (metrics_ext->SmuMetrics_V3.ThrottlingPercentage[i] ? 1U << i : 0); - } else if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu->smc_fw_version >= 0x3A4300)) { + } else if (use_metrics_v2) { for (i = 0; i < THROTTLER_COUNT; i++) throttler_status |= (metrics_ext->SmuMetrics_V2.ThrottlingPercentage[i] ? 1U << i : 0); @@ -864,7 +864,7 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu, metrics->TemperatureVrSoc) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; case METRICS_THROTTLER_STATUS: - *value = sienna_cichlid_get_throttler_status_locked(smu); + *value = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); break; case METRICS_CURR_FANSPEED: *value = use_metrics_v3 ? metrics_v3->CurrFanSpeed : @@ -4017,7 +4017,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_dclk1 = use_metrics_v3 ? metrics_v3->CurrClock[PPCLK_DCLK_1] : use_metrics_v2 ? metrics_v2->CurrClock[PPCLK_DCLK_1] : metrics->CurrClock[PPCLK_DCLK_1]; - gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu); + gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); gpu_metrics->indep_throttle_status = smu_cmn_get_indep_throttler_status(gpu_metrics->throttle_status, sienna_cichlid_throttler_map); -- cgit From d0d6928058300cff555c5e235ab97bcabbdbc62c Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Mon, 7 Aug 2023 13:56:39 +0530 Subject: drm/amdgpu: Fix identifier names to function definition arguments in atom.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following: WARNING: function definition argument 'struct card_info *' should also have an identifier name WARNING: function definition argument 'uint32_t' should also have an identifier name WARNING: function definition argument 'void *' should also have an identifier name WARNING: function definition argument 'struct atom_context *' should also have an identifier name WARNING: function definition argument 'int' should also have an identifier name WARNING: function definition argument 'uint32_t *' should also have an identifier name WARNING: Unnecessary space before function pointer name ERROR: space prohibited after that '*' (ctx:BxW) CHECK: Prefer kernel type 'u32' over 'uint32_t' Cc: Guchun Chen Cc: Christian König Cc: Alex Deucher Cc: "Pan, Xinhui" Signed-off-by: Srinivasan Shanmugam Reviewed-by: Guchun Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/atom.h | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h index 55bf99d5288d..c11cf18a0f18 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.h +++ b/drivers/gpu/drm/amd/amdgpu/atom.h @@ -117,12 +117,15 @@ struct drm_device; struct card_info { struct drm_device *dev; - void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ - uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */ - void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ - uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */ - void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ - uint32_t (* pll_read)(struct card_info *, uint32_t); /* filled by driver */ + void (*reg_write)(struct card_info *info, + u32 reg, uint32_t val); /* filled by driver */ + uint32_t (*reg_read)(struct card_info *info, uint32_t reg); /* filled by driver */ + void (*mc_write)(struct card_info *info, + u32 reg, uint32_t val); /* filled by driver */ + uint32_t (*mc_read)(struct card_info *info, uint32_t reg); /* filled by driver */ + void (*pll_write)(struct card_info *info, + u32 reg, uint32_t val); /* filled by driver */ + uint32_t (*pll_read)(struct card_info *info, uint32_t reg); /* filled by driver */ }; struct atom_context { @@ -152,10 +155,10 @@ struct atom_context { extern int amdgpu_atom_debug; -struct atom_context *amdgpu_atom_parse(struct card_info *, void *); -int amdgpu_atom_execute_table(struct atom_context *, int, uint32_t *); -int amdgpu_atom_asic_init(struct atom_context *); -void amdgpu_atom_destroy(struct atom_context *); +struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios); +int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params); +int amdgpu_atom_asic_init(struct atom_context *ctx); +void amdgpu_atom_destroy(struct atom_context *ctx); bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); bool amdgpu_atom_parse_cmd_header(struct atom_context *ctx, int index, -- cgit From f51069bac67cc5cff1a99ba715a5f7e2dbc78ebd Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Fri, 30 Jun 2023 13:58:33 -0400 Subject: drm/amd/display: Update replay for clk_mgr optimizations Add Replay calls to clk_mgr updates (just like PSR) Signed-off-by: Bhawanpreet Lakha Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 6127d6045336..dcedf9645161 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -117,6 +117,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m continue; clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active; dc->link_srv->edp_set_psr_allow_active(edp_link, &allow_active, false, false, NULL); + dc->link_srv->edp_set_replay_allow_active(edp_link, &allow_active, false, false, NULL); } } @@ -137,6 +138,8 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) continue; dc->link_srv->edp_set_psr_allow_active(edp_link, &clk_mgr->psr_allow_active_cache, false, false, NULL); + dc->link_srv->edp_set_replay_allow_active(edp_link, + &clk_mgr->psr_allow_active_cache, false, false, NULL); } } -- cgit From 8b4c350c4d0e2df6ed24e670697662db18520acf Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Thu, 10 Aug 2023 14:55:11 -0400 Subject: drm/amdkfd: fix double assign skip process context clear Remove redundant assignment when skipping process ctx clear. Signed-off-by: Jonathan Kim Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 7aa05f4068fc..b166f30f083e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -227,7 +227,6 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, queue_input.tba_addr = qpd->tba_addr; queue_input.tma_addr = qpd->tma_addr; queue_input.trap_en = !kfd_dbg_has_cwsr_workaround(q->device); - queue_input.skip_process_ctx_clear = qpd->pqm->process->debug_trap_enabled; queue_input.skip_process_ctx_clear = qpd->pqm->process->debug_trap_enabled || kfd_dbg_has_ttmps_always_setup(q->device); -- cgit From bdacd16afa6c15dde29e3de938aef5c3f772f3bb Mon Sep 17 00:00:00 2001 From: Xiongfeng Wang Date: Mon, 7 Aug 2023 21:17:59 +0800 Subject: drm/amd: Use pci_dev_id() to simplify the code PCI core API pci_dev_id() can be used to get the BDF number for a pci device. We don't need to compose it mannually. Use pci_dev_id() to simplify the code a little bit. Signed-off-by: Xiongfeng Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index a5a2b06c6588..2bca37044ad0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -706,7 +706,7 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, atcs_input.size = sizeof(struct atcs_pref_req_input); /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ - atcs_input.client_id = adev->pdev->devfn | (adev->pdev->bus->number << 8); + atcs_input.client_id = pci_dev_id(adev->pdev); atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK; atcs_input.flags = ATCS_WAIT_FOR_COMPLETION; if (advertise) @@ -776,7 +776,7 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev, atcs_input.size = sizeof(struct atcs_pwr_shift_input); /* dGPU id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ - atcs_input.dgpu_id = adev->pdev->devfn | (adev->pdev->bus->number << 8); + atcs_input.dgpu_id = pci_dev_id(adev->pdev); atcs_input.dev_acpi_state = dev_state; atcs_input.drv_state = drv_state; @@ -1141,7 +1141,7 @@ int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset, if (!tmr_offset || !tmr_size) return -EINVAL; - bdf = (adev->pdev->bus->number << 8) | adev->pdev->devfn; + bdf = pci_dev_id(adev->pdev); dev_info = amdgpu_acpi_get_dev(bdf); if (!dev_info) return -ENOENT; @@ -1162,7 +1162,7 @@ int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id, if (!numa_info) return -EINVAL; - bdf = (adev->pdev->bus->number << 8) | adev->pdev->devfn; + bdf = pci_dev_id(adev->pdev); dev_info = amdgpu_acpi_get_dev(bdf); if (!dev_info) return -ENOENT; -- cgit From 669f23724711ddbe44e7446375bff0a220b100c2 Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Thu, 10 Aug 2023 16:10:03 +0530 Subject: drm/amd/pm: Fix temperature unit of SMU v13.0.6 Temperature needs to be reported in millidegree Celsius. Signed-off-by: Lijo Lazar Reviewed-by: Yang Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 2898e9c0295e..362acbb242bb 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -718,16 +718,19 @@ static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu, *value = SMUQ10_TO_UINT(metrics->SocketPower) << 8; break; case METRICS_TEMPERATURE_HOTSPOT: - *value = SMUQ10_TO_UINT(metrics->MaxSocketTemperature); + *value = SMUQ10_TO_UINT(metrics->MaxSocketTemperature) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; case METRICS_TEMPERATURE_MEM: - *value = SMUQ10_TO_UINT(metrics->MaxHbmTemperature); + *value = SMUQ10_TO_UINT(metrics->MaxHbmTemperature) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; /* This is the max of all VRs and not just SOC VR. * No need to define another data type for the same. */ case METRICS_TEMPERATURE_VRSOC: - *value = SMUQ10_TO_UINT(metrics->MaxVrTemperature); + *value = SMUQ10_TO_UINT(metrics->MaxVrTemperature) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; default: *value = UINT_MAX; -- cgit From b7cc5b421cad12e4c00934a3e20208fdd7dd405e Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 10 Aug 2023 15:51:28 +0800 Subject: drm/amd/pm: correct the way for checking custom OD settings `FeatureCtrlMask` should not be included in those settings interested. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 16 ++++++++-------- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 0fb6be11a0cc..a5857acee641 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -1373,7 +1373,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, OverDriveTableExternal_t *od_table = (OverDriveTableExternal_t *)table_context->overdrive_table; struct amdgpu_device *adev = smu->adev; - uint32_t offset_of_featurectrlmask; + uint32_t offset_of_voltageoffset; int32_t minimum, maximum; uint32_t feature_ctrlmask; int i, ret = 0; @@ -1547,10 +1547,10 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, * It does not contain actual informations about user's custom * settings. Thus we do not cache it. */ - offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask); - if (memcmp((u8 *)od_table + offset_of_featurectrlmask, - table_context->user_overdrive_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) { + offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary); + if (memcmp((u8 *)od_table + offset_of_voltageoffset, + table_context->user_overdrive_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) { smu_v13_0_0_dump_od_table(smu, od_table); ret = smu_v13_0_0_upload_overdrive_table(smu, od_table); @@ -1560,9 +1560,9 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, } od_table->OverDriveTable.FeatureCtrlMask = 0; - memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask, - (u8 *)od_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask); + memcpy(table_context->user_overdrive_table + offset_of_voltageoffset, + (u8 *)od_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset); if (!memcmp(table_context->user_overdrive_table, table_context->boot_overdrive_table, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index b43c5d13f8d9..93b3e8fa8238 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -1354,7 +1354,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, OverDriveTableExternal_t *od_table = (OverDriveTableExternal_t *)table_context->overdrive_table; struct amdgpu_device *adev = smu->adev; - uint32_t offset_of_featurectrlmask; + uint32_t offset_of_voltageoffset; int32_t minimum, maximum; uint32_t feature_ctrlmask; int i, ret = 0; @@ -1528,10 +1528,10 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, * It does not contain actual informations about user's custom * settings. Thus we do not cache it. */ - offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask); - if (memcmp((u8 *)od_table + offset_of_featurectrlmask, - table_context->user_overdrive_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) { + offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary); + if (memcmp((u8 *)od_table + offset_of_voltageoffset, + table_context->user_overdrive_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) { smu_v13_0_7_dump_od_table(smu, od_table); ret = smu_v13_0_7_upload_overdrive_table(smu, od_table); @@ -1541,9 +1541,9 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, } od_table->OverDriveTable.FeatureCtrlMask = 0; - memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask, - (u8 *)od_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask); + memcpy(table_context->user_overdrive_table + offset_of_voltageoffset, + (u8 *)od_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset); if (!memcmp(table_context->user_overdrive_table, table_context->boot_overdrive_table, -- cgit From 0514dda30f006d5517ca8f65e4bba46c3107d939 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 10 Aug 2023 15:53:15 +0800 Subject: drm/amd/pm: correct the logics for retreiving SMU13 OD setting limits To better meet the growing demainds for more OD features. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 70 ++++++++++------------ .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 70 ++++++++++------------ 2 files changed, 64 insertions(+), 76 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index a5857acee641..48b03524a52d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -96,6 +96,12 @@ */ #define SUPPORT_ECCTABLE_SMU_13_0_10_VERSION 0x00502200 +#define PP_OD_FEATURE_GFXCLK_FMIN 0 +#define PP_OD_FEATURE_GFXCLK_FMAX 1 +#define PP_OD_FEATURE_UCLK_FMIN 2 +#define PP_OD_FEATURE_UCLK_FMAX 3 +#define PP_OD_FEATURE_GFX_VF_CURVE 4 + static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -1058,7 +1064,6 @@ static bool smu_v13_0_0_is_od_feature_supported(struct smu_context *smu, static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, int od_feature_bit, - bool lower_boundary, int32_t *min, int32_t *max) { @@ -1070,29 +1075,28 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, int32_t od_min_setting, od_max_setting; switch (od_feature_bit) { - case PP_OD_FEATURE_GFXCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->GfxclkFmin; - od_max_setting = overdrive_upperlimits->GfxclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->GfxclkFmax; - od_max_setting = overdrive_upperlimits->GfxclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMIN: + od_min_setting = overdrive_lowerlimits->GfxclkFmin; + od_max_setting = overdrive_upperlimits->GfxclkFmin; break; - case PP_OD_FEATURE_UCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->UclkFmin; - od_max_setting = overdrive_upperlimits->UclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->UclkFmax; - od_max_setting = overdrive_upperlimits->UclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMAX: + od_min_setting = overdrive_lowerlimits->GfxclkFmax; + od_max_setting = overdrive_upperlimits->GfxclkFmax; + break; + case PP_OD_FEATURE_UCLK_FMIN: + od_min_setting = overdrive_lowerlimits->UclkFmin; + od_max_setting = overdrive_upperlimits->UclkFmin; + break; + case PP_OD_FEATURE_UCLK_FMAX: + od_min_setting = overdrive_lowerlimits->UclkFmax; + od_max_setting = overdrive_upperlimits->UclkFmax; break; - case PP_OD_FEATURE_GFX_VF_CURVE_BIT: + case PP_OD_FEATURE_GFX_VF_CURVE: od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary; od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary; break; default: + od_min_setting = od_max_setting = INT_MAX; break; } @@ -1318,13 +1322,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &min_value, NULL); smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", @@ -1333,13 +1335,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &min_value, NULL); smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", @@ -1348,8 +1348,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &min_value, &max_value); size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", @@ -1394,8 +1393,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1411,8 +1409,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1457,8 +1454,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1474,8 +1470,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1516,8 +1511,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, return -EINVAL; smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &minimum, &maximum); if (input[1] < minimum || diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 93b3e8fa8238..690f89fcbbe3 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -72,6 +72,12 @@ #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000 +#define PP_OD_FEATURE_GFXCLK_FMIN 0 +#define PP_OD_FEATURE_GFXCLK_FMAX 1 +#define PP_OD_FEATURE_UCLK_FMIN 2 +#define PP_OD_FEATURE_UCLK_FMAX 3 +#define PP_OD_FEATURE_GFX_VF_CURVE 4 + static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -1039,7 +1045,6 @@ static bool smu_v13_0_7_is_od_feature_supported(struct smu_context *smu, static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, int od_feature_bit, - bool lower_boundary, int32_t *min, int32_t *max) { @@ -1051,29 +1056,28 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, int32_t od_min_setting, od_max_setting; switch (od_feature_bit) { - case PP_OD_FEATURE_GFXCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->GfxclkFmin; - od_max_setting = overdrive_upperlimits->GfxclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->GfxclkFmax; - od_max_setting = overdrive_upperlimits->GfxclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMIN: + od_min_setting = overdrive_lowerlimits->GfxclkFmin; + od_max_setting = overdrive_upperlimits->GfxclkFmin; break; - case PP_OD_FEATURE_UCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->UclkFmin; - od_max_setting = overdrive_upperlimits->UclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->UclkFmax; - od_max_setting = overdrive_upperlimits->UclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMAX: + od_min_setting = overdrive_lowerlimits->GfxclkFmax; + od_max_setting = overdrive_upperlimits->GfxclkFmax; + break; + case PP_OD_FEATURE_UCLK_FMIN: + od_min_setting = overdrive_lowerlimits->UclkFmin; + od_max_setting = overdrive_upperlimits->UclkFmin; + break; + case PP_OD_FEATURE_UCLK_FMAX: + od_min_setting = overdrive_lowerlimits->UclkFmax; + od_max_setting = overdrive_upperlimits->UclkFmax; break; - case PP_OD_FEATURE_GFX_VF_CURVE_BIT: + case PP_OD_FEATURE_GFX_VF_CURVE: od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary; od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary; break; default: + od_min_setting = od_max_setting = INT_MAX; break; } @@ -1299,13 +1303,11 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &min_value, NULL); smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", @@ -1314,13 +1316,11 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &min_value, NULL); smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", @@ -1329,8 +1329,7 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &min_value, &max_value); size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", @@ -1375,8 +1374,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1392,8 +1390,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1438,8 +1435,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1455,8 +1451,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1497,8 +1492,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, return -EINVAL; smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &minimum, &maximum); if (input[1] < minimum || -- cgit From 258ee02e23f3c8f6c552b821fe5bd11805363a65 Mon Sep 17 00:00:00 2001 From: Tim Huang Date: Mon, 7 Aug 2023 17:31:50 +0800 Subject: drm/amd/pm: bump SMU v13.0.5 driver_if header version Align the SMU driver interface version with PMFW to suppress the version mismatch message on driver loading. Signed-off-by: Tim Huang Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h index 7589faa0232d..779c2524806c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h @@ -23,7 +23,7 @@ #ifndef __SMU13_DRIVER_IF_V13_0_5_H__ #define __SMU13_DRIVER_IF_V13_0_5_H__ -#define SMU13_0_5_DRIVER_IF_VERSION 4 +#define SMU13_0_5_DRIVER_IF_VERSION 5 // Throttler Status Bitmask #define THROTTLER_STATUS_BIT_SPL 0 @@ -103,7 +103,6 @@ typedef struct { uint16_t ThrottlerStatus; uint16_t CurrentSocketPower; //[mW] - uint16_t spare1; } SmuMetrics_t; //Freq in MHz -- cgit From b81fde0dfe402e864ef1ac506eba756c89f1ad32 Mon Sep 17 00:00:00 2001 From: Candice Li Date: Tue, 1 Aug 2023 21:23:49 +0800 Subject: drm/amdgpu: Add I2C EEPROM support on smu v13_0_6 Support I2C EEPROM on smu v13_0_6. v2: Move IP_VERSION(13, 0, 6) ahead of IP_VERSION(13, 0, 10). Signed-off-by: Candice Li Reviewed-by: Yang Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index 4287743e1212..4764d2171f92 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -158,6 +158,7 @@ static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) case IP_VERSION(11, 0, 7): /* Sienna cichlid */ case IP_VERSION(13, 0, 0): case IP_VERSION(13, 0, 2): /* Aldebaran */ + case IP_VERSION(13, 0, 6): case IP_VERSION(13, 0, 10): return true; default: @@ -212,6 +213,7 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, control->i2c_address = EEPROM_I2C_MADDR_0; return true; case IP_VERSION(13, 0, 0): + case IP_VERSION(13, 0, 6): case IP_VERSION(13, 0, 10): control->i2c_address = EEPROM_I2C_MADDR_4; return true; -- cgit From 8d72444288c868f135a316f6bd5de292bbd50b37 Mon Sep 17 00:00:00 2001 From: Samir Dhume Date: Mon, 17 Jul 2023 11:03:13 -0400 Subject: drm/amdgpu/vcn: Add MMSCH v4_0_3 support for sriov The structures are the same as v4_0 except for the init header Signed-off-by: Samir Dhume Acked-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/mmsch_v4_0_3.h | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 drivers/gpu/drm/amd/amdgpu/mmsch_v4_0_3.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/mmsch_v4_0_3.h b/drivers/gpu/drm/amd/amdgpu/mmsch_v4_0_3.h new file mode 100644 index 000000000000..db7eb5260295 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/mmsch_v4_0_3.h @@ -0,0 +1,37 @@ +/* + * Copyright 2023 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. + * + */ + +#ifndef __MMSCH_V4_0_3_H__ +#define __MMSCH_V4_0_3_H__ + +#include "amdgpu_vcn.h" +#include "mmsch_v4_0.h" + +struct mmsch_v4_0_3_init_header { + uint32_t version; + uint32_t total_size; + struct mmsch_v4_0_table_info vcn0; + struct mmsch_v4_0_table_info mjpegdec0[4]; + struct mmsch_v4_0_table_info mjpegdec1[4]; +}; +#endif -- cgit From d78c227fce806cc157f147f4472bf288f9d6dce6 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:31:54 -0500 Subject: drm/amd: Add amdgpu_hwmon_get_sensor_generic() Many sensor function have a lot of boilerplate checks. Move these into a generic amdgpu_hwmon_get_sensor_generic() instead. No intended functional changes. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 321 ++++++++++--------------------------- 1 file changed, 88 insertions(+), 233 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 5aed023f7402..c0eda9bf0982 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -1467,6 +1467,32 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, return -EINVAL; } +static unsigned int amdgpu_hwmon_get_sensor_generic(struct amdgpu_device *adev, + enum amd_pp_sensors sensor, + void *query) +{ + int r, size = sizeof(uint32_t); + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + r = pm_runtime_get_sync(adev_to_drm(adev)->dev); + if (r < 0) { + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + return r; + } + + /* get the sensor value */ + r = amdgpu_dpm_read_sensor(adev, sensor, query, &size); + + pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + + return r; +} + /** * DOC: gpu_busy_percent * @@ -1481,26 +1507,10 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); - int r, value, size = sizeof(value); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(ddev->dev); - if (r < 0) { - pm_runtime_put_autosuspend(ddev->dev); - return r; - } - - /* read the IP busy sensor */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_LOAD, - (void *)&value, &size); - - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); + unsigned int value; + int r; + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_LOAD, &value); if (r) return r; @@ -1521,26 +1531,10 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); - int r, value, size = sizeof(value); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(ddev->dev); - if (r < 0) { - pm_runtime_put_autosuspend(ddev->dev); - return r; - } - - /* read the IP busy sensor */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_LOAD, - (void *)&value, &size); - - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); + unsigned int value; + int r; + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_LOAD, &value); if (r) return r; @@ -1814,45 +1808,15 @@ out: return size; } -static int amdgpu_device_read_powershift(struct amdgpu_device *adev, - uint32_t *ss_power, bool dgpu_share) -{ - struct drm_device *ddev = adev_to_drm(adev); - uint32_t size; - int r = 0; - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(ddev->dev); - if (r < 0) { - pm_runtime_put_autosuspend(ddev->dev); - return r; - } - - if (dgpu_share) - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, - (void *)ss_power, &size); - else - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, - (void *)ss_power, &size); - - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); - return r; -} - static int amdgpu_show_powershift_percent(struct device *dev, - char *buf, bool dgpu_share) + char *buf, enum amd_pp_sensors sensor) { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); uint32_t ss_power; int r = 0, i; - r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share); + r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&ss_power); if (r == -EOPNOTSUPP) { /* sensor not available on dGPU, try to read from APU */ adev = NULL; @@ -1865,14 +1829,15 @@ static int amdgpu_show_powershift_percent(struct device *dev, } mutex_unlock(&mgpu_info.mutex); if (adev) - r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share); + r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&ss_power); } - if (!r) - r = sysfs_emit(buf, "%u%%\n", ss_power); + if (r) + return r; - return r; + return sysfs_emit(buf, "%u%%\n", ss_power); } + /** * DOC: smartshift_apu_power * @@ -1886,7 +1851,7 @@ static int amdgpu_show_powershift_percent(struct device *dev, static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device_attribute *attr, char *buf) { - return amdgpu_show_powershift_percent(dev, buf, false); + return amdgpu_show_powershift_percent(dev, buf, AMDGPU_PP_SENSOR_SS_APU_SHARE); } /** @@ -1902,7 +1867,7 @@ static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device static ssize_t amdgpu_get_smartshift_dgpu_power(struct device *dev, struct device_attribute *attr, char *buf) { - return amdgpu_show_powershift_percent(dev, buf, true); + return amdgpu_show_powershift_percent(dev, buf, AMDGPU_PP_SENSOR_SS_DGPU_SHARE); } /** @@ -1965,7 +1930,6 @@ out: return r; } - static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, uint32_t mask, enum amdgpu_device_attr_states *states) { @@ -1978,15 +1942,15 @@ static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device static int ss_bias_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, uint32_t mask, enum amdgpu_device_attr_states *states) { - uint32_t ss_power, size; + uint32_t ss_power; if (!amdgpu_device_supports_smart_shift(adev_to_drm(adev))) *states = ATTR_STATE_UNSUPPORTED; - else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, - (void *)&ss_power, &size)) + else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, + (void *)&ss_power)) *states = ATTR_STATE_UNSUPPORTED; - else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, - (void *)&ss_power, &size)) + else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, + (void *)&ss_power)) *states = ATTR_STATE_UNSUPPORTED; return 0; @@ -2271,46 +2235,32 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); int channel = to_sensor_dev_attr(attr)->index; - int r, temp = 0, size = sizeof(temp); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; + int r, temp = 0; if (channel >= PP_TEMP_MAX) return -EINVAL; - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - switch (channel) { case PP_TEMP_JUNCTION: /* get current junction temperature */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP, - (void *)&temp, &size); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP, + (void *)&temp); break; case PP_TEMP_EDGE: /* get current edge temperature */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_EDGE_TEMP, - (void *)&temp, &size); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_EDGE_TEMP, + (void *)&temp); break; case PP_TEMP_MEM: /* get current memory temperature */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_TEMP, - (void *)&temp, &size); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_TEMP, + (void *)&temp); break; default: r = -EINVAL; break; } - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - if (r) return r; @@ -2594,25 +2544,10 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 min_rpm = 0; - u32 size = sizeof(min_rpm); int r; - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM, - (void *)&min_rpm, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM, + (void *)&min_rpm); if (r) return r; @@ -2626,25 +2561,10 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 max_rpm = 0; - u32 size = sizeof(max_rpm); int r; - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM, - (void *)&max_rpm, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM, + (void *)&max_rpm); if (r) return r; @@ -2806,26 +2726,11 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 vddgfx; - int r, size = sizeof(vddgfx); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } + int r; /* get the voltage */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX, - (void *)&vddgfx, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_VDDGFX, + (void *)&vddgfx); if (r) return r; @@ -2845,30 +2750,15 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 vddnb; - int r, size = sizeof(vddnb); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; + int r; /* only APUs have vddnb */ if (!(adev->flags & AMD_IS_APU)) return -EINVAL; - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - /* get the voltage */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, - (void *)&vddnb, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_VDDNB, + (void *)&vddnb); if (r) return r; @@ -2882,40 +2772,35 @@ static ssize_t amdgpu_hwmon_show_vddnb_label(struct device *dev, return sysfs_emit(buf, "vddnb\n"); } -static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, - struct device_attribute *attr, - char *buf) +static unsigned int amdgpu_hwmon_get_power(struct device *dev, + enum amd_pp_sensors sensor) { struct amdgpu_device *adev = dev_get_drvdata(dev); + unsigned int uw; u32 query = 0; - int r, size = sizeof(u32); - unsigned uw; - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - /* get the voltage */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, - (void *)&query, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + int r; + r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&query); if (r) return r; /* convert to microwatts */ uw = (query >> 8) * 1000000 + (query & 0xff) * 1000; - return sysfs_emit(buf, "%u\n", uw); + return uw; +} + +static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + unsigned int val; + + val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_POWER); + if (val < 0) + return val; + + return sysfs_emit(buf, "%u\n", val); } static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev, @@ -3050,26 +2935,11 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); uint32_t sclk; - int r, size = sizeof(sclk); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } + int r; /* get the sclk */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK, - (void *)&sclk, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GFX_SCLK, + (void *)&sclk); if (r) return r; @@ -3089,26 +2959,11 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); uint32_t mclk; - int r, size = sizeof(mclk); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } + int r; /* get the sclk */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK, - (void *)&mclk, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GFX_MCLK, + (void *)&mclk); if (r) return r; -- cgit From 56dd5140ebca15f12f70c8c98fda866096df56ae Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 8 Aug 2023 16:26:26 -0700 Subject: drm/amd/display: dmub_replay: don't use kernel-doc markers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These functions don't use kernel-doc notation for comments so don't begin each comment block with the "/**" kernel-doc marker. This prevents a bunch of kernel-doc warnings: dmub_replay.c:37: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst dmub_replay.c:37: warning: missing initial short description on line: * Get Replay state from firmware. dmub_replay.c:66: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst dmub_replay.c:66: warning: missing initial short description on line: * Enable/Disable Replay. dmub_replay.c:116: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst dmub_replay.c:116: warning: missing initial short description on line: * Set REPLAY power optimization flags. dmub_replay.c:134: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst dmub_replay.c:134: warning: missing initial short description on line: * Setup Replay by programming phy registers and sending replay hw context values to firmware. and 10 more similar warnings. Fixes: c7ddc0a800bc ("drm/amd/display: Add Functions to enable Freesync Panel Replay") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Link: lore.kernel.org/r/202308081459.US5rLYAY-lkp@intel.com Cc: Bhawanpreet Lakha Cc: Harry Wentland Cc: Alex Deucher Cc: Leo Li Cc: Rodrigo Siqueira Cc: amd-gfx@lists.freedesktop.org Cc: Christian König Cc: "Pan, Xinhui" Cc: dri-devel@lists.freedesktop.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c index cab7e71fd27f..28149e53c2a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c @@ -33,7 +33,7 @@ #define MAX_PIPES 6 -/** +/* * Get Replay state from firmware. */ static void dmub_replay_get_state(struct dmub_replay *dmub, enum replay_state *state, uint8_t panel_inst) @@ -62,7 +62,7 @@ static void dmub_replay_get_state(struct dmub_replay *dmub, enum replay_state *s } } -/** +/* * Enable/Disable Replay. */ static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, uint8_t panel_inst) @@ -112,7 +112,7 @@ static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, } -/** +/* * Set REPLAY power optimization flags. */ static void dmub_replay_set_power_opt(struct dmub_replay *dmub, unsigned int power_opt, uint8_t panel_inst) @@ -130,7 +130,7 @@ static void dmub_replay_set_power_opt(struct dmub_replay *dmub, unsigned int pow dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT); } -/** +/* * Setup Replay by programming phy registers and sending replay hw context values to firmware. */ static bool dmub_replay_copy_settings(struct dmub_replay *dmub, @@ -215,7 +215,7 @@ static bool dmub_replay_copy_settings(struct dmub_replay *dmub, return true; } -/** +/* * Set coasting vtotal. */ static void dmub_replay_set_coasting_vtotal(struct dmub_replay *dmub, @@ -234,7 +234,7 @@ static void dmub_replay_set_coasting_vtotal(struct dmub_replay *dmub, dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT); } -/** +/* * Get Replay residency from firmware. */ static void dmub_replay_residency(struct dmub_replay *dmub, uint8_t panel_inst, @@ -267,7 +267,7 @@ static const struct dmub_replay_funcs replay_funcs = { .replay_residency = dmub_replay_residency, }; -/** +/* * Construct Replay object. */ static void dmub_replay_construct(struct dmub_replay *replay, struct dc_context *ctx) @@ -276,7 +276,7 @@ static void dmub_replay_construct(struct dmub_replay *replay, struct dc_context replay->funcs = &replay_funcs; } -/** +/* * Allocate and initialize Replay object. */ struct dmub_replay *dmub_replay_create(struct dc_context *ctx) @@ -293,7 +293,7 @@ struct dmub_replay *dmub_replay_create(struct dc_context *ctx) return replay; } -/** +/* * Deallocate Replay object. */ void dmub_replay_destroy(struct dmub_replay **dmub) -- cgit From 275e37221b1046dea0c1de67c54ad3699fc9eb5b Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Wed, 9 Aug 2023 11:44:39 +0800 Subject: drm/amdkfd: Remove unnecessary NULL values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NULL initialization of the pointers assigned by kzalloc() first is not necessary, because if the kzalloc() failed, the pointers will be assigned NULL, otherwise it works as usual. so remove it. Reviewed-by: Christian König Signed-off-by: Ruan Jinjie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index 863cf060af48..d01bb57733b3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -48,7 +48,7 @@ int pipe_priority_map[] = { struct kfd_mem_obj *allocate_hiq_mqd(struct kfd_node *dev, struct queue_properties *q) { - struct kfd_mem_obj *mqd_mem_obj = NULL; + struct kfd_mem_obj *mqd_mem_obj; mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); if (!mqd_mem_obj) @@ -64,7 +64,7 @@ struct kfd_mem_obj *allocate_hiq_mqd(struct kfd_node *dev, struct queue_properti struct kfd_mem_obj *allocate_sdma_mqd(struct kfd_node *dev, struct queue_properties *q) { - struct kfd_mem_obj *mqd_mem_obj = NULL; + struct kfd_mem_obj *mqd_mem_obj; uint64_t offset; mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); -- cgit From a31c114bcfda33548b1197940ec9f05feab5e74b Mon Sep 17 00:00:00 2001 From: Samir Dhume Date: Mon, 17 Jul 2023 11:27:02 -0400 Subject: drm/amdgpu/vcn: mmsch_v4_0_3 requires doorbell on 32 byte boundary Align on 32 byte boundary. Signed-off-by: Samir Dhume Acked-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c index e62472e6e7b3..71eb6b55deef 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c @@ -111,9 +111,16 @@ static int vcn_v4_0_3_sw_init(void *handle) ring = &adev->vcn.inst[i].ring_enc[0]; ring->use_doorbell = true; - ring->doorbell_index = - (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + - 9 * vcn_inst; + + if (!amdgpu_sriov_vf(adev)) + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 9 * vcn_inst; + else + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 32 * vcn_inst; + ring->vm_hub = AMDGPU_MMHUB0(adev->vcn.inst[i].aid_id); sprintf(ring->name, "vcn_unified_%d", adev->vcn.inst[i].aid_id); r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0, -- cgit From 259d968034c3cb1890ff539e75d803b44c8e81e4 Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Wed, 9 Aug 2023 11:44:40 +0800 Subject: drm/amd/display: Remove unnecessary NULL values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NULL initialization of the pointers assigned by kzalloc() first is not necessary, because if the kzalloc() failed, the pointers will be assigned NULL, otherwise it works as usual. so remove it. Reviewed-by: Christian König Signed-off-by: Ruan Jinjie Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | 4 ++-- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index 4f005ae1516c..6b3190447581 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -96,7 +96,7 @@ struct dc_bios *bios_parser_create( struct bp_init_data *init, enum dce_version dce_version) { - struct bios_parser *bp = NULL; + struct bios_parser *bp; bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); if (!bp) @@ -2576,7 +2576,7 @@ static struct integrated_info *bios_parser_create_integrated_info( struct dc_bios *dcb) { struct bios_parser *bp = BP_FROM_DCB(dcb); - struct integrated_info *info = NULL; + struct integrated_info *info; info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 033ce2638eb2..484d62bcf2c2 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -3086,7 +3086,7 @@ static struct integrated_info *bios_parser_create_integrated_info( struct dc_bios *dcb) { struct bios_parser *bp = BP_FROM_DCB(dcb); - struct integrated_info *info = NULL; + struct integrated_info *info; info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); @@ -3675,7 +3675,7 @@ struct dc_bios *firmware_parser_create( struct bp_init_data *init, enum dce_version dce_version) { - struct bios_parser *bp = NULL; + struct bios_parser *bp; bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); if (!bp) -- cgit From 3cc0f8f4e391bfb0a9d0ca91594faea56f4752e9 Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Wed, 9 Aug 2023 11:44:42 +0800 Subject: drm/radeon: Remove unnecessary NULL values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NULL initialization of the pointers assigned by kzalloc() first is not necessary, because if the kzalloc() failed, the pointers will be assigned NULL, otherwise it works as usual. so remove it. Reviewed-by: Christian König Signed-off-by: Ruan Jinjie Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_agp.c | 2 +- drivers/gpu/drm/radeon/radeon_combios.c | 6 +++--- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index d124600b5f58..a3d749e350f9 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -130,7 +130,7 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { struct radeon_agp_head *radeon_agp_head_init(struct drm_device *dev) { struct pci_dev *pdev = to_pci_dev(dev->dev); - struct radeon_agp_head *head = NULL; + struct radeon_agp_head *head; head = kzalloc(sizeof(*head), GFP_KERNEL); if (!head) diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 795c3667f6d6..2620efc7c675 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -863,7 +863,7 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct struct radeon_device *rdev = dev->dev_private; uint16_t dac_info; uint8_t rev, bg, dac; - struct radeon_encoder_primary_dac *p_dac = NULL; + struct radeon_encoder_primary_dac *p_dac; int found = 0; p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), @@ -1014,7 +1014,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct struct radeon_device *rdev = dev->dev_private; uint16_t dac_info; uint8_t rev, bg, dac; - struct radeon_encoder_tv_dac *tv_dac = NULL; + struct radeon_encoder_tv_dac *tv_dac; int found = 0; tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); @@ -1100,7 +1100,7 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct radeon_device *rdev) { - struct radeon_encoder_lvds *lvds = NULL; + struct radeon_encoder_lvds *lvds; uint32_t fp_vert_stretch, fp_horz_stretch; uint32_t ppll_div_sel, ppll_val; uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 601d35d34eab..c4350ac2b3d2 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -1692,7 +1692,7 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon { struct drm_device *dev = encoder->base.dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_int_tmds *tmds = NULL; + struct radeon_encoder_int_tmds *tmds; bool ret; tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL); @@ -1715,7 +1715,7 @@ static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct ra { struct drm_device *dev = encoder->base.dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_ext_tmds *tmds = NULL; + struct radeon_encoder_ext_tmds *tmds; bool ret; if (rdev->is_atom_bios) -- cgit From dba24294ff3ac025103737ac4c44b92deb71edcb Mon Sep 17 00:00:00 2001 From: Samir Dhume Date: Mon, 17 Jul 2023 11:33:55 -0400 Subject: drm/amdgpu/jpeg: mmsch_v4_0_3 requires doorbell on 32 byte boundary BASE: VCN0 unified (32 byte boundary) BASE+4: MJPEG0 BASE+5: MJPEG1 BASE+6: MJPEG2 BASE+7: MJPEG3 BASE+12: MJPEG4 BASE+13: MJPEG5 BASE+14: MJPEG6 BASE+15: MJPEG7 Signed-off-by: Samir Dhume Acked-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c index 153731d6ce8b..03967d84fce9 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c @@ -109,9 +109,20 @@ static int jpeg_v4_0_3_sw_init(void *handle) ring = &adev->jpeg.inst[i].ring_dec[j]; ring->use_doorbell = true; ring->vm_hub = AMDGPU_MMHUB0(adev->jpeg.inst[i].aid_id); - ring->doorbell_index = - (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + - 1 + j + 9 * jpeg_inst; + if (!amdgpu_sriov_vf(adev)) { + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 1 + j + 9 * jpeg_inst; + } else { + if (j < 4) + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 4 + j + 32 * jpeg_inst; + else + ring->doorbell_index = + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 8 + j + 32 * jpeg_inst; + } sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j); r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0, AMDGPU_RING_PRIO_DEFAULT, NULL); -- cgit From ad5594ad41de08f01cb46a2263a1145c58bccee6 Mon Sep 17 00:00:00 2001 From: Michael Strauss Date: Thu, 22 Jun 2023 15:30:24 -0400 Subject: drm/amd/display: Support Compliance Test Pattern Generation with DP2 Retimer [WHY] Certain retimer requires workarounds in order to correctly output test patterns. [HOW] Add vendor-specific aux sequences to program retimer's TX and pattern generator when specific compliance test patterns are requested by sink. Note: SQ128 w/a in DPMF mode only works in one flip orientation currently Reviewed-by: Hansen Dsouza Reviewed-by: Wenjing Liu Acked-by: Stylon Wang Signed-off-by: Michael Strauss Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 8 +- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/inc/link.h | 4 + drivers/gpu/drm/amd/display/dc/link/Makefile | 3 +- .../amd/display/dc/link/accessories/link_dp_cts.c | 3 + .../drm/amd/display/dc/link/hwss/link_hwss_dio.c | 2 +- .../drm/amd/display/dc/link/hwss/link_hwss_dio.h | 3 + .../link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c | 200 ++++++++++++++ .../link/hwss/link_hwss_dio_fixed_vs_pe_retimer.h | 37 +++ .../amd/display/dc/link/hwss/link_hwss_hpo_dp.c | 22 +- .../amd/display/dc/link/hwss/link_hwss_hpo_dp.h | 28 +- .../hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c | 229 ++++++++++++++++ .../hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.h | 33 +++ drivers/gpu/drm/amd/display/dc/link/link_factory.c | 1 + .../drm/amd/display/dc/link/protocols/link_ddc.c | 82 ++++++ .../drm/amd/display/dc/link/protocols/link_ddc.h | 14 + .../link_dp_training_fixed_vs_pe_retimer.c | 305 ++++++--------------- 17 files changed, 738 insertions(+), 237 deletions(-) create mode 100644 drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c create mode 100644 drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.h create mode 100644 drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c create mode 100644 drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 7561fe748c72..853e5b99dd62 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -45,6 +45,8 @@ #include "link/hwss/link_hwss_dio.h" #include "link/hwss/link_hwss_dpia.h" #include "link/hwss/link_hwss_hpo_dp.h" +#include "link/hwss/link_hwss_dio_fixed_vs_pe_retimer.h" +#include "link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.h" #if defined(CONFIG_DRM_AMD_DC_SI) #include "dce60/dce60_resource.h" @@ -4198,11 +4200,13 @@ const struct link_hwss *get_link_hwss(const struct dc_link *link, * with an hpo encoder. Or we can return a very dummy one that doesn't * do work for all functions */ - return get_hpo_dp_link_hwss(); + return (requires_fixed_vs_pe_retimer_hpo_link_hwss(link) ? + get_hpo_fixed_vs_pe_retimer_dp_link_hwss() : get_hpo_dp_link_hwss()); else if (can_use_dpia_link_hwss(link, link_res)) return get_dpia_link_hwss(); else if (can_use_dio_link_hwss(link, link_res)) - return get_dio_link_hwss(); + return (requires_fixed_vs_pe_retimer_dio_link_hwss(link)) ? + get_dio_fixed_vs_pe_retimer_link_hwss() : get_dio_link_hwss(); else return get_virtual_link_hwss(); } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 44b6172da170..fc9756ea7cc5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1498,6 +1498,7 @@ struct dc_link { enum engine_id eng_id; bool test_pattern_enabled; + enum dp_test_pattern current_test_pattern; union compliance_test_state compliance_test_state; void *priv; diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h b/drivers/gpu/drm/amd/display/dc/inc/link.h index c07096e59201..e3e8c76c17cf 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -179,6 +179,10 @@ struct link_service { int (*aux_transfer_raw)(struct ddc_service *ddc, struct aux_payload *payload, enum aux_return_code_type *operation_result); + bool (*configure_fixed_vs_pe_retimer)( + struct ddc_service *ddc, + const uint8_t *data, + uint32_t len); bool (*aux_transfer_with_retries_no_mutex)(struct ddc_service *ddc, struct aux_payload *payload); bool (*is_in_aux_transaction_mode)(struct ddc_service *ddc); diff --git a/drivers/gpu/drm/amd/display/dc/link/Makefile b/drivers/gpu/drm/amd/display/dc/link/Makefile index a52b56e2859e..6af8a97d4a77 100644 --- a/drivers/gpu/drm/amd/display/dc/link/Makefile +++ b/drivers/gpu/drm/amd/display/dc/link/Makefile @@ -42,7 +42,8 @@ AMD_DISPLAY_FILES += $(AMD_DAL_LINK_ACCESSORIES) ############################################################################### # hwss ############################################################################### -LINK_HWSS = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o +LINK_HWSS = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o \ +link_hwss_dio_fixed_vs_pe_retimer.o link_hwss_hpo_fixed_vs_pe_retimer_dp.o AMD_DAL_LINK_HWSS = $(addprefix $(AMDDALPATH)/dc/link/hwss/, \ $(LINK_HWSS)) diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index 9fd68a11fad2..c7e1f2229afd 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -703,6 +703,7 @@ bool dp_set_test_pattern( /* Reset Test Pattern state */ link->test_pattern_enabled = false; + link->current_test_pattern = test_pattern; return true; } @@ -740,6 +741,7 @@ bool dp_set_test_pattern( if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) { /* Set Test Pattern state */ link->test_pattern_enabled = true; + link->current_test_pattern = test_pattern; if (p_link_settings != NULL) dpcd_set_link_settings(link, p_link_settings); @@ -938,6 +940,7 @@ bool dp_set_test_pattern( /* Set Test Pattern state */ link->test_pattern_enabled = true; + link->current_test_pattern = test_pattern; } return true; diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c index d19a0a958fbb..1328a0ade342 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c @@ -166,7 +166,7 @@ void set_dio_dp_lane_settings(struct dc_link *link, link_enc->funcs->dp_set_lane_settings(link_enc, link_settings, lane_settings); } -static void update_dio_stream_allocation_table(struct dc_link *link, +void update_dio_stream_allocation_table(struct dc_link *link, const struct link_resource *link_res, const struct link_mst_stream_allocation_table *table) { diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.h b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.h index 8b8a099feeb0..f4633d3cf9b9 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.h +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.h @@ -55,5 +55,8 @@ void setup_dio_audio_output(struct pipe_ctx *pipe_ctx, struct audio_output *audio_output, uint32_t audio_inst); void enable_dio_audio_packet(struct pipe_ctx *pipe_ctx); void disable_dio_audio_packet(struct pipe_ctx *pipe_ctx); +void update_dio_stream_allocation_table(struct dc_link *link, + const struct link_resource *link_res, + const struct link_mst_stream_allocation_table *table); #endif /* __LINK_HWSS_DIO_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c new file mode 100644 index 000000000000..b659baa23147 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c @@ -0,0 +1,200 @@ +/* + * Copyright 2023 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 "link_hwss_dio.h" +#include "link_hwss_dio_fixed_vs_pe_retimer.h" +#include "link_enc_cfg.h" + +uint8_t dp_dio_fixed_vs_pe_retimer_lane_cfg_to_hw_cfg(struct dc_link *link) +{ + // TODO: Get USB-C cable orientation + if (link->cur_link_settings.lane_count == LANE_COUNT_FOUR) + return 0xF2; + else + return 0x12; +} + +void dp_dio_fixed_vs_pe_retimer_exit_manual_automation(struct dc_link *link) +{ + const uint8_t dp_type = dp_dio_fixed_vs_pe_retimer_lane_cfg_to_hw_cfg(link); + const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 0x0, 0x06}; + const uint8_t vendor_lttpr_exit_manual_automation_1[4] = {0x1, 0x50, dp_type, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_2[4] = {0x1, 0x50, 0x50, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_3[4] = {0x1, 0x51, 0x50, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_4[4] = {0x1, 0x10, 0x58, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_5[4] = {0x1, 0x10, 0x59, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_6[4] = {0x1, 0x30, 0x51, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_7[4] = {0x1, 0x30, 0x52, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_8[4] = {0x1, 0x30, 0x54, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_9[4] = {0x1, 0x30, 0x55, 0x0}; + + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_0[0], sizeof(vendor_lttpr_exit_manual_automation_0)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_1[0], sizeof(vendor_lttpr_exit_manual_automation_1)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_2[0], sizeof(vendor_lttpr_exit_manual_automation_2)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_3[0], sizeof(vendor_lttpr_exit_manual_automation_3)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_4[0], sizeof(vendor_lttpr_exit_manual_automation_4)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_5[0], sizeof(vendor_lttpr_exit_manual_automation_5)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_6[0], sizeof(vendor_lttpr_exit_manual_automation_6)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_7[0], sizeof(vendor_lttpr_exit_manual_automation_7)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_8[0], sizeof(vendor_lttpr_exit_manual_automation_8)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_9[0], sizeof(vendor_lttpr_exit_manual_automation_9)); +} + +static bool set_dio_fixed_vs_pe_retimer_dp_link_test_pattern_override(struct dc_link *link, + const struct link_resource *link_res, struct encoder_set_dp_phy_pattern_param *tp_params, + const struct link_hwss *link_hwss) +{ + struct encoder_set_dp_phy_pattern_param hw_tp_params = { 0 }; + const uint8_t pltpat_custom[10] = {0x1F, 0x7C, 0xF0, 0xC1, 0x07, 0x1F, 0x7C, 0xF0, 0xC1, 0x07}; + const uint8_t vendor_lttpr_write_data_pg0[4] = {0x1, 0x11, 0x0, 0x0}; + const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 0x0, 0x06}; + + + if (tp_params == NULL) + return false; + + if (link->current_test_pattern >= DP_TEST_PATTERN_SQUARE_BEGIN && + link->current_test_pattern <= DP_TEST_PATTERN_SQUARE_END) { + // Deprogram overrides from previous test pattern + dp_dio_fixed_vs_pe_retimer_exit_manual_automation(link); + } + + switch (tp_params->dp_phy_pattern) { + case DP_TEST_PATTERN_80BIT_CUSTOM: + if (tp_params->custom_pattern_size == 0 || memcmp(tp_params->custom_pattern, + pltpat_custom, tp_params->custom_pattern_size) != 0) + return false; + break; + case DP_TEST_PATTERN_D102: + break; + default: + if (link->current_test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM || + link->current_test_pattern == DP_TEST_PATTERN_D102) + // Deprogram overrides from previous test pattern + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_0[0], + sizeof(vendor_lttpr_exit_manual_automation_0)); + + return false; + } + + hw_tp_params.dp_phy_pattern = tp_params->dp_phy_pattern; + hw_tp_params.dp_panel_mode = tp_params->dp_panel_mode; + + if (link_hwss->ext.set_dp_link_test_pattern) + link_hwss->ext.set_dp_link_test_pattern(link, link_res, &hw_tp_params); + + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg0[0], sizeof(vendor_lttpr_write_data_pg0)); + + return true; +} + +static void set_dio_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *link, + const struct link_resource *link_res, + struct encoder_set_dp_phy_pattern_param *tp_params) +{ + struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + + if (!set_dio_fixed_vs_pe_retimer_dp_link_test_pattern_override( + link, link_res, tp_params, get_dio_link_hwss())) { + link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params); + } + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); +} + +void enable_dio_fixed_vs_pe_retimer_program_4lane_output(struct dc_link *link) +{ + const uint8_t vendor_lttpr_write_data_4lane_1[4] = {0x1, 0x6E, 0xF2, 0x19}; + const uint8_t vendor_lttpr_write_data_4lane_2[4] = {0x1, 0x6B, 0xF2, 0x01}; + const uint8_t vendor_lttpr_write_data_4lane_3[4] = {0x1, 0x6D, 0xF2, 0x18}; + const uint8_t vendor_lttpr_write_data_4lane_4[4] = {0x1, 0x6C, 0xF2, 0x03}; + const uint8_t vendor_lttpr_write_data_4lane_5[4] = {0x1, 0x03, 0xF3, 0x06}; + + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_1[0], sizeof(vendor_lttpr_write_data_4lane_1)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_2[0], sizeof(vendor_lttpr_write_data_4lane_2)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_3[0], sizeof(vendor_lttpr_write_data_4lane_3)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_4[0], sizeof(vendor_lttpr_write_data_4lane_4)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_5[0], sizeof(vendor_lttpr_write_data_4lane_5)); +} + +static void enable_dio_fixed_vs_pe_retimer_dp_link_output(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal, + enum clock_source_id clock_source, + const struct dc_link_settings *link_settings) +{ + if (link_settings->lane_count == LANE_COUNT_FOUR) + enable_dio_fixed_vs_pe_retimer_program_4lane_output(link); + + enable_dio_dp_link_output(link, link_res, signal, clock_source, link_settings); +} + +static const struct link_hwss dio_fixed_vs_pe_retimer_link_hwss = { + .setup_stream_encoder = setup_dio_stream_encoder, + .reset_stream_encoder = reset_dio_stream_encoder, + .setup_stream_attribute = setup_dio_stream_attribute, + .disable_link_output = disable_dio_link_output, + .setup_audio_output = setup_dio_audio_output, + .enable_audio_packet = enable_dio_audio_packet, + .disable_audio_packet = disable_dio_audio_packet, + .ext = { + .set_throttled_vcp_size = set_dio_throttled_vcp_size, + .enable_dp_link_output = enable_dio_fixed_vs_pe_retimer_dp_link_output, + .set_dp_link_test_pattern = set_dio_fixed_vs_pe_retimer_dp_link_test_pattern, + .set_dp_lane_settings = set_dio_dp_lane_settings, + .update_stream_allocation_table = update_dio_stream_allocation_table, + }, +}; + +bool requires_fixed_vs_pe_retimer_dio_link_hwss(const struct dc_link *link) +{ + if (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)) + return false; + + if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) + return false; + + return true; +} + +const struct link_hwss *get_dio_fixed_vs_pe_retimer_link_hwss(void) +{ + return &dio_fixed_vs_pe_retimer_link_hwss; +} diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.h b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.h new file mode 100644 index 000000000000..9ac08a332540 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.h @@ -0,0 +1,37 @@ +/* + * Copyright 2023 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 __LINK_HWSS_DIO_FIXED_VS_PE_RETIMER_H__ +#define __LINK_HWSS_DIO_FIXED_VS_PE_RETIMER_H__ + +#include "link.h" + +uint32_t dp_dio_fixed_vs_pe_retimer_get_lttpr_write_address(struct dc_link *link); +uint8_t dp_dio_fixed_vs_pe_retimer_lane_cfg_to_hw_cfg(struct dc_link *link); +void dp_dio_fixed_vs_pe_retimer_exit_manual_automation(struct dc_link *link); +void enable_dio_fixed_vs_pe_retimer_program_4lane_output(struct dc_link *link); +bool requires_fixed_vs_pe_retimer_dio_link_hwss(const struct dc_link *link); +const struct link_hwss *get_dio_fixed_vs_pe_retimer_link_hwss(void); + +#endif /* __LINK_HWSS_DIO_FIXED_VS_PE_RETIMER_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c index dc1cb5478e08..e1257404357b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c @@ -28,7 +28,7 @@ #include "dccg.h" #include "clk_mgr.h" -static void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx, +void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx, struct fixed31_32 throttled_vcp_size) { struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = @@ -41,7 +41,7 @@ static void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx, throttled_vcp_size); } -static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx, +void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx, const struct dc_link_settings *link_settings, struct fixed31_32 throttled_vcp_size) { @@ -69,7 +69,7 @@ static void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx, hblank_min_symbol_width); } -static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) +void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) { struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc; @@ -78,14 +78,14 @@ static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst); } -static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) +void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) { struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; stream_enc->funcs->disable(stream_enc); } -static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx) +void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx) { struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; struct dc_stream_state *stream = pipe_ctx->stream; @@ -102,7 +102,7 @@ static void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx) DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR); } -static void enable_hpo_dp_link_output(struct dc_link *link, +void enable_hpo_dp_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal, enum clock_source_id clock_source, @@ -120,7 +120,7 @@ static void enable_hpo_dp_link_output(struct dc_link *link, link->link_enc->hpd_source); } -static void disable_hpo_dp_link_output(struct dc_link *link, +void disable_hpo_dp_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal) { @@ -154,7 +154,7 @@ static void set_hpo_dp_lane_settings(struct dc_link *link, lane_settings[0].FFE_PRESET.raw); } -static void update_hpo_dp_stream_allocation_table(struct dc_link *link, +void update_hpo_dp_stream_allocation_table(struct dc_link *link, const struct link_resource *link_res, const struct link_mst_stream_allocation_table *table) { @@ -163,7 +163,7 @@ static void update_hpo_dp_stream_allocation_table(struct dc_link *link, table); } -static void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx, +void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx, struct audio_output *audio_output, uint32_t audio_inst) { pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_setup( @@ -172,13 +172,13 @@ static void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx, &pipe_ctx->stream->audio_info); } -static void enable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx) +void enable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx) { pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_enable( pipe_ctx->stream_res.hpo_dp_stream_enc); } -static void disable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx) +void disable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx) { if (pipe_ctx->stream_res.audio) pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_disable( diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.h b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.h index 3cbb94b41a23..1d3ed8ca83b5 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.h +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.h @@ -28,9 +28,35 @@ #include "link_hwss.h" #include "link.h" +void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx, + struct fixed31_32 throttled_vcp_size); +void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx, + const struct dc_link_settings *link_settings, + struct fixed31_32 throttled_vcp_size); +void set_hpo_dp_hblank_min_symbol_width(struct pipe_ctx *pipe_ctx, + const struct dc_link_settings *link_settings, + struct fixed31_32 throttled_vcp_size); +void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx); +void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx); +void setup_hpo_dp_stream_attribute(struct pipe_ctx *pipe_ctx); +void enable_hpo_dp_link_output(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal, + enum clock_source_id clock_source, + const struct dc_link_settings *link_settings); +void disable_hpo_dp_link_output(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal); +void update_hpo_dp_stream_allocation_table(struct dc_link *link, + const struct link_resource *link_res, + const struct link_mst_stream_allocation_table *table); +void setup_hpo_dp_audio_output(struct pipe_ctx *pipe_ctx, + struct audio_output *audio_output, uint32_t audio_inst); +void enable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx); +void disable_hpo_dp_audio_packet(struct pipe_ctx *pipe_ctx); +const struct link_hwss *get_hpo_dp_link_hwss(void); bool can_use_hpo_dp_link_hwss(const struct dc_link *link, const struct link_resource *link_res); -const struct link_hwss *get_hpo_dp_link_hwss(void); #endif /* __LINK_HWSS_HPO_DP_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c new file mode 100644 index 000000000000..b621b97711b6 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c @@ -0,0 +1,229 @@ +/* + * Copyright 2023 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 "link_hwss_hpo_dp.h" +#include "link_hwss_hpo_fixed_vs_pe_retimer_dp.h" +#include "link_hwss_dio_fixed_vs_pe_retimer.h" + +static void dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(struct dc_link *link, + const struct dc_lane_settings *hw_lane_settings) +{ + const uint8_t vendor_ffe_preset_table[16] = { + 0x01, 0x41, 0x61, 0x81, + 0xB1, 0x05, 0x35, 0x65, + 0x85, 0xA5, 0x09, 0x39, + 0x59, 0x89, 0x0F, 0x24}; + + const uint8_t ffe_mask[4] = { + (hw_lane_settings[0].FFE_PRESET.settings.no_deemphasis != 0 ? 0x0F : 0xFF) + & (hw_lane_settings[0].FFE_PRESET.settings.no_preshoot != 0 ? 0xF1 : 0xFF), + (hw_lane_settings[1].FFE_PRESET.settings.no_deemphasis != 0 ? 0x0F : 0xFF) + & (hw_lane_settings[1].FFE_PRESET.settings.no_preshoot != 0 ? 0xF1 : 0xFF), + (hw_lane_settings[2].FFE_PRESET.settings.no_deemphasis != 0 ? 0x0F : 0xFF) + & (hw_lane_settings[2].FFE_PRESET.settings.no_preshoot != 0 ? 0xF1 : 0xFF), + (hw_lane_settings[3].FFE_PRESET.settings.no_deemphasis != 0 ? 0x0F : 0xFF) + & (hw_lane_settings[3].FFE_PRESET.settings.no_preshoot != 0 ? 0xF1 : 0xFF)}; + + const uint8_t ffe_cfg[4] = { + vendor_ffe_preset_table[hw_lane_settings[0].FFE_PRESET.settings.level] & ffe_mask[0], + vendor_ffe_preset_table[hw_lane_settings[1].FFE_PRESET.settings.level] & ffe_mask[1], + vendor_ffe_preset_table[hw_lane_settings[2].FFE_PRESET.settings.level] & ffe_mask[2], + vendor_ffe_preset_table[hw_lane_settings[3].FFE_PRESET.settings.level] & ffe_mask[3]}; + + const uint8_t dp_type = dp_dio_fixed_vs_pe_retimer_lane_cfg_to_hw_cfg(link); + + const uint8_t vendor_lttpr_write_data_ffe1[4] = {0x01, 0x50, dp_type, 0x0F}; + const uint8_t vendor_lttpr_write_data_ffe2[4] = {0x01, 0x55, dp_type, ffe_cfg[0]}; + const uint8_t vendor_lttpr_write_data_ffe3[4] = {0x01, 0x56, dp_type, ffe_cfg[1]}; + const uint8_t vendor_lttpr_write_data_ffe4[4] = {0x01, 0x57, dp_type, ffe_cfg[2]}; + const uint8_t vendor_lttpr_write_data_ffe5[4] = {0x01, 0x58, dp_type, ffe_cfg[3]}; + + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_ffe1[0], sizeof(vendor_lttpr_write_data_ffe1)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_ffe2[0], sizeof(vendor_lttpr_write_data_ffe2)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_ffe3[0], sizeof(vendor_lttpr_write_data_ffe3)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_ffe4[0], sizeof(vendor_lttpr_write_data_ffe4)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_ffe5[0], sizeof(vendor_lttpr_write_data_ffe5)); +} + +static void dp_hpo_fixed_vs_pe_retimer_program_override_test_pattern(struct dc_link *link, + struct encoder_set_dp_phy_pattern_param *tp_params) +{ + const uint8_t vendor_lttpr_write_data_pg0[4] = {0x1, 0x11, 0x0, 0x0}; + const uint8_t vendor_lttpr_write_data_pg1[4] = {0x1, 0x50, 0x50, 0x0}; + const uint8_t vendor_lttpr_write_data_pg2[4] = {0x1, 0x51, 0x50, 0x0}; + const uint8_t vendor_lttpr_write_data_pg3[4] = {0x1, 0x10, 0x58, 0x21}; + const uint8_t vendor_lttpr_write_data_pg4[4] = {0x1, 0x10, 0x59, 0x21}; + const uint8_t vendor_lttpr_write_data_pg5[4] = {0x1, 0x1C, 0x58, 0x4F}; + const uint8_t vendor_lttpr_write_data_pg6[4] = {0x1, 0x1C, 0x59, 0x4F}; + const uint8_t vendor_lttpr_write_data_pg7[4] = {0x1, 0x30, 0x51, 0x20}; + const uint8_t vendor_lttpr_write_data_pg8[4] = {0x1, 0x30, 0x52, 0x20}; + const uint8_t vendor_lttpr_write_data_pg9[4] = {0x1, 0x30, 0x54, 0x20}; + const uint8_t vendor_lttpr_write_data_pg10[4] = {0x1, 0x30, 0x55, 0x20}; + + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg0[0], sizeof(vendor_lttpr_write_data_pg0)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg1[0], sizeof(vendor_lttpr_write_data_pg1)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg2[0], sizeof(vendor_lttpr_write_data_pg2)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg3[0], sizeof(vendor_lttpr_write_data_pg3)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg4[0], sizeof(vendor_lttpr_write_data_pg4)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg5[0], sizeof(vendor_lttpr_write_data_pg5)); + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg6[0], sizeof(vendor_lttpr_write_data_pg6)); + + if (link->cur_link_settings.lane_count == LANE_COUNT_FOUR) + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg7[0], sizeof(vendor_lttpr_write_data_pg7)); + + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg8[0], sizeof(vendor_lttpr_write_data_pg8)); + + if (link->cur_link_settings.lane_count == LANE_COUNT_FOUR) + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg9[0], sizeof(vendor_lttpr_write_data_pg9)); + + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pg10[0], sizeof(vendor_lttpr_write_data_pg10)); +} + +static bool dp_hpo_fixed_vs_pe_retimer_set_override_test_pattern(struct dc_link *link, + const struct link_resource *link_res, struct encoder_set_dp_phy_pattern_param *tp_params, + const struct link_hwss *link_hwss) +{ + struct encoder_set_dp_phy_pattern_param hw_tp_params = { 0 }; + const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 0x0, 0x06}; + + if (tp_params == NULL) + return false; + + if (tp_params->dp_phy_pattern < DP_TEST_PATTERN_SQUARE_BEGIN || + tp_params->dp_phy_pattern > DP_TEST_PATTERN_SQUARE_END) { + // Deprogram overrides from previously set square wave override + if (link->current_test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM || + link->current_test_pattern == DP_TEST_PATTERN_D102) + link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_exit_manual_automation_0[0], + sizeof(vendor_lttpr_exit_manual_automation_0)); + else + dp_dio_fixed_vs_pe_retimer_exit_manual_automation(link); + + return false; + } + + hw_tp_params.dp_phy_pattern = DP_TEST_PATTERN_PRBS31; + hw_tp_params.dp_panel_mode = tp_params->dp_panel_mode; + + if (link_hwss->ext.set_dp_link_test_pattern) + link_hwss->ext.set_dp_link_test_pattern(link, link_res, &hw_tp_params); + + dp_hpo_fixed_vs_pe_retimer_program_override_test_pattern(link, tp_params); + + dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, &link->cur_lane_setting[0]); + + return true; +} + +static void set_hpo_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *link, + const struct link_resource *link_res, + struct encoder_set_dp_phy_pattern_param *tp_params) +{ + if (!dp_hpo_fixed_vs_pe_retimer_set_override_test_pattern( + link, link_res, tp_params, get_hpo_dp_link_hwss())) { + link_res->hpo_dp_link_enc->funcs->set_link_test_pattern( + link_res->hpo_dp_link_enc, tp_params); + } + link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); +} + +static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link, + const struct link_resource *link_res, + const struct dc_link_settings *link_settings, + const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) +{ + link_res->hpo_dp_link_enc->funcs->set_ffe( + link_res->hpo_dp_link_enc, + link_settings, + lane_settings[0].FFE_PRESET.raw); + + // FFE is programmed when retimer is programmed for SQ128, but explicit + // programming needed here as well in case FFE-only update is requested + if (link->current_test_pattern >= DP_TEST_PATTERN_SQUARE_BEGIN && + link->current_test_pattern <= DP_TEST_PATTERN_SQUARE_END) + dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, &lane_settings[0]); +} + +static void enable_hpo_fixed_vs_pe_retimer_dp_link_output(struct dc_link *link, + const struct link_resource *link_res, + enum signal_type signal, + enum clock_source_id clock_source, + const struct dc_link_settings *link_settings) +{ + if (link_settings->lane_count == LANE_COUNT_FOUR) + enable_dio_fixed_vs_pe_retimer_program_4lane_output(link); + + enable_hpo_dp_link_output(link, link_res, signal, clock_source, link_settings); +} + +static const struct link_hwss hpo_fixed_vs_pe_retimer_dp_link_hwss = { + .setup_stream_encoder = setup_hpo_dp_stream_encoder, + .reset_stream_encoder = reset_hpo_dp_stream_encoder, + .setup_stream_attribute = setup_hpo_dp_stream_attribute, + .disable_link_output = disable_hpo_dp_link_output, + .setup_audio_output = setup_hpo_dp_audio_output, + .enable_audio_packet = enable_hpo_dp_audio_packet, + .disable_audio_packet = disable_hpo_dp_audio_packet, + .ext = { + .set_throttled_vcp_size = set_hpo_dp_throttled_vcp_size, + .set_hblank_min_symbol_width = set_hpo_dp_hblank_min_symbol_width, + .enable_dp_link_output = enable_hpo_fixed_vs_pe_retimer_dp_link_output, + .set_dp_link_test_pattern = set_hpo_fixed_vs_pe_retimer_dp_link_test_pattern, + .set_dp_lane_settings = set_hpo_fixed_vs_pe_retimer_dp_lane_settings, + .update_stream_allocation_table = update_hpo_dp_stream_allocation_table, + }, +}; + +bool requires_fixed_vs_pe_retimer_hpo_link_hwss(const struct dc_link *link) +{ + if (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)) + return false; + + if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) + return false; + + return true; +} + +const struct link_hwss *get_hpo_fixed_vs_pe_retimer_dp_link_hwss(void) +{ + return &hpo_fixed_vs_pe_retimer_dp_link_hwss; +} diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.h b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.h new file mode 100644 index 000000000000..82301187bc7c --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.h @@ -0,0 +1,33 @@ +/* + * Copyright 2023 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 __LINK_HWSS_HPO_FIXED_VS_PE_RETIMER_DP_H__ +#define __LINK_HWSS_HPO_FIXED_VS_PE_RETIMER_DP_H__ + +#include "link.h" + +bool requires_fixed_vs_pe_retimer_hpo_link_hwss(const struct dc_link *link); +const struct link_hwss *get_hpo_fixed_vs_pe_retimer_dp_link_hwss(void); + +#endif /* __LINK_HWSS_HPO_FIXED_VS_PE_RETIMER_DP_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index bb063e1491a2..195ca9e52eda 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -132,6 +132,7 @@ static void construct_link_service_ddc(struct link_service *link_srv) link_srv->destroy_ddc_service = link_destroy_ddc_service; link_srv->query_ddc_data = link_query_ddc_data; link_srv->aux_transfer_raw = link_aux_transfer_raw; + link_srv->configure_fixed_vs_pe_retimer = link_configure_fixed_vs_pe_retimer; link_srv->aux_transfer_with_retries_no_mutex = link_aux_transfer_with_retries_no_mutex; link_srv->is_in_aux_transaction_mode = link_is_in_aux_transaction_mode; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c index 0f19c07011b5..ecfd83299e75 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c @@ -412,6 +412,88 @@ int link_aux_transfer_raw(struct ddc_service *ddc, } } +uint32_t link_get_fixed_vs_pe_retimer_write_address(struct dc_link *link) +{ + uint32_t vendor_lttpr_write_address = 0xF004F; + uint8_t offset; + + switch (link->dpcd_caps.lttpr_caps.phy_repeater_cnt) { + case 0x80: // 1 lttpr repeater + offset = 1; + break; + case 0x40: // 2 lttpr repeaters + offset = 2; + break; + case 0x20: // 3 lttpr repeaters + offset = 3; + break; + case 0x10: // 4 lttpr repeaters + offset = 4; + break; + case 0x08: // 5 lttpr repeaters + offset = 5; + break; + case 0x04: // 6 lttpr repeaters + offset = 6; + break; + case 0x02: // 7 lttpr repeaters + offset = 7; + break; + case 0x01: // 8 lttpr repeaters + offset = 8; + break; + default: + offset = 0xFF; + } + + if (offset != 0xFF) { + vendor_lttpr_write_address += + ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + } + return vendor_lttpr_write_address; +} + +uint32_t link_get_fixed_vs_pe_retimer_read_address(struct dc_link *link) +{ + return link_get_fixed_vs_pe_retimer_write_address(link) + 4; +} + +bool link_configure_fixed_vs_pe_retimer(struct ddc_service *ddc, const uint8_t *data, uint32_t length) +{ + struct aux_payload write_payload = { + .i2c_over_aux = false, + .write = true, + .address = link_get_fixed_vs_pe_retimer_write_address(ddc->link), + .length = length, + .data = (uint8_t *) data, + .reply = NULL, + .mot = I2C_MOT_UNDEF, + .write_status_update = false, + .defer_delay = 0, + }; + + return link_aux_transfer_with_retries_no_mutex(ddc, + &write_payload); +} + +bool link_query_fixed_vs_pe_retimer(struct ddc_service *ddc, uint8_t *data, uint32_t length) +{ + struct aux_payload read_payload = { + .i2c_over_aux = false, + .write = false, + .address = link_get_fixed_vs_pe_retimer_read_address(ddc->link), + .length = length, + .data = data, + .reply = NULL, + .mot = I2C_MOT_UNDEF, + .write_status_update = false, + .defer_delay = 0, + }; + + return link_aux_transfer_with_retries_no_mutex(ddc, + &read_payload); +} + bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc, struct aux_payload *payload) { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h index 860ef15d7f1b..a3e25e55bed6 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h @@ -72,6 +72,20 @@ bool link_query_ddc_data( bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc, struct aux_payload *payload); +bool link_configure_fixed_vs_pe_retimer( + struct ddc_service *ddc, + const uint8_t *data, + uint32_t length); + +bool link_query_fixed_vs_pe_retimer( + struct ddc_service *ddc, + uint8_t *data, + uint32_t length); + +uint32_t link_get_fixed_vs_pe_retimer_read_address(struct dc_link *link); +uint32_t link_get_fixed_vs_pe_retimer_write_address(struct dc_link *link); + + void write_scdc_data( struct ddc_service *ddc_service, uint32_t pix_clk, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c index ca0543e62917..fd8f6f198146 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c @@ -36,6 +36,7 @@ #include "link_dpcd.h" #include "link_dp_phy.h" #include "link_dp_capability.h" +#include "link_ddc.h" #define DC_LOGGER \ link->ctx->logger @@ -46,42 +47,20 @@ void dp_fixed_vs_pe_read_lane_adjust( { const uint8_t vendor_lttpr_write_data_vs[3] = {0x0, 0x53, 0x63}; const uint8_t vendor_lttpr_write_data_pe[3] = {0x0, 0x54, 0x63}; - const uint8_t offset = dp_parse_lttpr_repeater_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - uint32_t vendor_lttpr_write_address = 0xF004F; - uint32_t vendor_lttpr_read_address = 0xF0053; uint8_t dprx_vs = 0; uint8_t dprx_pe = 0; uint8_t lane; - if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - vendor_lttpr_read_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - } - /* W/A to read lane settings requested by DPRX */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_read_dpcd( - link, - vendor_lttpr_read_address, - &dprx_vs, - 1); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); - core_link_read_dpcd( - link, - vendor_lttpr_read_address, - &dprx_pe, - 1); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + + link_query_fixed_vs_pe_retimer(link->ddc, &dprx_vs, 1); + + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); + + link_query_fixed_vs_pe_retimer(link->ddc, &dprx_pe, 1); for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET = (dprx_vs >> (2 * lane)) & 0x3; @@ -95,19 +74,11 @@ void dp_fixed_vs_pe_set_retimer_lane_settings( const union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX], uint8_t lane_count) { - const uint8_t offset = dp_parse_lttpr_repeater_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF}; - uint32_t vendor_lttpr_write_address = 0xF004F; uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; uint8_t lane = 0; - if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - } - for (lane = 0; lane < lane_count; lane++) { vendor_lttpr_write_data_vs[3] |= dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET << (2 * lane); @@ -116,21 +87,14 @@ void dp_fixed_vs_pe_set_retimer_lane_settings( } /* Force LTTPR to output desired VS and PE */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_reset[0], sizeof(vendor_lttpr_write_data_reset)); + + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); } static enum link_training_result perform_fixed_vs_pe_nontransparent_training_sequence( @@ -241,7 +205,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( const uint8_t vendor_lttpr_write_data_4lane_3[4] = {0x1, 0x6D, 0xF2, 0x18}; const uint8_t vendor_lttpr_write_data_4lane_4[4] = {0x1, 0x6C, 0xF2, 0x03}; const uint8_t vendor_lttpr_write_data_4lane_5[4] = {0x1, 0x03, 0xF3, 0x06}; - uint32_t vendor_lttpr_write_address = 0xF004F; enum link_training_result status = LINK_TRAINING_SUCCESS; uint8_t lane = 0; union down_spread_ctrl downspread = {0}; @@ -259,8 +222,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( } if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); if (offset == 2) { pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; @@ -271,28 +232,17 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( } /* Vendor specific: Reset lane settings */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_reset[0], sizeof(vendor_lttpr_write_data_reset)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* Vendor specific: Enable intercept */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_intercept_en[0], - sizeof(vendor_lttpr_write_data_intercept_en)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); + /* 1. set link rate, lane count and spread. */ @@ -344,31 +294,16 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( lt_settings->link_settings.link_spread); if (lt_settings->link_settings.lane_count == LANE_COUNT_FOUR) { - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_1[0], - sizeof(vendor_lttpr_write_data_4lane_1)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_2[0], - sizeof(vendor_lttpr_write_data_4lane_2)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_3[0], - sizeof(vendor_lttpr_write_data_4lane_3)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_4[0], - sizeof(vendor_lttpr_write_data_4lane_4)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_5[0], - sizeof(vendor_lttpr_write_data_4lane_5)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_1[0], sizeof(vendor_lttpr_write_data_4lane_1)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_2[0], sizeof(vendor_lttpr_write_data_4lane_2)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_3[0], sizeof(vendor_lttpr_write_data_4lane_3)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_4[0], sizeof(vendor_lttpr_write_data_4lane_4)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_5[0], sizeof(vendor_lttpr_write_data_4lane_5)); } /* 2. Perform link training */ @@ -383,7 +318,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; union lane_align_status_updated dpcd_lane_status_updated; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - enum dc_status dpcd_status = DC_OK; uint8_t i = 0; retries_cr = 0; @@ -418,18 +352,12 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( for (i = 0; i < max_vendor_dpcd_retries; i++) { if (pre_disable_intercept_delay_ms != 0) msleep(pre_disable_intercept_delay_ms); - dpcd_status = core_link_write_dpcd( - link, - vendor_lttpr_write_address, + if (link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_dis[0], - sizeof(vendor_lttpr_write_data_intercept_dis)); - - if (dpcd_status == DC_OK) + sizeof(vendor_lttpr_write_data_intercept_dis))) break; - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); } @@ -445,16 +373,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); dpcd_set_lane_settings( link, @@ -550,16 +472,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* 2. update DPCD*/ if (!retries_ch_eq) @@ -636,7 +552,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( const uint8_t vendor_lttpr_write_data_4lane_3[4] = {0x1, 0x6D, 0xF2, 0x18}; const uint8_t vendor_lttpr_write_data_4lane_4[4] = {0x1, 0x6C, 0xF2, 0x03}; const uint8_t vendor_lttpr_write_data_4lane_5[4] = {0x1, 0x03, 0xF3, 0x06}; - uint32_t vendor_lttpr_write_address = 0xF004F; enum link_training_result status = LINK_TRAINING_SUCCESS; uint8_t lane = 0; union down_spread_ctrl downspread = {0}; @@ -654,8 +569,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( } if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); if (offset == 2) { pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; @@ -666,28 +579,16 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( } /* Vendor specific: Reset lane settings */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_reset[0], sizeof(vendor_lttpr_write_data_reset)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* Vendor specific: Enable intercept */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_intercept_en[0], - sizeof(vendor_lttpr_write_data_intercept_en)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); /* 1. set link rate, lane count and spread. */ @@ -739,31 +640,16 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( lt_settings->link_settings.link_spread); if (lt_settings->link_settings.lane_count == LANE_COUNT_FOUR) { - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_1[0], - sizeof(vendor_lttpr_write_data_4lane_1)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_2[0], - sizeof(vendor_lttpr_write_data_4lane_2)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_3[0], - sizeof(vendor_lttpr_write_data_4lane_3)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_4[0], - sizeof(vendor_lttpr_write_data_4lane_4)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_4lane_5[0], - sizeof(vendor_lttpr_write_data_4lane_5)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_1[0], sizeof(vendor_lttpr_write_data_4lane_1)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_2[0], sizeof(vendor_lttpr_write_data_4lane_2)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_3[0], sizeof(vendor_lttpr_write_data_4lane_3)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_4[0], sizeof(vendor_lttpr_write_data_4lane_4)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_5[0], sizeof(vendor_lttpr_write_data_4lane_5)); } /* 2. Perform link training */ @@ -778,7 +664,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; union lane_align_status_updated dpcd_lane_status_updated; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - enum dc_status dpcd_status = DC_OK; uint8_t i = 0; retries_cr = 0; @@ -813,18 +698,12 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( for (i = 0; i < max_vendor_dpcd_retries; i++) { if (pre_disable_intercept_delay_ms != 0) msleep(pre_disable_intercept_delay_ms); - dpcd_status = core_link_write_dpcd( - link, - vendor_lttpr_write_address, + if (link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_dis[0], - sizeof(vendor_lttpr_write_data_intercept_dis)); - - if (dpcd_status == DC_OK) + sizeof(vendor_lttpr_write_data_intercept_dis))) break; - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); } @@ -840,16 +719,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); dpcd_set_lane_settings( link, @@ -922,17 +795,14 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_adicora_eq1[0], sizeof(vendor_lttpr_write_data_adicora_eq1)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_adicora_eq2[0], sizeof(vendor_lttpr_write_data_adicora_eq2)); + /* Note: also check that TPS4 is a supported feature*/ tr_pattern = lt_settings->pattern_for_eq; @@ -956,16 +826,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* 2. update DPCD*/ if (!retries_ch_eq) { @@ -978,11 +842,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( lt_settings, tr_pattern, 0); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_adicora_eq3[0], - sizeof(vendor_lttpr_write_data_adicora_eq3)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_adicora_eq3[0], + sizeof(vendor_lttpr_write_data_adicora_eq3)); + } else dpcd_set_lane_settings(link, lt_settings, 0); -- cgit From 97c2eba5d6fb33ada411ce92883823ddc080e40b Mon Sep 17 00:00:00 2001 From: Muhammad Ahmed Date: Fri, 28 Jul 2023 16:08:44 -0400 Subject: drm/amd/display: disable clock gating logic reversed bug fix [Why] disable clock gating logic reversed bug fix Reviewed-by: Charlene Liu Acked-by: Stylon Wang Signed-off-by: Muhammad Ahmed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c index 7445ed27852a..1f4e0b6261ad 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c @@ -1018,8 +1018,8 @@ void hubbub31_init(struct hubbub *hubbub) /*done in hwseq*/ /*REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);*/ REG_UPDATE_2(DCHUBBUB_CLOCK_CNTL, - DISPCLK_R_DCHUBBUB_GATE_DIS, 0, - DCFCLK_R_DCHUBBUB_GATE_DIS, 0); + DISPCLK_R_DCHUBBUB_GATE_DIS, 1, + DCFCLK_R_DCHUBBUB_GATE_DIS, 1); } /* diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c index a18b9c0c5709..8bfef6d095b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c @@ -955,8 +955,8 @@ void hubbub32_init(struct hubbub *hubbub) /*REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);*/ REG_UPDATE_2(DCHUBBUB_CLOCK_CNTL, - DISPCLK_R_DCHUBBUB_GATE_DIS, 0, - DCFCLK_R_DCHUBBUB_GATE_DIS, 0); + DISPCLK_R_DCHUBBUB_GATE_DIS, 1, + DCFCLK_R_DCHUBBUB_GATE_DIS, 1); } /* ignore the "df_pre_cstate_req" from the SDP port control. -- cgit From 3831989d62b11e3ef3fdcc44cbed57812082e8b0 Mon Sep 17 00:00:00 2001 From: Eric Huang Date: Thu, 10 Aug 2023 16:01:30 -0400 Subject: drm/amdkfd: workaround address watch clearing bug for gfx v9.4.2 KFD currently relies on MEC FW to clear tcp watch control register on UNMAP_PROCESS, but FW doesn't work on it, which is a bug. So the solution is to clear the register as gfx v9 in KFD. Signed-off-by: Eric Huang Reviewed-by: Jonathan Kim Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c index e2fed6edbdd0..aff08321e976 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c @@ -163,12 +163,6 @@ static uint32_t kgd_gfx_aldebaran_set_address_watch( return watch_address_cntl; } -static uint32_t kgd_gfx_aldebaran_clear_address_watch(struct amdgpu_device *adev, - uint32_t watch_id) -{ - return 0; -} - const struct kfd2kgd_calls aldebaran_kfd2kgd = { .program_sh_mem_settings = kgd_gfx_v9_program_sh_mem_settings, .set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping, @@ -193,7 +187,7 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = { .set_wave_launch_trap_override = kgd_aldebaran_set_wave_launch_trap_override, .set_wave_launch_mode = kgd_aldebaran_set_wave_launch_mode, .set_address_watch = kgd_gfx_aldebaran_set_address_watch, - .clear_address_watch = kgd_gfx_aldebaran_clear_address_watch, + .clear_address_watch = kgd_gfx_v9_clear_address_watch, .get_iq_wait_times = kgd_gfx_v9_get_iq_wait_times, .build_grace_period_packet_info = kgd_gfx_v9_build_grace_period_packet_info, .program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings, -- cgit From 945355c96e967aa24712e632ee7c838efc649f2c Mon Sep 17 00:00:00 2001 From: Samir Dhume Date: Thu, 10 Aug 2023 21:00:31 -0400 Subject: drm/amdgpu/vcn: change end doorbell index for vcn_v4_0_3 For sriov, doorbell index for vcn0 for AID needs to be on 32 byte boundary so we need to move the vcn end doorbell Signed-off-by: Samir Dhume Acked-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h index a4ecb802d2f9..09f6727e7c73 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h @@ -334,14 +334,14 @@ enum AMDGPU_DOORBELL_ASSIGNMENT_LAYOUT1 { AMDGPU_DOORBELL_LAYOUT1_sDMA_ENGINE_END = 0x19F, /* IH: 0x1A0 ~ 0x1AF */ AMDGPU_DOORBELL_LAYOUT1_IH = 0x1A0, - /* VCN: 0x1B0 ~ 0x1D4 */ + /* VCN: 0x1B0 ~ 0x1E8 */ AMDGPU_DOORBELL_LAYOUT1_VCN_START = 0x1B0, - AMDGPU_DOORBELL_LAYOUT1_VCN_END = 0x1D4, + AMDGPU_DOORBELL_LAYOUT1_VCN_END = 0x1E8, AMDGPU_DOORBELL_LAYOUT1_FIRST_NON_CP = AMDGPU_DOORBELL_LAYOUT1_sDMA_ENGINE_START, AMDGPU_DOORBELL_LAYOUT1_LAST_NON_CP = AMDGPU_DOORBELL_LAYOUT1_VCN_END, - AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT = 0x1D4, + AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT = 0x1E8, AMDGPU_DOORBELL_LAYOUT1_INVALID = 0xFFFF }; -- cgit From 30c3a3305c62c129e39893aa86840ff8ee64df46 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Mon, 31 Jul 2023 17:56:23 -0400 Subject: drm/amd/display: Enable subvp high refresh up to 175hz [Description] Expand the SubVP policy to include up to 175hz displays for better power saving on more display configs. Reviewed-by: Chaitanya Dhere Acked-by: Stylon Wang Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') 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 05bb23bc122d..01fe2d2fd241 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -321,7 +321,7 @@ static bool is_subvp_high_refresh_candidate(struct dc_stream_state *stream) * remain in HW cursor mode if there's no cursor update which will * then cause corruption. */ - if ((refresh_rate >= 120 && refresh_rate <= 165 && + if ((refresh_rate >= 120 && refresh_rate <= 175 && stream->timing.v_addressable >= 1440 && stream->timing.v_addressable <= 2160) && (dc->current_state->stream_count > 1 || diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 0f882b879b0d..6d60ae0133ee 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -37,7 +37,7 @@ static const struct subvp_high_refresh_list subvp_high_refresh_list = { .min_refresh = 120, - .max_refresh = 165, + .max_refresh = 175, .res = { {.width = 3840, .height = 2160, }, {.width = 3440, .height = 1440, }, @@ -1064,7 +1064,8 @@ static bool subvp_subvp_admissable(struct dc *dc, } if (subvp_count == 2 && ((min_refresh < 120 && max_refresh < 120) || - (min_refresh >= 120 && max_refresh <= 165))) + (min_refresh >= subvp_high_refresh_list.min_refresh && + max_refresh <= subvp_high_refresh_list.max_refresh))) result = true; return result; -- cgit From aa298b30ce566bb7fe0d5967d3d864cf636d8e4f Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Tue, 1 Aug 2023 11:19:38 -0400 Subject: drm/amd/display: PMFW to wait for DMCUB ack for FPO cases [Description] We want PMFW to wait for DMCUB to ACK the MCLK end message for FPO cases as well. Reviewed-by: Samson Tam Acked-by: Stylon Wang Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 5 +++++ .../gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.c | 7 +++++++ .../gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.h | 1 + 3 files changed, 13 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c index 360a71763061..984b52923534 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -555,6 +555,11 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base, } } + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) + dcn32_smu_wait_for_dmub_ack_mclk(clk_mgr, true); + else + dcn32_smu_wait_for_dmub_ack_mclk(clk_mgr, false); + /* Always update saved value, even if new value not set due to P-State switching unsupported. Also check safe_to_lower for FCLK */ if (safe_to_lower && (clk_mgr_base->clks.fclk_p_state_change_support != clk_mgr_base->clks.fclk_prev_p_state_change_support)) { update_fclk = true; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.c index fb524fe4ab26..700ce42036d7 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.c @@ -139,3 +139,10 @@ unsigned int dcn32_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, ui return response; } + +void dcn32_smu_wait_for_dmub_ack_mclk(struct clk_mgr_internal *clk_mgr, bool enable) +{ + smu_print("PMFW to wait for DMCUB ack for MCLK : %d\n", enable); + + dcn32_smu_send_msg_with_param(clk_mgr, 0x14, enable ? 1 : 0, NULL); +} diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.h index a68038a41972..a34c258c19dc 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr_smu_msg.h @@ -43,5 +43,6 @@ void dcn32_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr); void dcn32_smu_send_cab_for_uclk_message(struct clk_mgr_internal *clk_mgr, unsigned int num_ways); void dcn32_smu_transfer_wm_table_dram_2_smu(struct clk_mgr_internal *clk_mgr); unsigned int dcn32_smu_set_hard_min_by_freq(struct clk_mgr_internal *clk_mgr, uint32_t clk, uint16_t freq_mhz); +void dcn32_smu_wait_for_dmub_ack_mclk(struct clk_mgr_internal *clk_mgr, bool enable); #endif /* __DCN32_CLK_MGR_SMU_MSG_H_ */ -- cgit From d288c87151a176cda322e8ae19ec307353706cc3 Mon Sep 17 00:00:00 2001 From: Krunoslav Kovac Date: Mon, 31 Jul 2023 16:46:14 -0400 Subject: drm/amd/display: Gamut remap only changes missed [WHY&HOW] If surface format is dynamically changed within app without changing timing / whole plane, we don't reprogram gamut remap matrix. Issue example: Linear FP16 scRGB going to PQ+BT.2020 monitor. Remap = scRGB->BT.2020 App switches swapchain format to 10-bit PQ+BT.2020. SW calculates correctly that new Remap = bypass (in=-out=BT.2020). But update not applied in HW. Reviewed-by: Jun Lei Acked-by: Stylon Wang Signed-off-by: Krunoslav Kovac Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index b196b7ff1a0d..65fa9e21ad9c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1638,6 +1638,7 @@ static void dcn20_update_dchubp_dpp( if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed || pipe_ctx->update_flags.bits.plane_changed || pipe_ctx->stream->update_flags.bits.gamut_remap + || plane_state->update_flags.bits.gamut_remap_change || pipe_ctx->stream->update_flags.bits.out_csc) { /* dpp/cm gamut remap*/ dc->hwss.program_gamut_remap(pipe_ctx); -- cgit From 73d450926432c7cb48f668b774629b596afe6084 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Tue, 1 Aug 2023 13:04:22 -0400 Subject: drm/amd/display: fix incorrect stream_res allocation for older ASIC [why] There is a recent work for developing a new pipe resource allocation policy used for new ASIC. The new code change needs to modify asic independent pipe resource allocation flow and hook up the new allocation policy in asic dependent layer. Unfortunately this change revealed a hidden bug in the old pipe resource allocation sequence used for older asics. In the older version of acquiring pipe for layer, we are always assigning otg master's opp and tg to the newly allocated secondary dpp pipe. This logic is incorrect when the secodnary dpp pipe is connected to a secondary opp head pipe in ODM combine configuration. Before the recent change, we will overwrite this wrong assignement in asic independent layer again. This covers up the issue. With the recent change, we will no longer cover up this in upper layer and therefore causes wrong tg and opp assignement to the secondary dpp pipe connected to a secondary opp head. [how] Always assign tg and opp from its own opp head instead of otg master. Reviewed-by: Martin Leung Acked-by: Stylon Wang Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index dfecb9602f49..efa600e46194 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2151,28 +2151,27 @@ struct pipe_ctx *dcn20_acquire_free_pipe_for_layer( const struct dc_state *cur_ctx, struct dc_state *new_ctx, const struct resource_pool *pool, - const struct pipe_ctx *opp_head_pipe) + const struct pipe_ctx *opp_head) { struct resource_context *res_ctx = &new_ctx->res_ctx; - struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, opp_head_pipe->stream); - struct pipe_ctx *idle_pipe = find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe); + struct pipe_ctx *otg_master = resource_get_head_pipe_for_stream(res_ctx, opp_head->stream); + struct pipe_ctx *sec_dpp_pipe = find_free_secondary_pipe_legacy(res_ctx, pool, otg_master); - if (!head_pipe) - ASSERT(0); + ASSERT(otg_master); - if (!idle_pipe) + if (!sec_dpp_pipe) return NULL; - idle_pipe->stream = head_pipe->stream; - idle_pipe->stream_res.tg = head_pipe->stream_res.tg; - idle_pipe->stream_res.opp = head_pipe->stream_res.opp; + sec_dpp_pipe->stream = opp_head->stream; + sec_dpp_pipe->stream_res.tg = opp_head->stream_res.tg; + sec_dpp_pipe->stream_res.opp = opp_head->stream_res.opp; - idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx]; - idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx]; - idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx]; - idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst; + sec_dpp_pipe->plane_res.hubp = pool->hubps[sec_dpp_pipe->pipe_idx]; + sec_dpp_pipe->plane_res.ipp = pool->ipps[sec_dpp_pipe->pipe_idx]; + sec_dpp_pipe->plane_res.dpp = pool->dpps[sec_dpp_pipe->pipe_idx]; + sec_dpp_pipe->plane_res.mpcc_inst = pool->dpps[sec_dpp_pipe->pipe_idx]->inst; - return idle_pipe; + return sec_dpp_pipe; } bool dcn20_get_dcc_compression_cap(const struct dc *dc, -- cgit From 133fe0dd99a9b896fe66fd4bc682227e8bbd4ded Mon Sep 17 00:00:00 2001 From: Nicholas Susanto Date: Mon, 31 Jul 2023 13:19:38 -0400 Subject: drm/amd/display: Enable 8k60hz mode on single display [Why] 8k60hz compliace test failing because we restrict it single memory channels. Workaround by not restricting it on single displays. [How] Adding an additional check to DCN314 to restrict 8k60hz mode if it has more than 1 display connected. Reviewed-by: Nicholas Kazlauskas Acked-by: Stylon Wang Signed-off-by: Nicholas Susanto Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c index 5e9459e26469..4e09ba4f2806 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -1689,7 +1689,9 @@ static bool filter_modes_for_single_channel_workaround(struct dc *dc, struct dc_state *context) { // Filter 2K@240Hz+8K@24fps above combination timing if memory only has single dimm LPDDR - if (dc->clk_mgr->bw_params->vram_type == 34 && dc->clk_mgr->bw_params->num_channels < 2) { + if (dc->clk_mgr->bw_params->vram_type == 34 && + dc->clk_mgr->bw_params->num_channels < 2 && + context->stream_count > 1) { int total_phy_pix_clk = 0; for (int i = 0; i < context->stream_count; i++) -- cgit From 53f3288079460ec7c86a39871af5c8b2a5d48685 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Fri, 28 Jul 2023 13:42:37 -0400 Subject: drm/amd/display: implement pipe type definition and adding accessors [why] There is a lack of encapsulation of pipe connection representation in pipe context. This has caused many challenging bugs and coding errors with repeated logic to identify the same pipe type. [how] Formally define pipe types and provide getters to identify a pipe type and find a pipe based on specific requirements. Update existing logic in non dcn specific files and dcn32 and future versions to use the new accessors. Reviewed-by: Jun Lei Acked-by: Stylon Wang Signed-off-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 41 ++-- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 186 +++++++++-------- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 22 ++- .../drm/amd/display/dc/dce100/dce100_resource.c | 2 +- .../drm/amd/display/dc/dce110/dce110_resource.c | 2 +- .../drm/amd/display/dc/dce112/dce112_resource.c | 4 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 6 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 18 +- .../drm/amd/display/dc/dcn201/dcn201_resource.c | 4 +- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 12 +- .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c | 4 +- .../amd/display/dc/dcn32/dcn32_resource_helpers.c | 12 +- .../gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c | 2 +- .../gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c | 2 +- .../gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 2 +- .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 11 +- drivers/gpu/drm/amd/display/dc/inc/resource.h | 220 +++++++++++++++++++-- .../amd/display/dc/link/accessories/link_dp_cts.c | 3 +- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 7 +- 19 files changed, 375 insertions(+), 185 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 508d5ea89b8b..566d7045b2de 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -586,18 +586,15 @@ dc_stream_forward_crc_window(struct dc_stream_state *stream, bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, struct crc_params *crc_window, bool enable, bool continuous) { - int i; struct pipe_ctx *pipe; struct crc_params param; struct timing_generator *tg; - for (i = 0; i < MAX_PIPES; i++) { - pipe = &dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe) - break; - } + pipe = resource_get_otg_master_for_stream( + &dc->current_state->res_ctx, stream); + /* Stream not found */ - if (i == MAX_PIPES) + if (pipe == NULL) return false; /* By default, capture the full frame */ @@ -1064,7 +1061,7 @@ static void apply_ctx_interdependent_lock(struct dc *dc, // Copied conditions that were previously in dce110_apply_ctx_for_surface if (stream == pipe_ctx->stream) { - if (!pipe_ctx->top_pipe && + if (resource_is_pipe_type(pipe_ctx, OPP_HEAD) && (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) dc->hwss.pipe_control_lock(dc, pipe_ctx, lock); } @@ -3164,7 +3161,7 @@ static void commit_planes_do_stream_update(struct dc *dc, for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; - if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) { + if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) && pipe_ctx->stream == stream) { if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt) dc->hwss.setup_periodic_interrupt(dc, pipe_ctx); @@ -3446,16 +3443,9 @@ static void commit_planes_for_stream_fast(struct dc *dc, struct pipe_ctx *top_pipe_to_program = NULL; dc_z10_restore(dc); - for (j = 0; j < dc->res_pool->pipe_count; j++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; - - if (!pipe_ctx->top_pipe && - !pipe_ctx->prev_odm_pipe && - pipe_ctx->stream && - pipe_ctx->stream == stream) { - top_pipe_to_program = pipe_ctx; - } - } + top_pipe_to_program = resource_get_otg_master_for_stream( + &context->res_ctx, + stream); if (dc->debug.visual_confirm) { for (i = 0; i < dc->res_pool->pipe_count; i++) { @@ -3560,16 +3550,9 @@ static void commit_planes_for_stream(struct dc *dc, context_clock_trace(dc, context); } - for (j = 0; j < dc->res_pool->pipe_count; j++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; - - if (!pipe_ctx->top_pipe && - !pipe_ctx->prev_odm_pipe && - pipe_ctx->stream && - pipe_ctx->stream == stream) { - top_pipe_to_program = pipe_ctx; - } - } + top_pipe_to_program = resource_get_otg_master_for_stream( + &context->res_ctx, + stream); for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 853e5b99dd62..f7b51aca6020 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -732,10 +732,10 @@ static inline void get_vp_scan_direction( *flip_horz_scan_dir = !*flip_horz_scan_dir; } -int get_num_mpc_splits(struct pipe_ctx *pipe) +int resource_get_num_mpc_splits(const struct pipe_ctx *pipe) { int mpc_split_count = 0; - struct pipe_ctx *other_pipe = pipe->bottom_pipe; + const struct pipe_ctx *other_pipe = pipe->bottom_pipe; while (other_pipe && other_pipe->plane_state == pipe->plane_state) { mpc_split_count++; @@ -750,40 +750,30 @@ int get_num_mpc_splits(struct pipe_ctx *pipe) return mpc_split_count; } -int get_num_odm_splits(struct pipe_ctx *pipe) +int resource_get_num_odm_splits(const struct pipe_ctx *pipe) { int odm_split_count = 0; - struct pipe_ctx *next_pipe = NULL; - while (pipe->top_pipe) - pipe = pipe->top_pipe; + pipe = resource_get_otg_master(pipe); - next_pipe = pipe->next_odm_pipe; - while (next_pipe) { + while (pipe->next_odm_pipe) { odm_split_count++; - next_pipe = next_pipe->next_odm_pipe; - } - pipe = pipe->prev_odm_pipe; - while (pipe) { - odm_split_count++; - pipe = pipe->prev_odm_pipe; + pipe = pipe->next_odm_pipe; } return odm_split_count; } static int get_odm_split_index(struct pipe_ctx *pipe_ctx) { - struct pipe_ctx *split_pipe = NULL; int index = 0; - while (pipe_ctx->top_pipe) - pipe_ctx = pipe_ctx->top_pipe; - - split_pipe = pipe_ctx->prev_odm_pipe; + pipe_ctx = resource_get_opp_head(pipe_ctx); + if (!pipe_ctx) + return 0; - while (split_pipe) { + while (pipe_ctx->prev_odm_pipe) { index++; - split_pipe = split_pipe->prev_odm_pipe; + pipe_ctx = pipe_ctx->prev_odm_pipe; } return index; @@ -854,7 +844,7 @@ static struct rect shift_rec(const struct rect *rec_in, int x, int y) static struct rect calculate_odm_slice_in_timing_active(struct pipe_ctx *pipe_ctx) { const struct dc_stream_state *stream = pipe_ctx->stream; - int odm_slice_count = get_num_odm_splits(pipe_ctx) + 1; + int odm_slice_count = resource_get_num_odm_splits(pipe_ctx) + 1; int odm_slice_idx = get_odm_split_index(pipe_ctx); bool is_last_odm_slice = (odm_slice_idx + 1) == odm_slice_count; int h_active = stream->timing.h_addressable + @@ -972,7 +962,7 @@ static struct rect calculate_mpc_slice_in_timing_active( struct rect *plane_clip_rec) { const struct dc_stream_state *stream = pipe_ctx->stream; - int mpc_slice_count = get_num_mpc_splits(pipe_ctx) + 1; + int mpc_slice_count = resource_get_num_mpc_splits(pipe_ctx) + 1; int mpc_slice_idx = get_mpc_split_index(pipe_ctx); int epimo = mpc_slice_count - plane_clip_rec->width % mpc_slice_count - 1; struct rect mpc_rec; @@ -1565,7 +1555,7 @@ enum dc_status resource_build_scaling_params_for_context( return DC_OK; } -struct pipe_ctx *find_free_secondary_pipe_legacy( +struct pipe_ctx *resource_find_free_secondary_pipe_legacy( struct resource_context *res_ctx, const struct resource_pool *pool, const struct pipe_ctx *primary_pipe) @@ -1631,7 +1621,7 @@ int resource_find_free_pipe_used_in_cur_mpc_blending_tree( const struct pipe_ctx *cur_opp_head) { const struct pipe_ctx *cur_sec_dpp = cur_opp_head->bottom_pipe; - struct pipe_ctx *new_sec_dpp; + struct pipe_ctx *new_pipe; int free_pipe_idx = FREE_PIPE_INDEX_NOT_FOUND; while (cur_sec_dpp) { @@ -1639,9 +1629,8 @@ int resource_find_free_pipe_used_in_cur_mpc_blending_tree( * this is to avoid MPO pipe switching to different opp blending * tree */ - new_sec_dpp = &new_res_ctx->pipe_ctx[cur_sec_dpp->pipe_idx]; - if (new_sec_dpp->plane_state == NULL && - new_sec_dpp->stream == NULL) { + new_pipe = &new_res_ctx->pipe_ctx[cur_sec_dpp->pipe_idx]; + if (resource_is_pipe_type(new_pipe, FREE_PIPE)) { free_pipe_idx = cur_sec_dpp->pipe_idx; break; } @@ -1657,17 +1646,15 @@ int recource_find_free_pipe_not_used_in_cur_res_ctx( const struct resource_pool *pool) { int free_pipe_idx = FREE_PIPE_INDEX_NOT_FOUND; - const struct pipe_ctx *new_sec_dpp, *cur_sec_dpp; + const struct pipe_ctx *new_pipe, *cur_pipe; int i; for (i = 0; i < pool->pipe_count; i++) { - cur_sec_dpp = &cur_res_ctx->pipe_ctx[i]; - new_sec_dpp = &new_res_ctx->pipe_ctx[i]; + cur_pipe = &cur_res_ctx->pipe_ctx[i]; + new_pipe = &new_res_ctx->pipe_ctx[i]; - if (cur_sec_dpp->plane_state == NULL && - cur_sec_dpp->stream == NULL && - new_sec_dpp->plane_state == NULL && - new_sec_dpp->stream == NULL) { + if (resource_is_pipe_type(cur_pipe, FREE_PIPE) && + resource_is_pipe_type(new_pipe, FREE_PIPE)) { free_pipe_idx = i; break; } @@ -1682,18 +1669,17 @@ int resource_find_free_pipe_used_as_cur_sec_dpp_in_mpcc_combine( const struct resource_pool *pool) { int free_pipe_idx = FREE_PIPE_INDEX_NOT_FOUND; - const struct pipe_ctx *new_sec_dpp, *cur_sec_dpp; + const struct pipe_ctx *new_pipe, *cur_pipe; int i; for (i = 0; i < pool->pipe_count; i++) { - cur_sec_dpp = &cur_res_ctx->pipe_ctx[i]; - new_sec_dpp = &new_res_ctx->pipe_ctx[i]; - - if (cur_sec_dpp->plane_state && - cur_sec_dpp->top_pipe && - cur_sec_dpp->top_pipe->plane_state == cur_sec_dpp->plane_state && - new_sec_dpp->plane_state == NULL && - new_sec_dpp->stream == NULL) { + cur_pipe = &cur_res_ctx->pipe_ctx[i]; + new_pipe = &new_res_ctx->pipe_ctx[i]; + + if (resource_is_pipe_type(cur_pipe, DPP_PIPE) && + !resource_is_pipe_type(cur_pipe, OPP_HEAD) && + resource_is_for_mpcc_combine(cur_pipe) && + resource_is_pipe_type(new_pipe, FREE_PIPE)) { free_pipe_idx = i; break; } @@ -1706,14 +1692,13 @@ int resource_find_any_free_pipe(struct resource_context *new_res_ctx, const struct resource_pool *pool) { int free_pipe_idx = FREE_PIPE_INDEX_NOT_FOUND; - const struct pipe_ctx *new_sec_dpp; + const struct pipe_ctx *new_pipe; int i; for (i = 0; i < pool->pipe_count; i++) { - new_sec_dpp = &new_res_ctx->pipe_ctx[i]; + new_pipe = &new_res_ctx->pipe_ctx[i]; - if (new_sec_dpp->plane_state == NULL && - new_sec_dpp->stream == NULL) { + if (resource_is_pipe_type(new_pipe, FREE_PIPE)) { free_pipe_idx = i; break; } @@ -1722,51 +1707,83 @@ int resource_find_any_free_pipe(struct resource_context *new_res_ctx, return free_pipe_idx; } -/* TODO: Unify the pipe naming convention: - * - * OPP head pipe - the head pipe of an MPC blending tree with a functional OPP - * feeding to an OTG. OPP head pipe is by convention the top most pipe. i.e. - * pipe's top_pipe is NULL. - * - * OTG master pipe - the master pipe of its OPP head pipes with a functional - * OTG. It merges all its OPP head pipes pixel data from their MPCs in ODM block - * and output to backend DIG. OTG master pipe is by convention the top most pipe - * of the first odm slice. i.e. pipe's top_pipe is NULL and pipe's prev_odm_pipe - * is NULL. - * - * Secondary OPP head pipe - an OPP head pipe which is not an OTG master pipe. - * Its output feeds to another OTG master pipe. i.e pipe's top_pipe is NULL and - * pipe's prev_odm_pipe is not NULL. - * - * Secondary DPP pipe - the pipe with a functional DPP outputting to another OPP - * head pipe's MPC. Its output is a secondary layer in the OPP head's MPC - * blending tree. Secondary DPP pipe is by convention a non top most pipe. i.e - * pipe's top_pipe should be not NULL. - * - * The function below is actually getting the OTG master pipe associated with - * the stream. Name it as getting head pipe is confusing. - */ -struct pipe_ctx *resource_get_head_pipe_for_stream( +bool resource_is_pipe_type(const struct pipe_ctx *pipe_ctx, enum pipe_type type) +{ +#ifdef DBG + if (pipe_ctx->stream == NULL) { + /* a free pipe with dangling states */ + ASSERT(!pipe_ctx->plane_state); + ASSERT(!pipe_ctx->prev_odm_pipe); + ASSERT(!pipe_ctx->next_odm_pipe); + ASSERT(!pipe_ctx->top_pipe); + ASSERT(!pipe_ctx->bottom_pipe); + } else if (pipe_ctx->top_pipe) { + /* a secondary DPP pipe must be signed to a plane */ + ASSERT(pipe_ctx->plane_state) + } + /* Add more checks here to prevent corrupted pipe ctx. It is very hard + * to debug this issue afterwards because we can't pinpoint the code + * location causing inconsistent pipe context states. + */ +#endif + switch (type) { + case OTG_MASTER: + return !pipe_ctx->prev_odm_pipe && + !pipe_ctx->top_pipe && + pipe_ctx->stream; + case OPP_HEAD: + return !pipe_ctx->top_pipe && pipe_ctx->stream; + case DPP_PIPE: + return pipe_ctx->plane_state && pipe_ctx->stream; + case FREE_PIPE: + return !pipe_ctx->plane_state && !pipe_ctx->stream; + default: + return false; + } +} + +bool resource_is_for_mpcc_combine(const struct pipe_ctx *pipe_ctx) +{ + return resource_get_num_mpc_splits(pipe_ctx) > 0; +} + +struct pipe_ctx *resource_get_otg_master_for_stream( struct resource_context *res_ctx, struct dc_stream_state *stream) { int i; for (i = 0; i < MAX_PIPES; i++) { - if (res_ctx->pipe_ctx[i].stream == stream - && !res_ctx->pipe_ctx[i].top_pipe - && !res_ctx->pipe_ctx[i].prev_odm_pipe) + if (res_ctx->pipe_ctx[i].stream == stream && + resource_is_pipe_type(&res_ctx->pipe_ctx[i], OTG_MASTER)) return &res_ctx->pipe_ctx[i]; } return NULL; } +struct pipe_ctx *resource_get_otg_master(const struct pipe_ctx *pipe_ctx) +{ + struct pipe_ctx *otg_master = resource_get_opp_head(pipe_ctx); + + while (otg_master->prev_odm_pipe) + otg_master = otg_master->prev_odm_pipe; + return otg_master; +} + +struct pipe_ctx *resource_get_opp_head(const struct pipe_ctx *pipe_ctx) +{ + struct pipe_ctx *opp_head = (struct pipe_ctx *) pipe_ctx; + + ASSERT(!resource_is_pipe_type(opp_head, FREE_PIPE)); + while (opp_head->top_pipe) + opp_head = opp_head->top_pipe; + return opp_head; +} + static struct pipe_ctx *get_tail_pipe( struct pipe_ctx *head_pipe) { - struct pipe_ctx *tail_pipe; - - tail_pipe = head_pipe->bottom_pipe; + struct pipe_ctx *tail_pipe = head_pipe->bottom_pipe; while (tail_pipe) { head_pipe = tail_pipe; @@ -1908,7 +1925,7 @@ bool dc_add_plane_to_context( goto out; } - otg_master_pipe = resource_get_head_pipe_for_stream( + otg_master_pipe = resource_get_otg_master_for_stream( &context->res_ctx, stream); if (otg_master_pipe->plane_state == NULL) added = add_plane_to_opp_head_pipes(otg_master_pipe, @@ -2429,7 +2446,7 @@ enum dc_status dc_remove_stream_from_ctx( { int i; struct dc_context *dc_ctx = dc->ctx; - struct pipe_ctx *del_pipe = resource_get_head_pipe_for_stream(&new_ctx->res_ctx, stream); + struct pipe_ctx *del_pipe = resource_get_otg_master_for_stream(&new_ctx->res_ctx, stream); struct pipe_ctx *odm_pipe; if (!del_pipe) { @@ -3683,7 +3700,7 @@ enum dc_status resource_map_clock_resources( { /* acquire new resources */ const struct resource_pool *pool = dc->res_pool; - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream( + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream( &context->res_ctx, stream); if (!pipe_ctx) @@ -4073,10 +4090,7 @@ void reset_syncd_pipes_from_disabled_pipes(struct dc *dc, pipe_ctx_old = &dc->current_state->res_ctx.pipe_ctx[i]; pipe_ctx = &context->res_ctx.pipe_ctx[i]; - if (!pipe_ctx_old->stream) - continue; - - if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe) + if (!resource_is_pipe_type(pipe_ctx_old, OTG_MASTER)) continue; if (!pipe_ctx->stream || diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 530b85a50b03..4c5ef3ef8dbd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -31,6 +31,7 @@ #include "core_types.h" #include "../basics/conversion.h" #include "cursor_reg_cache.h" +#include "resource.h" #define CTX dc_dmub_srv->ctx #define DC_LOGGER CTX->logger @@ -356,7 +357,7 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru for (i = 0, k = 0; context && i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->stream && pipe->stream->fpo_in_use) { + if (resource_is_pipe_type(pipe, OTG_MASTER) && pipe->stream->fpo_in_use) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; uint8_t min_refresh_in_hz = (pipe->stream->timing.min_refresh_in_uhz + 999999) / 1000000; @@ -531,7 +532,8 @@ static void populate_subvp_cmd_vblank_pipe_info(struct dc *dc, // We check for master pipe, but it shouldn't matter since we only need // the pipe for timing info (stream should be same for any pipe splits) - if (!pipe->stream || !pipe->plane_state || pipe->top_pipe || pipe->prev_odm_pipe) + if (!resource_is_pipe_type(pipe, OTG_MASTER) || + !resource_is_pipe_type(pipe, DPP_PIPE)) continue; // Find the SubVP pipe @@ -728,12 +730,10 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc, for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->stream) - continue; - /* For SubVP pipe count, only count the top most (ODM / MPC) pipe */ - if (pipe->plane_state && !pipe->top_pipe && !pipe->prev_odm_pipe && + if (resource_is_pipe_type(pipe, OTG_MASTER) && + resource_is_pipe_type(pipe, DPP_PIPE) && pipe->stream->mall_stream_config.type == SUBVP_MAIN) subvp_pipes[subvp_count++] = pipe; } @@ -750,12 +750,14 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc, * Any ODM or MPC splits being used in SubVP will be handled internally in * populate_subvp_cmd_pipe_info */ - if (pipe->plane_state && pipe->stream->mall_stream_config.paired_stream && - !pipe->top_pipe && !pipe->prev_odm_pipe && + if (resource_is_pipe_type(pipe, OTG_MASTER) && + resource_is_pipe_type(pipe, DPP_PIPE) && + pipe->stream->mall_stream_config.paired_stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) { populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++); - } else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE && - !pipe->top_pipe && !pipe->prev_odm_pipe) { + } else if (resource_is_pipe_type(pipe, OTG_MASTER) && + resource_is_pipe_type(pipe, DPP_PIPE) && + pipe->stream->mall_stream_config.type == SUBVP_NONE) { // Don't need to check for ActiveDRAMClockChangeMargin < 0, not valid in cases where // we run through DML without calculating "natural" P-state support populate_subvp_cmd_vblank_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++); diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 42e9b6a529f6..899b25b0bad8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -824,7 +824,7 @@ static enum dc_status build_mapped_resource( struct dc_state *context, struct dc_stream_state *stream) { - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream); if (!pipe_ctx) return DC_ERROR_UNEXPECTED; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index c0214da714d4..1289b9418877 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -942,7 +942,7 @@ static enum dc_status build_mapped_resource( struct dc_state *context, struct dc_stream_state *stream) { - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream); if (!pipe_ctx) return DC_ERROR_UNEXPECTED; diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index e115ff91aaaa..2b20180f1a32 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -873,7 +873,7 @@ static enum dc_status build_mapped_resource( struct dc_state *context, struct dc_stream_state *stream) { - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream); if (!pipe_ctx) return DC_ERROR_UNEXPECTED; @@ -964,7 +964,7 @@ enum dc_status resource_map_phy_clock_resources( { /* acquire new resources */ - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream( + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream( &context->res_ctx, stream); if (!pipe_ctx) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 82e5af4d5d15..9f9145742f14 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1055,7 +1055,7 @@ static enum dc_status build_mapped_resource( struct dc_state *context, struct dc_stream_state *stream) { - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream); if (!pipe_ctx) return DC_ERROR_UNEXPECTED; @@ -1090,8 +1090,8 @@ static struct pipe_ctx *dcn10_acquire_free_pipe_for_layer( const struct pipe_ctx *opp_head_pipe) { struct resource_context *res_ctx = &new_ctx->res_ctx; - struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, opp_head_pipe->stream); - struct pipe_ctx *idle_pipe = find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe); + struct pipe_ctx *head_pipe = resource_get_otg_master_for_stream(res_ctx, opp_head_pipe->stream); + struct pipe_ctx *idle_pipe = resource_find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe); if (!head_pipe) { ASSERT(0); diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index efa600e46194..66b74bb5d936 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -1294,7 +1294,7 @@ static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx) enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream) { enum dc_status status = DC_OK; - struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); + struct pipe_ctx *pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, stream); if (!pipe_ctx) return DC_ERROR_UNEXPECTED; @@ -1948,7 +1948,7 @@ int dcn20_validate_apply_pipe_split_flags( v->ODMCombineEnablePerState[vlevel][pipe_plane]; if (v->ODMCombineEnabled[pipe_plane] == dm_odm_combine_mode_disabled) { - if (get_num_mpc_splits(pipe) == 1) { + if (resource_get_num_mpc_splits(pipe) == 1) { /*If need split for mpc but 2 way split already*/ if (split[i] == 4) split[i] = 2; /* 2 -> 4 MPC */ @@ -1956,7 +1956,7 @@ int dcn20_validate_apply_pipe_split_flags( split[i] = 0; /* 2 -> 2 MPC */ else if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) merge[i] = true; /* 2 -> 1 MPC */ - } else if (get_num_mpc_splits(pipe) == 3) { + } else if (resource_get_num_mpc_splits(pipe) == 3) { /*If need split for mpc but 4 way split already*/ if (split[i] == 2 && ((pipe->top_pipe && !pipe->top_pipe->top_pipe) || !pipe->bottom_pipe)) { @@ -1965,7 +1965,7 @@ int dcn20_validate_apply_pipe_split_flags( pipe->top_pipe->plane_state == pipe->plane_state) merge[i] = true; /* 4 -> 1 MPC */ split[i] = 0; - } else if (get_num_odm_splits(pipe)) { + } else if (resource_get_num_odm_splits(pipe)) { /* ODM -> MPC transition */ if (pipe->prev_odm_pipe) { split[i] = 0; @@ -1973,7 +1973,7 @@ int dcn20_validate_apply_pipe_split_flags( } } } else { - if (get_num_odm_splits(pipe) == 1) { + if (resource_get_num_odm_splits(pipe) == 1) { /*If need split for odm but 2 way split already*/ if (split[i] == 4) split[i] = 2; /* 2 -> 4 ODM */ @@ -1983,7 +1983,7 @@ int dcn20_validate_apply_pipe_split_flags( ASSERT(0); /* NOT expected yet */ merge[i] = true; /* exit ODM */ } - } else if (get_num_odm_splits(pipe) == 3) { + } else if (resource_get_num_odm_splits(pipe) == 3) { /*If need split for odm but 4 way split already*/ if (split[i] == 2 && ((pipe->prev_odm_pipe && !pipe->prev_odm_pipe->prev_odm_pipe) || !pipe->next_odm_pipe)) { @@ -1993,7 +1993,7 @@ int dcn20_validate_apply_pipe_split_flags( merge[i] = true; /* exit ODM */ } split[i] = 0; - } else if (get_num_mpc_splits(pipe)) { + } else if (resource_get_num_mpc_splits(pipe)) { /* MPC -> ODM transition */ ASSERT(0); /* NOT expected yet */ if (pipe->top_pipe && pipe->top_pipe->plane_state == pipe->plane_state) { @@ -2154,8 +2154,8 @@ struct pipe_ctx *dcn20_acquire_free_pipe_for_layer( const struct pipe_ctx *opp_head) { struct resource_context *res_ctx = &new_ctx->res_ctx; - struct pipe_ctx *otg_master = resource_get_head_pipe_for_stream(res_ctx, opp_head->stream); - struct pipe_ctx *sec_dpp_pipe = find_free_secondary_pipe_legacy(res_ctx, pool, otg_master); + struct pipe_ctx *otg_master = resource_get_otg_master_for_stream(res_ctx, opp_head->stream); + struct pipe_ctx *sec_dpp_pipe = resource_find_free_secondary_pipe_legacy(res_ctx, pool, otg_master); ASSERT(otg_master); diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c index 4fce3485d0f5..2dc4d2c1410b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c @@ -999,8 +999,8 @@ static struct pipe_ctx *dcn201_acquire_free_pipe_for_layer( const struct pipe_ctx *opp_head_pipe) { struct resource_context *res_ctx = &new_ctx->res_ctx; - struct pipe_ctx *head_pipe = resource_get_head_pipe_for_stream(res_ctx, opp_head_pipe->stream); - struct pipe_ctx *idle_pipe = find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe); + struct pipe_ctx *head_pipe = resource_get_otg_master_for_stream(res_ctx, opp_head_pipe->stream); + struct pipe_ctx *idle_pipe = resource_find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe); if (!head_pipe) ASSERT(0); diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c index a87afb796f47..680e7fa8d18a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -567,7 +567,7 @@ bool dcn32_set_output_transfer_func(struct dc *dc, bool ret = false; /* program OGAM or 3DLUT only for the top pipe*/ - if (pipe_ctx->top_pipe == NULL) { + if (resource_is_pipe_type(pipe_ctx, OPP_HEAD)) { /*program shaper and 3dlut in MPC*/ ret = dcn32_set_mpc_shaper_3dlut(pipe_ctx, stream); if (ret == false && mpc->funcs->set_output_gamma && stream->out_transfer_func) { @@ -1202,10 +1202,10 @@ void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_ for (i = 0; i < dc->res_pool->pipe_count; i++) { pipe = &dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe->top_pipe || pipe->prev_odm_pipe) + if (!resource_is_pipe_type(pipe, OTG_MASTER)) continue; - if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal)) + if ((pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal)) && pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) { pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg); reset_sync_context_for_pipe(dc, context, i); @@ -1299,7 +1299,7 @@ static void apply_symclk_on_tx_off_wa(struct dc_link *link) if (link->phy_state.symclk_ref_cnts.otg > 0) { for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) { + if (resource_is_pipe_type(pipe_ctx, OPP_HEAD) && pipe_ctx->stream->link == link) { pipe_ctx->clock_source->funcs->program_pix_clk( pipe_ctx->clock_source, &pipe_ctx->stream_res.pix_clk_params, @@ -1382,7 +1382,7 @@ void dcn32_apply_update_flags_for_phantom(struct pipe_ctx *phantom_pipe) { phantom_pipe->update_flags.raw = 0; if (phantom_pipe->stream && phantom_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { - if (phantom_pipe->stream && phantom_pipe->plane_state) { + if (resource_is_pipe_type(phantom_pipe, DPP_PIPE)) { phantom_pipe->update_flags.bits.enable = 1; phantom_pipe->update_flags.bits.mpcc = 1; phantom_pipe->update_flags.bits.dppclk = 1; @@ -1392,7 +1392,7 @@ void dcn32_apply_update_flags_for_phantom(struct pipe_ctx *phantom_pipe) phantom_pipe->update_flags.bits.scaler = 1; phantom_pipe->update_flags.bits.viewport = 1; phantom_pipe->update_flags.bits.det_size = 1; - if (!phantom_pipe->top_pipe && !phantom_pipe->prev_odm_pipe) { + if (resource_is_pipe_type(phantom_pipe, OTG_MASTER)) { phantom_pipe->update_flags.bits.odm = 1; phantom_pipe->update_flags.bits.global_sync = 1; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c index cadbe1dcfbfe..935cd23e6a01 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c @@ -1709,8 +1709,8 @@ void dcn32_retain_phantom_pipes(struct dc *dc, struct dc_state *context) for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->top_pipe && !pipe->prev_odm_pipe && - pipe->plane_state && pipe->stream && + if (resource_is_pipe_type(pipe, OTG_MASTER) && + resource_is_pipe_type(pipe, DPP_PIPE) && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { phantom_plane = pipe->plane_state; phantom_stream = pipe->stream; diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c index db9c55a09d9f..3ad2b48954e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -646,10 +646,8 @@ bool dcn32_subvp_drr_admissable(struct dc *dc, struct dc_state *context) for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->stream) - continue; - - if (pipe->plane_state && !pipe->top_pipe) { + if (resource_is_pipe_type(pipe, OPP_HEAD) && + resource_is_pipe_type(pipe, DPP_PIPE)) { if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) { subvp_count++; @@ -706,10 +704,8 @@ bool dcn32_subvp_vblank_admissable(struct dc *dc, struct dc_state *context, int for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe->stream) - continue; - - if (pipe->plane_state && !pipe->top_pipe) { + if (resource_is_pipe_type(pipe, OPP_HEAD) && + resource_is_pipe_type(pipe, DPP_PIPE)) { if (pipe->stream->mall_stream_config.type == SUBVP_MAIN) { subvp_count++; diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c index 0100a6053ab6..f2dfa96f9ef5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dce_calcs.c @@ -3015,7 +3015,7 @@ static bool all_displays_in_sync(const struct pipe_ctx pipe[], int i, num_active_pipes = 0; for (i = 0; i < pipe_count; i++) { - if (!pipe[i].stream || pipe[i].top_pipe) + if (!resource_is_pipe_type(&pipe[i], OPP_HEAD)) continue; active_pipes[num_active_pipes++] = &pipe[i]; diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c index 794d6517e511..50b0434354f8 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c @@ -1258,7 +1258,7 @@ bool dcn_validate_bandwidth( hsplit_pipe->pipe_dlg_param.vblank_end = pipe->pipe_dlg_param.vblank_end; } else { /* pipe not split previously needs split */ - hsplit_pipe = find_free_secondary_pipe_legacy(&context->res_ctx, pool, pipe); + hsplit_pipe = resource_find_free_secondary_pipe_legacy(&context->res_ctx, pool, pipe); ASSERT(hsplit_pipe); split_stream_across_pipes(&context->res_ctx, pool, pipe, hsplit_pipe); } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c index 8ae5ddbd1b27..8afda5ecc0cd 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c @@ -1305,7 +1305,7 @@ int dcn20_populate_dml_pipes_from_context(struct dc *dc, pipes[pipe_cnt].dout.is_virtual = 0; pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min; pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max; - switch (get_num_odm_splits(&res_ctx->pipe_ctx[i])) { + switch (resource_get_num_odm_splits(&res_ctx->pipe_ctx[i])) { case 1: pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1; break; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 6d60ae0133ee..711d4085b33b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -756,7 +756,7 @@ static bool dcn32_enough_pipes_for_subvp(struct dc *dc, struct dc_state *context struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; // Find the minimum pipe split count for non SubVP pipes - if (pipe->stream && !pipe->top_pipe && + if (resource_is_pipe_type(pipe, OPP_HEAD) && pipe->stream->mall_stream_config.type == SUBVP_NONE) { split_cnt = 0; while (pipe) { @@ -886,7 +886,8 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context) // We check for master pipe, but it shouldn't matter since we only need // the pipe for timing info (stream should be same for any pipe splits) - if (!pipe->stream || !pipe->plane_state || pipe->top_pipe || pipe->prev_odm_pipe) + if (!resource_is_pipe_type(pipe, OTG_MASTER) || + !resource_is_pipe_type(pipe, DPP_PIPE)) continue; // Find the SubVP pipe @@ -899,7 +900,8 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context) drr_pipe = &context->res_ctx.pipe_ctx[i]; // We check for master pipe only - if (!drr_pipe->stream || !drr_pipe->plane_state || drr_pipe->top_pipe || drr_pipe->prev_odm_pipe) + if (!resource_is_pipe_type(pipe, OTG_MASTER) || + !resource_is_pipe_type(pipe, DPP_PIPE)) continue; if (drr_pipe->stream->mall_stream_config.type == SUBVP_NONE && drr_pipe->stream->ignore_msa_timing_param && @@ -980,7 +982,8 @@ static bool subvp_vblank_schedulable(struct dc *dc, struct dc_state *context) // We check for master pipe, but it shouldn't matter since we only need // the pipe for timing info (stream should be same for any pipe splits) - if (!pipe->stream || !pipe->plane_state || pipe->top_pipe || pipe->prev_odm_pipe) + if (!resource_is_pipe_type(pipe, OTG_MASTER) || + !resource_is_pipe_type(pipe, DPP_PIPE)) continue; if (!found && pipe->stream->mall_stream_config.type == SUBVP_NONE) { diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 8dabbbc2a7b9..e546b9c506c1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -37,7 +37,6 @@ #define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0) #define GET_PIPE_SYNCD_FROM_PIPE(pipe) ((pipe)->pipe_idx_syncd & 0x7F) #define SET_PIPE_SYNCD_TO_PIPE(pipe, pipe_syncd) ((pipe)->pipe_idx_syncd = (0x80 | pipe_syncd)) -#define FREE_PIPE_INDEX_NOT_FOUND -1 enum dce_version resource_parse_asic_id( struct hw_asic_id asic_id); @@ -143,10 +142,6 @@ struct clock_source *dc_resource_find_first_free_pll( struct resource_context *res_ctx, const struct resource_pool *pool); -struct pipe_ctx *resource_get_head_pipe_for_stream( - struct resource_context *res_ctx, - struct dc_stream_state *stream); - bool resource_attach_surfaces_to_context( struct dc_plane_state *const *plane_state, int surface_count, @@ -154,29 +149,232 @@ bool resource_attach_surfaces_to_context( struct dc_state *context, const struct resource_pool *pool); -struct pipe_ctx *find_free_secondary_pipe_legacy( - struct resource_context *res_ctx, - const struct resource_pool *pool, - const struct pipe_ctx *primary_pipe); +#define FREE_PIPE_INDEX_NOT_FOUND -1 +/* + * pipe types are identified based on MUXes in DCN front end that are capable + * of taking input from one DCN pipeline to another DCN pipeline. The name is + * in a form of XXXX_YYYY, where XXXX is the DCN front end hardware block the + * pipeline ends with and YYYY is the rendering role that the pipe is in. + * + * For instance OTG_MASTER is a pipe ending with OTG hardware block in its + * pipeline and it is in a role of a master pipe for timing generation. + * + * For quick reference a diagram of each pipe type's areas of responsibility + * for outputting timings on the screen is shown below: + * + * Timing Active for Stream 0 + * __________________________________________________ + * |OTG master 0 (OPP head 0)|OPP head 2 (DPP pipe 2) | + * | (DPP pipe 0)| | + * | Top Plane 0 | | + * | ______________|____ | + * | |DPP pipe 1 |DPP | | + * | | |pipe| | + * | | Bottom |3 | | + * | | Plane 1 | | | + * | | | | | + * | |______________|____| | + * | | | + * | | | + * | ODM slice 0 | ODM slice 1 | + * |_________________________|________________________| + * + * Timing Active for Stream 1 + * __________________________________________________ + * |OTG master 4 (OPP head 4) | + * | | + * | | + * | | + * | | + * | | + * | Blank Pixel Data | + * | (generated by DPG4) | + * | | + * | | + * | | + * | | + * | | + * |__________________________________________________| + * + * Inter-pipe Relation + * __________________________________________________ + * |PIPE IDX| DPP PIPES | OPP HEADS | OTG MASTER | + * | | plane 0 | slice 0 | | + * | 0 | -------------MPC---------ODM----------- | + * | | plane 1 | | | | | + * | 1 | ------------- | | | | + * | | plane 0 | slice 1 | | | + * | 2 | -------------MPC--------- | | + * | | plane 1 | | | | + * | 3 | ------------- | | | + * | | | blank | | + * | 4 | | ----------------------- | + * | | | | | + * | 5 | (FREE) | | | + * |________|_______________|___________|_____________| + */ +enum pipe_type { + /* free pipe - free pipe is an uninitialized pipe without a stream + * associated with it. It is a free DCN pipe resource. It can be + * acquired as any type of pipe. + */ + FREE_PIPE, + + /* OTG master pipe - the master pipe of its OPP head pipes with a + * functional OTG. It merges all its OPP head pipes pixel data in ODM + * block and output to backend DIG. OTG master pipe is responsible for + * generating entire crtc timing to backend DIG. An OTG master pipe may + * or may not have a plane. If it has a plane it blends it as the left + * most MPC slice of the top most layer. If it doesn't have a plane it + * can output pixel data from its OPP head pipes' test pattern + * generators (DPG) such as solid black pixel data to blank the screen. + */ + OTG_MASTER, + + /* OPP head pipe - the head pipe of an MPC blending tree with a + * functional OPP outputting to an OTG. OPP head pipe is responsible for + * processing output pixels in its own ODM slice. It may or may not have + * a plane. If it has a plane it blends it as the top most layer within + * its own ODM slice. If it doesn't have a plane it can output pixel + * data from its DPG such as solid black pixel data to blank the pixel + * data in its own ODM slice. OTG master pipe is also an OPP head pipe + * but with more responsibility. + */ + OPP_HEAD, + + /* DPP pipe - the pipe with a functional DPP outputting to an OPP head + * pipe's MPC. DPP pipe is responsible for processing pixel data from + * its own MPC slice of a plane. It must be connected to an OPP head + * pipe and it must have a plane associated with it. + */ + DPP_PIPE, +}; + +/* + * Determine if the input pipe ctx is of a pipe type. + * return - true if pipe ctx is of the input type. + */ +bool resource_is_pipe_type(const struct pipe_ctx *pipe_ctx, enum pipe_type type); + +/* + * Determine if the input pipe ctx is used for rendering a plane with MPCC + * combine. MPCC combine is a hardware feature to combine multiple DPP pipes + * into a single plane. It is typically used for bypassing pipe bandwidth + * limitation for rendering a very large plane or saving power by reducing UCLK + * and DPPCLK speeds. + * + * For instance in the Inter-pipe Relation diagram shown below, both PIPE 0 and + * 1 are for MPCC combine for plane 0 + * + * Inter-pipe Relation + * __________________________________________________ + * |PIPE IDX| DPP PIPES | OPP HEADS | OTG MASTER | + * | | plane 0 | | | + * | 0 | -------------MPC----------------------- | + * | | plane 0 | | | | + * | 1 | ------------- | | | + * |________|_______________|___________|_____________| + * + * return - true if pipe ctx is used for mpcc combine. + */ +bool resource_is_for_mpcc_combine(const struct pipe_ctx *pipe_ctx); + +/* + * Look for a free pipe in new resource context that is used as a secondary DPP + * pipe in MPC blending tree associated with input OPP head pipe. + * + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ int resource_find_free_pipe_used_in_cur_mpc_blending_tree( const struct resource_context *cur_res_ctx, struct resource_context *new_res_ctx, const struct pipe_ctx *cur_opp_head); +/* + * Look for a free pipe in new resource context that is not used in current + * resource context. + * + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ int recource_find_free_pipe_not_used_in_cur_res_ctx( const struct resource_context *cur_res_ctx, struct resource_context *new_res_ctx, const struct resource_pool *pool); +/* + * Look for a free pipe in new resource context that is used as a secondary DPP + * pipe in any MPCC combine in current resource context. + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ int resource_find_free_pipe_used_as_cur_sec_dpp_in_mpcc_combine( const struct resource_context *cur_res_ctx, struct resource_context *new_res_ctx, const struct resource_pool *pool); +/* + * Look for any free pipe in new resource context. + * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise + * pipe idx of the free pipe + */ int resource_find_any_free_pipe(struct resource_context *new_res_ctx, const struct resource_pool *pool); +/* + * Legacy find free secondary pipe logic deprecated for newer DCNs as it doesn't + * find the most optimal free pipe to prevent from time consuming hardware state + * transitions. + */ +struct pipe_ctx *resource_find_free_secondary_pipe_legacy( + struct resource_context *res_ctx, + const struct resource_pool *pool, + const struct pipe_ctx *primary_pipe); + +/* + * Get number of MPC "cuts" of the plane associated with the pipe. MPC slice + * count is equal to MPC splits + 1. For example if a plane is cut 3 times, it + * will have 4 pieces of slice. + * return - 0 if pipe is not used for a plane with MPCC combine. otherwise + * the number of MPC "cuts" for the plane. + */ +int resource_get_num_mpc_splits(const struct pipe_ctx *pipe); + +/* + * Get number of ODM "cuts" of the timing associated with the pipe. ODM slice + * count is equal to ODM splits + 1. For example if a timing is cut 3 times, it + * will have 4 pieces of slice. + * return - 0 if pipe is not used for ODM combine. otherwise + * the number of ODM "cuts" for the timing. + */ +int resource_get_num_odm_splits(const struct pipe_ctx *pipe); + +/* + * Get the OTG master pipe in resource context associated with the stream. + * return - NULL if not found. Otherwise the OTG master pipe associated with the + * stream. + */ +struct pipe_ctx *resource_get_otg_master_for_stream( + struct resource_context *res_ctx, + struct dc_stream_state *stream); + +/* + * Get the OTG master pipe for the input pipe context. + * return - the OTG master pipe for the input pipe + * context. + */ +struct pipe_ctx *resource_get_otg_master(const struct pipe_ctx *pipe_ctx); + +/* + * Get the OPP head pipe for the input pipe context. + * return - the OPP head pipe for the input pipe + * context. + */ +struct pipe_ctx *resource_get_opp_head(const struct pipe_ctx *pipe_ctx); + + bool resource_validate_attach_surfaces( const struct dc_validation_set set[], int set_count, @@ -212,10 +410,6 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format); void get_audio_check(struct audio_info *aud_modes, struct audio_check *aud_chk); -int get_num_mpc_splits(struct pipe_ctx *pipe); - -int get_num_odm_splits(struct pipe_ctx *pipe); - bool get_temp_dp_link_res(struct dc_link *link, struct link_resource *link_res, struct dc_link_settings *link_settings); diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index c7e1f2229afd..fe4282771cd0 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -675,7 +675,8 @@ bool dp_set_test_pattern( if (pipes[i].stream == NULL) continue; - if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) { + if (resource_is_pipe_type(&pipes[i], OTG_MASTER) && + pipes[i].stream->link == link) { pipe_ctx = &pipes[i]; break; } diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 7997936613fc..79aef205598b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -182,11 +182,8 @@ void link_resume(struct dc_link *link) static bool is_master_pipe_for_link(const struct dc_link *link, const struct pipe_ctx *pipe) { - return (pipe->stream && - pipe->stream->link && - pipe->stream->link == link && - pipe->top_pipe == NULL && - pipe->prev_odm_pipe == NULL); + return resource_is_pipe_type(pipe, OTG_MASTER) && + pipe->stream->link == link; } /* -- cgit From f7d0157bfb26b8a88d424ac946c4ea31243317f8 Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Mon, 31 Jul 2023 20:01:11 -0400 Subject: drm/amd/display: avoid crash and add z8_marks related in dml [why] add dml1 used calculate_wm_and_dlg function pointer check to prevent crash. add z8 watermarks to struct for later asic use Reviewed-by: Alvin Lee Acked-by: Stylon Wang Signed-off-by: Charlene Liu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c | 4 ++-- drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 2 ++ 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index e6220ecf1d7d..88c0b24a3249 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -2063,7 +2063,8 @@ bool dcn30_validate_bandwidth(struct dc *dc, } DC_FP_START(); - dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); + if (dc->res_pool->funcs->calculate_wm_and_dlg) + dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); DC_FP_END(); BW_VAL_TRACE_END_WATERMARKS(); diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index cdaa33707f5c..82de4fe2637f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -1781,8 +1781,8 @@ bool dcn31_validate_bandwidth(struct dc *dc, BW_VAL_TRACE_SKIP(fast); goto validate_out; } - - dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); + if (dc->res_pool->funcs->calculate_wm_and_dlg) + dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); BW_VAL_TRACE_END_WATERMARKS(); diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c index 4e09ba4f2806..1c1fb2fa0822 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c @@ -1740,8 +1740,8 @@ bool dcn314_validate_bandwidth(struct dc *dc, BW_VAL_TRACE_SKIP(fast); goto validate_out; } - - dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); + if (dc->res_pool->funcs->calculate_wm_and_dlg) + dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); BW_VAL_TRACE_END_WATERMARKS(); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h index aaa293613846..f5677dbb4e7d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -49,6 +49,8 @@ struct dcn_hubbub_wm_set { uint32_t dram_clk_change; uint32_t usr_retrain; uint32_t fclk_pstate_change; + uint32_t sr_enter_exit_Z8; + uint32_t sr_enter_Z8; }; struct dcn_hubbub_wm { -- cgit From b73b737f3dd5fb75233645413a73e4eb7da7a41c Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Thu, 11 May 2023 10:56:51 -0400 Subject: drm/amd/display: Add some missing register definitions [Why&How] Add some missing register definitions and rearrange some others to maintain consistency with related definitions. Acked-by: Stylon Wang Signed-off-by: Aurabindo Pillai Reviewed-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | 69 +++++++++++++--------- .../amd/include/asic_reg/dcn/dcn_3_0_0_offset.h | 5 ++ .../amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h | 5 ++ .../amd/include/asic_reg/dcn/dcn_3_0_2_offset.h | 4 ++ .../amd/include/asic_reg/dcn/dcn_3_0_2_sh_mask.h | 5 +- 5 files changed, 58 insertions(+), 30 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index a3fee929cd12..86233f94db4a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -98,6 +98,29 @@ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) +#define HWSEQ_PIXEL_RATE_REG_LIST_302(blk) \ + SRII(PIXEL_RATE_CNTL, blk, 0), \ + SRII(PIXEL_RATE_CNTL, blk, 1),\ + SRII(PIXEL_RATE_CNTL, blk, 2),\ + SRII(PIXEL_RATE_CNTL, blk, 3), \ + SRII(PIXEL_RATE_CNTL, blk, 4) + +#define HWSEQ_PHYPLL_REG_LIST_302(blk) \ + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\ + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\ + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \ + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4) + +#define HWSEQ_PIXEL_RATE_REG_LIST_303(blk) \ + SRII(PIXEL_RATE_CNTL, blk, 0), \ + SRII(PIXEL_RATE_CNTL, blk, 1) + +#define HWSEQ_PHYPLL_REG_LIST_303(blk) \ + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ + SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1) + + #define HWSEQ_PHYPLL_REG_LIST_201(blk) \ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1) @@ -387,7 +410,11 @@ SR(MPC_CRC_RESULT_C), \ SR(MPC_CRC_RESULT_AR), \ SR(AZALIA_AUDIO_DTO), \ - SR(AZALIA_CONTROLLER_CLOCK_GATING) + SR(AZALIA_CONTROLLER_CLOCK_GATING), \ + SR(HPO_TOP_CLOCK_CONTROL), \ + SR(ODM_MEM_PWR_CTRL3), \ + SR(DMU_MEM_PWR_CNTL), \ + SR(MMHUBBUB_MEM_PWR_CNTL) #define HWSEQ_DCN301_REG_LIST()\ SR(REFCLK_CNTL), \ @@ -508,8 +535,11 @@ SR(D5VGA_CONTROL), \ SR(D6VGA_CONTROL), \ SR(DC_IP_REQUEST_CNTL), \ + HWSEQ_PIXEL_RATE_REG_LIST_302(OTG), \ + HWSEQ_PHYPLL_REG_LIST_302(OTG), \ SR(AZALIA_AUDIO_DTO), \ - SR(AZALIA_CONTROLLER_CLOCK_GATING) + SR(AZALIA_CONTROLLER_CLOCK_GATING), \ + SR(HPO_TOP_CLOCK_CONTROL) #define HWSEQ_DCN303_REG_LIST() \ HWSEQ_DCN_REG_LIST(), \ @@ -540,28 +570,6 @@ SR(AZALIA_CONTROLLER_CLOCK_GATING), \ SR(HPO_TOP_CLOCK_CONTROL) -#define HWSEQ_PIXEL_RATE_REG_LIST_302(blk) \ - SRII(PIXEL_RATE_CNTL, blk, 0), \ - SRII(PIXEL_RATE_CNTL, blk, 1),\ - SRII(PIXEL_RATE_CNTL, blk, 2),\ - SRII(PIXEL_RATE_CNTL, blk, 3), \ - SRII(PIXEL_RATE_CNTL, blk, 4) - -#define HWSEQ_PHYPLL_REG_LIST_302(blk) \ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1),\ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 2),\ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4) - -#define HWSEQ_PIXEL_RATE_REG_LIST_303(blk) \ - SRII(PIXEL_RATE_CNTL, blk, 0), \ - SRII(PIXEL_RATE_CNTL, blk, 1) - -#define HWSEQ_PHYPLL_REG_LIST_303(blk) \ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1) - struct dce_hwseq_registers { uint32_t DCFE_CLOCK_CONTROL[6]; uint32_t DCFEV_CLOCK_CONTROL; @@ -663,14 +671,15 @@ struct dce_hwseq_registers { uint32_t MC_VM_XGMI_LFB_CNTL; uint32_t AZALIA_AUDIO_DTO; uint32_t AZALIA_CONTROLLER_CLOCK_GATING; + /* MMHUB VM */ + uint32_t MC_VM_FB_LOCATION_BASE; + uint32_t MC_VM_FB_LOCATION_TOP; + uint32_t MC_VM_FB_OFFSET; + uint32_t MMHUBBUB_MEM_PWR_CNTL; uint32_t HPO_TOP_CLOCK_CONTROL; uint32_t ODM_MEM_PWR_CTRL3; uint32_t DMU_MEM_PWR_CNTL; - uint32_t MMHUBBUB_MEM_PWR_CNTL; uint32_t DCHUBBUB_ARB_HOSTVM_CNTL; - uint32_t MC_VM_FB_LOCATION_BASE; - uint32_t MC_VM_FB_LOCATION_TOP; - uint32_t MC_VM_FB_OFFSET; uint32_t HPO_TOP_HW_CONTROL; }; /* set field name */ @@ -915,6 +924,7 @@ struct dce_hwseq_registers { #define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\ HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \ HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \ + HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh), \ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \ HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \ @@ -1012,7 +1022,8 @@ struct dce_hwseq_registers { HWS_SF(, DOMAIN19_PG_STATUS, DOMAIN19_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DOMAIN20_PG_STATUS, DOMAIN20_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ - HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) + HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \ + HWS_SF(, HPO_TOP_CLOCK_CONTROL, HPO_HDMISTREAMCLK_GATE_DIS, mask_sh) #define HWSEQ_DCN303_MASK_SH_LIST(mask_sh) \ HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h index 537aee0536d3..f2f8f9b39c6b 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h @@ -15805,6 +15805,11 @@ #define mmDME6_DME_MEMORY_CONTROL 0x093d #define mmDME6_DME_MEMORY_CONTROL_BASE_IDX 3 +// addressBlock: dce_dc_hpo_hpo_top_dispdec +// base address: 0x0 +#define mmHPO_TOP_CLOCK_CONTROL 0x0e43 +#define mmHPO_TOP_CLOCK_CONTROL_BASE_IDX 3 + // base address: 0x1a698 #define mmDC_PERFMON29_PERFCOUNTER_CNTL 0x0e66 #define mmDC_PERFMON29_PERFCOUNTER_CNTL_BASE_IDX 3 diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h index f9d90b098519..e0a447351623 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h @@ -60666,7 +60666,12 @@ #define DME6_DME_MEMORY_CONTROL__DME_MEM_PWR_STATE_MASK 0x00000300L #define DME6_DME_MEMORY_CONTROL__DME_MEM_DEFAULT_MEM_LOW_POWER_STATE_MASK 0x00003000L +// addressBlock: dce_dc_hpo_hpo_top_dispdec +//HPO_TOP_CLOCK_CONTROL +#define HPO_TOP_CLOCK_CONTROL__HPO_HDMISTREAMCLK_GATE_DIS__SHIFT 0x9 +#define HPO_TOP_CLOCK_CONTROL__HPO_HDMISTREAMCLK_GATE_DIS_MASK 0x00000200L +// addressBlock: dce_dc_hpo_hpo_dcperfmon_dc_perfmon_dispdec //DC_PERFMON29_PERFCOUNTER_CNTL #define DC_PERFMON29_PERFCOUNTER_CNTL__PERFCOUNTER_EVENT_SEL__SHIFT 0x0 #define DC_PERFMON29_PERFCOUNTER_CNTL__PERFCOUNTER_CVALUE_SEL__SHIFT 0x9 diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_offset.h index 476469d41d73..b45a35aae241 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_offset.h @@ -14205,6 +14205,10 @@ +// addressBlock: dce_dc_hpo_hpo_top_dispdec +// base address: 0x0 +#define mmHPO_TOP_CLOCK_CONTROL 0x0e43 +#define mmHPO_TOP_CLOCK_CONTROL_BASE_IDX 3 // base address: 0x1a698 #define mmDC_PERFMON26_PERFCOUNTER_CNTL 0x0e66 diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_sh_mask.h index b9de0ebc8b03..3dae29f9581e 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_2_sh_mask.h @@ -52401,7 +52401,10 @@ #define DC_PERFMON25_PERFMON_LOW__PERFMON_LOW__SHIFT 0x0 #define DC_PERFMON25_PERFMON_LOW__PERFMON_LOW_MASK 0xFFFFFFFFL - +// addressBlock: dce_dc_hpo_hpo_top_dispdec +//HPO_TOP_CLOCK_CONTROL +#define HPO_TOP_CLOCK_CONTROL__HPO_HDMISTREAMCLK_GATE_DIS__SHIFT 0x9 +#define HPO_TOP_CLOCK_CONTROL__HPO_HDMISTREAMCLK_GATE_DIS_MASK 0x00000200L // addressBlock: dce_dc_hpo_hpo_dcperfmon_dc_perfmon_dispdec //DC_PERFMON26_PERFCOUNTER_CNTL -- cgit From 44fd83e920e2ec0322ad82320ca575445b5e135e Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Sat, 12 Aug 2023 20:17:24 +0530 Subject: drm/amdgpu: Replace ternary operator with min() in 'amdgpu_iomem_read' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following coccicheck: drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c:2427:16-17: WARNING opportunity for min() min() macro is defined in include/linux/minmax.h. It avoids multiple evaluations of the arguments when non-constant and performs strict type-checking. Cc: Guchun Chen Cc: Christian König Cc: Alex Deucher Cc: "Pan, Xinhui" Signed-off-by: Srinivasan Shanmugam Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index dea848bb55c1..d9adc520f656 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -2420,7 +2420,7 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, struct page *p; void *ptr; - bytes = bytes < size ? bytes : size; + bytes = min(bytes, size); /* Translate the bus address to a physical address. If * the domain is NULL it means there is no IOMMU active -- cgit From d117fd296456b0b754fe6819a68ba883c4f46d1c Mon Sep 17 00:00:00 2001 From: Samir Dhume Date: Mon, 17 Jul 2023 11:13:36 -0400 Subject: drm/amdgpu/vcn: sriov support for vcn_v4_0_3 initialization table handshake with mmsch Signed-off-by: Samir Dhume Acked-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 260 +++++++++++++++++++++++++++++--- 1 file changed, 236 insertions(+), 24 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c index 71eb6b55deef..503cd26d3fdd 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c @@ -31,6 +31,7 @@ #include "soc15d.h" #include "soc15_hw_ip.h" #include "vcn_v2_0.h" +#include "mmsch_v4_0_3.h" #include "vcn/vcn_4_0_3_offset.h" #include "vcn/vcn_4_0_3_sh_mask.h" @@ -44,6 +45,7 @@ #define VCN_VID_SOC_ADDRESS_2_0 0x1fb00 #define VCN1_VID_SOC_ADDRESS_3_0 0x48300 +static int vcn_v4_0_3_start_sriov(struct amdgpu_device *adev); static void vcn_v4_0_3_set_unified_ring_funcs(struct amdgpu_device *adev); static void vcn_v4_0_3_set_irq_funcs(struct amdgpu_device *adev); static int vcn_v4_0_3_set_powergating_state(void *handle, @@ -137,6 +139,12 @@ static int vcn_v4_0_3_sw_init(void *handle) amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); } + if (amdgpu_sriov_vf(adev)) { + r = amdgpu_virt_alloc_mm_table(adev); + if (r) + return r; + } + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) adev->vcn.pause_dpg_mode = vcn_v4_0_3_pause_dpg_mode; @@ -174,6 +182,9 @@ static int vcn_v4_0_3_sw_fini(void *handle) drm_dev_exit(idx); } + if (amdgpu_sriov_vf(adev)) + amdgpu_virt_free_mm_table(adev); + r = amdgpu_vcn_suspend(adev); if (r) return r; @@ -196,33 +207,47 @@ static int vcn_v4_0_3_hw_init(void *handle) struct amdgpu_ring *ring; int i, r, vcn_inst; - for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { - vcn_inst = GET_INST(VCN, i); - ring = &adev->vcn.inst[i].ring_enc[0]; + if (amdgpu_sriov_vf(adev)) { + r = vcn_v4_0_3_start_sriov(adev); + if (r) + goto done; - if (ring->use_doorbell) { - adev->nbio.funcs->vcn_doorbell_range( - adev, ring->use_doorbell, - (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + - 9 * vcn_inst, - adev->vcn.inst[i].aid_id); - - WREG32_SOC15( - VCN, GET_INST(VCN, ring->me), - regVCN_RB1_DB_CTRL, - ring->doorbell_index - << VCN_RB1_DB_CTRL__OFFSET__SHIFT | - VCN_RB1_DB_CTRL__EN_MASK); - - /* Read DB_CTRL to flush the write DB_CTRL command. */ - RREG32_SOC15( - VCN, GET_INST(VCN, ring->me), - regVCN_RB1_DB_CTRL); + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + ring = &adev->vcn.inst[i].ring_enc[0]; + ring->wptr = 0; + ring->wptr_old = 0; + vcn_v4_0_3_unified_ring_set_wptr(ring); + ring->sched.ready = true; } + } else { + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + vcn_inst = GET_INST(VCN, i); + ring = &adev->vcn.inst[i].ring_enc[0]; + + if (ring->use_doorbell) { + adev->nbio.funcs->vcn_doorbell_range( + adev, ring->use_doorbell, + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 9 * vcn_inst, + adev->vcn.inst[i].aid_id); + + WREG32_SOC15( + VCN, GET_INST(VCN, ring->me), + regVCN_RB1_DB_CTRL, + ring->doorbell_index + << VCN_RB1_DB_CTRL__OFFSET__SHIFT | + VCN_RB1_DB_CTRL__EN_MASK); + + /* Read DB_CTRL to flush the write DB_CTRL command. */ + RREG32_SOC15( + VCN, GET_INST(VCN, ring->me), + regVCN_RB1_DB_CTRL); + } - r = amdgpu_ring_test_helper(ring); - if (r) - goto done; + r = amdgpu_ring_test_helper(ring); + if (r) + goto done; + } } done: @@ -820,6 +845,193 @@ static int vcn_v4_0_3_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, b return 0; } +static int vcn_v4_0_3_start_sriov(struct amdgpu_device *adev) +{ + int i, vcn_inst; + struct amdgpu_ring *ring_enc; + uint64_t cache_addr; + uint64_t rb_enc_addr; + uint64_t ctx_addr; + uint32_t param, resp, expected; + uint32_t offset, cache_size; + uint32_t tmp, timeout; + + struct amdgpu_mm_table *table = &adev->virt.mm_table; + uint32_t *table_loc; + uint32_t table_size; + uint32_t size, size_dw; + uint32_t init_status; + uint32_t enabled_vcn; + + struct mmsch_v4_0_cmd_direct_write + direct_wt = { {0} }; + struct mmsch_v4_0_cmd_direct_read_modify_write + direct_rd_mod_wt = { {0} }; + struct mmsch_v4_0_cmd_end end = { {0} }; + struct mmsch_v4_0_3_init_header header; + + volatile struct amdgpu_vcn4_fw_shared *fw_shared; + volatile struct amdgpu_fw_shared_rb_setup *rb_setup; + + direct_wt.cmd_header.command_type = + MMSCH_COMMAND__DIRECT_REG_WRITE; + direct_rd_mod_wt.cmd_header.command_type = + MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; + end.cmd_header.command_type = MMSCH_COMMAND__END; + + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + vcn_inst = GET_INST(VCN, i); + + memset(&header, 0, sizeof(struct mmsch_v4_0_3_init_header)); + header.version = MMSCH_VERSION; + header.total_size = sizeof(struct mmsch_v4_0_3_init_header) >> 2; + + table_loc = (uint32_t *)table->cpu_addr; + table_loc += header.total_size; + + table_size = 0; + + MMSCH_V4_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, 0, regUVD_STATUS), + ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY); + + cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4); + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo); + + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi); + + offset = 0; + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET0), 0); + } else { + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), + lower_32_bits(adev->vcn.inst[i].gpu_addr)); + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), + upper_32_bits(adev->vcn.inst[i].gpu_addr)); + offset = cache_size; + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET0), + AMDGPU_UVD_FIRMWARE_OFFSET >> 3); + } + + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_SIZE0), + cache_size); + + cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset; + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), lower_32_bits(cache_addr)); + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET1), 0); + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE); + + cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset + + AMDGPU_VCN_STACK_SIZE; + + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), lower_32_bits(cache_addr)); + + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), upper_32_bits(cache_addr)); + + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_OFFSET2), 0); + + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE); + + fw_shared = adev->vcn.inst[vcn_inst].fw_shared.cpu_addr; + rb_setup = &fw_shared->rb_setup; + + ring_enc = &adev->vcn.inst[vcn_inst].ring_enc[0]; + ring_enc->wptr = 0; + rb_enc_addr = ring_enc->gpu_addr; + + rb_setup->is_rb_enabled_flags |= RB_ENABLED; + rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr); + rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr); + rb_setup->rb_size = ring_enc->ring_size / 4; + fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG); + + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), + lower_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), + upper_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr)); + MMSCH_V4_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0, + regUVD_VCPU_NONCACHE_SIZE0), + AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared))); + MMSCH_V4_0_INSERT_END(); + + header.vcn0.init_status = 0; + header.vcn0.table_offset = header.total_size; + header.vcn0.table_size = table_size; + header.total_size += table_size; + + /* Send init table to mmsch */ + size = sizeof(struct mmsch_v4_0_3_init_header); + table_loc = (uint32_t *)table->cpu_addr; + memcpy((void *)table_loc, &header, size); + + ctx_addr = table->gpu_addr; + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr)); + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr)); + + tmp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID); + tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; + tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID, tmp); + + size = header.total_size; + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_SIZE, size); + + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP, 0); + + param = 0x00000001; + WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_HOST, param); + tmp = 0; + timeout = 1000; + resp = 0; + expected = MMSCH_VF_MAILBOX_RESP__OK; + while (resp != expected) { + resp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP); + if (resp != 0) + break; + + udelay(10); + tmp = tmp + 10; + if (tmp >= timeout) { + DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\ + " waiting for regMMSCH_VF_MAILBOX_RESP "\ + "(expected=0x%08x, readback=0x%08x)\n", + tmp, expected, resp); + return -EBUSY; + } + } + + enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0; + init_status = ((struct mmsch_v4_0_3_init_header *)(table_loc))->vcn0.init_status; + if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE + && init_status != MMSCH_VF_ENGINE_STATUS__PASS) { + DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\ + "status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status); + } + } + + return 0; +} + /** * vcn_v4_0_3_start - VCN start * -- cgit From bb9f7b6826257390a847abb39c719dca0de41a18 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:31:55 -0500 Subject: drm/amd: Add a new hwmon attribute for instantaneous power Some GPUs provide support for current power, some average power, and some both. To be able to support all these combinations, introduce a new attribute. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index c0eda9bf0982..816f034cfe3f 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2803,6 +2803,19 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, return sysfs_emit(buf, "%u\n", val); } +static ssize_t amdgpu_hwmon_show_power_input(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + unsigned int val; + + val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_POWER); + if (val < 0) + return val; + + return sysfs_emit(buf, "%u\n", val); +} + static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev, struct device_attribute *attr, char *buf) @@ -3023,6 +3036,8 @@ static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev, * * - power1_average: average power used by the SoC in microWatts. On APUs this includes the CPU. * + * - power1_input: instantaneous power used by the SoC in microWatts. On APUs this includes the CPU. + * * - power1_cap_min: minimum cap supported in microWatts * * - power1_cap_max: maximum cap supported in microWatts @@ -3091,6 +3106,7 @@ static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, amdgpu_hwmon_show_vddgfx_label, NU static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0); static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, amdgpu_hwmon_show_vddnb_label, NULL, 0); static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 0); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, amdgpu_hwmon_show_power_input, NULL, 0); static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 0); static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 0); static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0); @@ -3137,6 +3153,7 @@ static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_label.dev_attr.attr, &sensor_dev_attr_power1_average.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, &sensor_dev_attr_power1_cap_max.dev_attr.attr, &sensor_dev_attr_power1_cap_min.dev_attr.attr, &sensor_dev_attr_power1_cap.dev_attr.attr, -- cgit From e94e787e37b99645e7c02d20d0a1ba0f8a18a82a Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Wed, 22 Mar 2023 14:29:26 -0400 Subject: drm/amd: Remove freesync video mode amdgpu parameter [Why&How] Freesync Video mode was enabled by default. Hence no need for the module parameter, so remove it completely Acked-by: Stylon Wang Signed-off-by: Aurabindo Pillai Reviewed-by: Stylon Wang Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 27 --------------------------- 2 files changed, 28 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 97cb56c791f3..dc2d53081e80 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -192,7 +192,6 @@ extern int amdgpu_emu_mode; extern uint amdgpu_smu_memory_pool_size; extern int amdgpu_smu_pptable_id; extern uint amdgpu_dc_feature_mask; -extern uint amdgpu_freesync_vid_mode; extern uint amdgpu_dc_debug_mask; extern uint amdgpu_dc_visual_confirm; extern uint amdgpu_dm_abm_level; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index d11fa7dec4c4..892ecb5289ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -187,7 +187,6 @@ int amdgpu_mes_kiq; int amdgpu_noretry = -1; int amdgpu_force_asic_type = -1; int amdgpu_tmz = -1; /* auto */ -uint amdgpu_freesync_vid_mode; int amdgpu_reset_method = -1; /* auto */ int amdgpu_num_kcq = -1; int amdgpu_smartshift_bias; @@ -871,32 +870,6 @@ module_param_named(backlight, amdgpu_backlight, bint, 0444); MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)"); module_param_named(tmz, amdgpu_tmz, int, 0444); -/** - * DOC: freesync_video (uint) - * Enable the optimization to adjust front porch timing to achieve seamless - * mode change experience when setting a freesync supported mode for which full - * modeset is not needed. - * - * The Display Core will add a set of modes derived from the base FreeSync - * video mode into the corresponding connector's mode list based on commonly - * used refresh rates and VRR range of the connected display, when users enable - * this feature. From the userspace perspective, they can see a seamless mode - * change experience when the change between different refresh rates under the - * same resolution. Additionally, userspace applications such as Video playback - * can read this modeset list and change the refresh rate based on the video - * frame rate. Finally, the userspace can also derive an appropriate mode for a - * particular refresh rate based on the FreeSync Mode and add it to the - * connector's mode list. - * - * Note: This is an experimental feature. - * - * The default value: 0 (off). - */ -MODULE_PARM_DESC( - freesync_video, - "Enable freesync modesetting optimization feature (0 = off (default), 1 = on)"); -module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444); - /** * DOC: reset_method (int) * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco) -- cgit From 47f1724db4fe0085b33cafd68bb8b7267678bb95 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:31:56 -0500 Subject: drm/amd: Introduce `AMDGPU_PP_SENSOR_GPU_INPUT_POWER` Some GPUs have been overloading average power values and input power values. To disambiguate these, introduce a new `AMDGPU_PP_SENSOR_GPU_INPUT_POWER` and the GPUs that share input power update to use this instead of average power. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2746 Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 1 + drivers/gpu/drm/amd/pm/amdgpu_pm.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 1 + drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c | 12 +++++++++++- drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 10 ++++++++++ drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 6 +++--- drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c | 9 +++++++++ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c | 6 +++--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 17 +++++------------ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 6 +++--- 20 files changed, 57 insertions(+), 27 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 90989405eddc..6582cdf2736f 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -133,6 +133,7 @@ enum amd_pp_sensors { AMDGPU_PP_SENSOR_VCE_POWER, AMDGPU_PP_SENSOR_UVD_POWER, AMDGPU_PP_SENSOR_GPU_POWER, + AMDGPU_PP_SENSOR_GPU_INPUT_POWER, AMDGPU_PP_SENSOR_SS_APU_SHARE, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK, diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 816f034cfe3f..bb4285159229 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2809,7 +2809,7 @@ static ssize_t amdgpu_hwmon_show_power_input(struct device *dev, { unsigned int val; - val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_POWER); + val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER); if (val < 0) return val; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index c91b2a3966cd..5a2371484a58 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -4039,7 +4039,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; return 0; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: return smu7_get_gpu_power(hwmgr, (uint32_t *)value); case AMDGPU_PP_SENSOR_VDDGFX: if ((data->vr_config & VRCONF_VDDGFX_MASK) == diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 52ae6fa2d2a6..6d6bc6a380b3 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -3966,7 +3966,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = vega10_get_gpu_power(hwmgr, (uint32_t *)value); break; case AMDGPU_PP_SENSOR_VDDGFX: diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c index 4bd573d815ff..460067933de2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c @@ -1529,7 +1529,7 @@ static int vega12_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = vega12_get_gpu_power(hwmgr, (uint32_t *)value); if (!ret) *size = 4; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index 492ca33637d6..b6dd7f8daf72 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -2253,7 +2253,7 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: *size = 16; ret = vega20_get_gpu_power(hwmgr, (uint32_t *)value); break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 6e2069dcb6b9..6b5e220affdf 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -1398,6 +1398,7 @@ typedef enum { METRICS_PCIE_RATE, METRICS_PCIE_WIDTH, METRICS_CURR_FANPWM, + METRICS_CURR_SOCKETPOWER, } MetricsMember_t; enum smu_cmn2asic_mapping_type { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index c49f770c97b3..e5f629a23db6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1169,6 +1169,7 @@ static int arcturus_read_sensor(struct smu_context *smu, ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c index ca4d97b7f576..4840e4d69b10 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c @@ -154,10 +154,14 @@ cyan_skillfish_get_smu_metrics_data(struct smu_context *smu, case METRICS_CURR_UCLK: *value = metrics->Current.MemclkFrequency; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->Current.CurrentSocketPower << 8) / 1000; break; + case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->Average.CurrentSocketPower << 8) / + 1000; + break; case METRICS_TEMPERATURE_EDGE: *value = metrics->Current.GfxTemperature / 100 * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; @@ -214,6 +218,12 @@ static int cyan_skillfish_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = cyan_skillfish_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_TEMPERATURE_HOTSPOT, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index e655071516b7..06474bbb7382 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -2240,6 +2240,7 @@ static int navi10_read_sensor(struct smu_context *smu, ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index f0800c0c5168..6dead62095bb 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -1962,6 +1962,7 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, ret = -EOPNOTSUPP; } break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 185d0b50ee8e..8a2c9c7abea6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -390,6 +390,10 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu, *value = metrics->Current.UvdActivity; break; case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->Average.CurrentSocketPower << 8) / + 1000; + break; + case METRICS_CURR_SOCKETPOWER: *value = (metrics->Current.CurrentSocketPower << 8) / 1000; break; @@ -1542,6 +1546,12 @@ static int vangogh_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = vangogh_common_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: ret = vangogh_common_get_smu_metrics_data(smu, METRICS_TEMPERATURE_EDGE, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index a7569354229d..7b5ccb935fc0 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1197,7 +1197,7 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->AverageUvdActivity / 100; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1)) && (adev->pm.fw_version >= 0x40000f)) || ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0)) && (adev->pm.fw_version >= 0x373200))) *value = metrics->CurrentSocketPower << 8; @@ -1297,9 +1297,9 @@ static int renoir_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = renoir_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 8f26123ac703..4e5043b6ce40 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1183,6 +1183,7 @@ static int aldebaran_read_sensor(struct smu_context *smu, ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 48b03524a52d..203dc50c0fd5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -997,6 +997,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c index ef37dda9908f..a4e87984645e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -321,6 +321,9 @@ static int smu_v13_0_4_get_smu_metrics_data(struct smu_context *smu, *value = metrics->UvdActivity; break; case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->AverageSocketPower << 8) / 1000; + break; + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -575,6 +578,12 @@ static int smu_v13_0_4_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = smu_v13_0_4_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: ret = smu_v13_0_4_get_smu_metrics_data(smu, METRICS_TEMPERATURE_EDGE, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c index 87a79e6f983b..5f8e70d4c467 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c @@ -288,7 +288,7 @@ static int smu_v13_0_5_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->UvdActivity; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -332,9 +332,9 @@ static int smu_v13_0_5_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = smu_v13_0_5_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 362acbb242bb..aedf1c41d4a4 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -714,7 +714,7 @@ static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_MEMACTIVITY: *value = SMUQ10_TO_UINT(metrics->DramBandwidthUtilization); break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = SMUQ10_TO_UINT(metrics->SocketPower) << 8; break; case METRICS_TEMPERATURE_HOTSPOT: @@ -1139,15 +1139,6 @@ static int smu_v13_0_6_get_current_activity_percent(struct smu_context *smu, return ret; } -static int smu_v13_0_6_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return smu_v13_0_6_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, - value); -} - static int smu_v13_0_6_thermal_get_temperature(struct smu_context *smu, enum amd_pp_sensors sensor, uint32_t *value) @@ -1193,8 +1184,10 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: - ret = smu_v13_0_6_get_gpu_power(smu, (uint32_t *)data); + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = smu_v13_0_6_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 690f89fcbbe3..880a83e53882 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -978,6 +978,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index a1be2029ba4a..14fe45d3b7b7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -365,7 +365,7 @@ static int yellow_carp_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->UvdActivity; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -423,9 +423,9 @@ static int yellow_carp_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = yellow_carp_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; -- cgit From 4d6fc55ab13c7af4fcdbc8373327504ad7f4c4ef Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 7 Jun 2023 12:56:18 -0400 Subject: drm/amdgpu: expand runpm parameter Allow the user to specify -2 as auto enabled with displays. By default we don't enter runtime suspend when there are displays attached because it does not work well in some desktop environments due to the driver sending hotplug events on resume in case any new displays were attached while the GPU was powered down. Some users still want this functionality though, so this lets you enable it. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2428 Reviewed-by: Guchun Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 37 ++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 892ecb5289ca..81edf66dbea8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -347,8 +347,9 @@ module_param_named(aspm, amdgpu_aspm, int, 0444); * Override for runtime power management control for dGPUs. The amdgpu driver can dynamically power down * the dGPUs when they are idle if supported. The default is -1 (auto enable). * Setting the value to 0 disables this functionality. + * Setting the value to -2 is auto enabled with power down when displays are attached. */ -MODULE_PARM_DESC(runpm, "PX runtime pm (2 = force enable with BAMACO, 1 = force enable with BACO, 0 = disable, -1 = auto)"); +MODULE_PARM_DESC(runpm, "PX runtime pm (2 = force enable with BAMACO, 1 = force enable with BACO, 0 = disable, -1 = auto, -2 = autowith displays)"); module_param_named(runpm, amdgpu_runtime_pm, int, 0444); /** @@ -2496,24 +2497,26 @@ static int amdgpu_runtime_idle_check_display(struct device *dev) struct drm_connector_list_iter iter; int ret = 0; - /* XXX: Return busy if any displays are connected to avoid - * possible display wakeups after runtime resume due to - * hotplug events in case any displays were connected while - * the GPU was in suspend. Remove this once that is fixed. - */ - mutex_lock(&drm_dev->mode_config.mutex); - drm_connector_list_iter_begin(drm_dev, &iter); - drm_for_each_connector_iter(list_connector, &iter) { - if (list_connector->status == connector_status_connected) { - ret = -EBUSY; - break; + if (amdgpu_runtime_pm != -2) { + /* XXX: Return busy if any displays are connected to avoid + * possible display wakeups after runtime resume due to + * hotplug events in case any displays were connected while + * the GPU was in suspend. Remove this once that is fixed. + */ + mutex_lock(&drm_dev->mode_config.mutex); + drm_connector_list_iter_begin(drm_dev, &iter); + drm_for_each_connector_iter(list_connector, &iter) { + if (list_connector->status == connector_status_connected) { + ret = -EBUSY; + break; + } } - } - drm_connector_list_iter_end(&iter); - mutex_unlock(&drm_dev->mode_config.mutex); + drm_connector_list_iter_end(&iter); + mutex_unlock(&drm_dev->mode_config.mutex); - if (ret) - return ret; + if (ret) + return ret; + } if (adev->dc_enabled) { struct drm_crtc *crtc; -- cgit From 236dcf75865b21581e2ce6c7329938525e71c894 Mon Sep 17 00:00:00 2001 From: Ran Sun Date: Mon, 31 Jul 2023 09:21:08 +0000 Subject: drm/amd/pm: Clean up errors in smu_v11_0_pptable.h Fix the following errors reported by checkpatch: ERROR: trailing whitespace ERROR: open brace '{' following struct go on the same line ERROR: code indent should use tabs where possible Signed-off-by: Ran Sun Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h index 0116e3d04fad..df7430876e0c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h @@ -101,8 +101,7 @@ enum SMU_11_0_ODSETTING_ID { }; #define SMU_11_0_MAX_ODSETTING 32 //Maximum Number of ODSettings -struct smu_11_0_overdrive_table -{ +struct smu_11_0_overdrive_table { uint8_t revision; //Revision = SMU_11_0_PP_OVERDRIVE_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t feature_count; //Total number of supported features @@ -127,8 +126,7 @@ enum SMU_11_0_PPCLOCK_ID { }; #define SMU_11_0_MAX_PPCLOCK 16 //Maximum Number of PP Clocks -struct smu_11_0_power_saving_clock_table -{ +struct smu_11_0_power_saving_clock_table { uint8_t revision; //Revision = SMU_11_0_PP_POWERSAVINGCLOCK_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t count; //power_saving_clock_count = SMU_11_0_PPCLOCK_COUNT @@ -136,8 +134,7 @@ struct smu_11_0_power_saving_clock_table uint32_t min[SMU_11_0_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Minimum array In MHz }; -struct smu_11_0_powerplay_table -{ +struct smu_11_0_powerplay_table { struct atom_common_table_header header; uint8_t table_revision; uint16_t table_size; //Driver portion table size. The offset to smc_pptable including header size @@ -145,14 +142,14 @@ struct smu_11_0_powerplay_table uint32_t golden_revision; uint16_t format_id; uint32_t platform_caps; //POWERPLAYABLE::ulPlatformCaps - + uint8_t thermal_controller_type; //one of SMU_11_0_PP_THERMALCONTROLLER uint16_t small_power_limit1; uint16_t small_power_limit2; uint16_t boost_power_limit; - uint16_t od_turbo_power_limit; //Power limit setting for Turbo mode in Performance UI Tuning. - uint16_t od_power_save_power_limit; //Power limit setting for PowerSave/Optimal mode in Performance UI Tuning. + uint16_t od_turbo_power_limit; //Power limit setting for Turbo mode in Performance UI Tuning. + uint16_t od_power_save_power_limit; //Power limit setting for PowerSave/Optimal mode in Performance UI Tuning. uint16_t software_shutdown_temp; uint16_t reserve[6]; //Zero filled field reserved for future use -- cgit From 39619d50a8e464215b6da6902afe00d3da1ee0ec Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Thu, 11 May 2023 10:59:39 -0400 Subject: drm/amd/display: enable low power mode for VGA memory [Why] When unused, all memory blocks should be put in a low power state [How] Check the value of enable_mem_low_power.bits.vga and set corresponding bit in the hardware register Acked-by: Stylon Wang Signed-off-by: Aurabindo Pillai Reviewed-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu') 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 4cd4ae07d73d..6cef62d7a2e5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -461,6 +461,11 @@ void dcn30_init_hw(struct dc *dc) REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1); } + if (dc->debug.enable_mem_low_power.bits.vga) { + // Power down VGA memory + REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1); + } + if (dc->ctx->dc_bios->fw_info_valid) { res_pool->ref_clocks.xtalin_clock_inKhz = dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency; -- cgit From 712c6812dcbf69df9752076705ccc762313083e7 Mon Sep 17 00:00:00 2001 From: Ran Sun Date: Mon, 31 Jul 2023 09:30:09 +0000 Subject: drm/amd/pm: Clean up errors in amdgpu_smu.h Fix the following errors reported by checkpatch: ERROR: open brace '{' following enum go on the same line ERROR: open brace '{' following struct go on the same line Signed-off-by: Ran Sun Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 36 +++++++++------------------ 1 file changed, 12 insertions(+), 24 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 6b5e220affdf..95eb8a5eb54f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -200,29 +200,25 @@ struct smu_power_state { struct smu_hw_power_state hardware; }; -enum smu_power_src_type -{ +enum smu_power_src_type { SMU_POWER_SOURCE_AC, SMU_POWER_SOURCE_DC, SMU_POWER_SOURCE_COUNT, }; -enum smu_ppt_limit_type -{ +enum smu_ppt_limit_type { SMU_DEFAULT_PPT_LIMIT = 0, SMU_FAST_PPT_LIMIT, }; -enum smu_ppt_limit_level -{ +enum smu_ppt_limit_level { SMU_PPT_LIMIT_MIN = -1, SMU_PPT_LIMIT_CURRENT, SMU_PPT_LIMIT_DEFAULT, SMU_PPT_LIMIT_MAX, }; -enum smu_memory_pool_size -{ +enum smu_memory_pool_size { SMU_MEMORY_POOL_SIZE_ZERO = 0, SMU_MEMORY_POOL_SIZE_256_MB = 0x10000000, SMU_MEMORY_POOL_SIZE_512_MB = 0x20000000, @@ -282,8 +278,7 @@ struct smu_clock_info { uint32_t max_bus_bandwidth; }; -struct smu_bios_boot_up_values -{ +struct smu_bios_boot_up_values { uint32_t revision; uint32_t gfxclk; uint32_t uclk; @@ -305,8 +300,7 @@ struct smu_bios_boot_up_values uint32_t firmware_caps; }; -enum smu_table_id -{ +enum smu_table_id { SMU_TABLE_PPTABLE = 0, SMU_TABLE_WATERMARKS, SMU_TABLE_CUSTOM_DPM, @@ -326,8 +320,7 @@ enum smu_table_id SMU_TABLE_COUNT, }; -struct smu_table_context -{ +struct smu_table_context { void *power_play_table; uint32_t power_play_table_size; void *hardcode_pptable; @@ -390,8 +383,7 @@ struct smu_power_context { }; #define SMU_FEATURE_MAX (64) -struct smu_feature -{ +struct smu_feature { uint32_t feature_num; DECLARE_BITMAP(supported, SMU_FEATURE_MAX); DECLARE_BITMAP(allowed, SMU_FEATURE_MAX); @@ -416,21 +408,18 @@ struct mclock_latency_table { struct mclk_latency_entries entries[MAX_REGULAR_DPM_NUM]; }; -enum smu_reset_mode -{ +enum smu_reset_mode { SMU_RESET_MODE_0, SMU_RESET_MODE_1, SMU_RESET_MODE_2, }; -enum smu_baco_state -{ +enum smu_baco_state { SMU_BACO_STATE_ENTER = 0, SMU_BACO_STATE_EXIT, }; -struct smu_baco_context -{ +struct smu_baco_context { uint32_t state; bool platform_support; bool maco_support; @@ -478,8 +467,7 @@ struct stb_context { #define WORKLOAD_POLICY_MAX 7 -struct smu_context -{ +struct smu_context { struct amdgpu_device *adev; struct amdgpu_irq_src irq_source; -- cgit From e8b2ad875ffa1c213d047e02c9c1b7db5f149241 Mon Sep 17 00:00:00 2001 From: GUO Zihua Date: Thu, 10 Aug 2023 19:56:12 +0800 Subject: drm/amdgpu: Remove duplicated includes Remove duplicated includes in amdgpu_amdkfd_gpuvm.c and amdgpu_ttm.c. Resolves checkincludes message. Signed-off-by: GUO Zihua Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index a136fba9f29b..7d6daf8d2bfa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -39,7 +39,6 @@ #include "amdgpu_xgmi.h" #include "kfd_priv.h" #include "kfd_smi_events.h" -#include /* Userptr restore delay, just long enough to allow consecutive VM * changes to accumulate diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index d9adc520f656..f27bd4a3467a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -49,7 +49,6 @@ #include #include -#include #include "amdgpu.h" #include "amdgpu_object.h" -- cgit From 3cecafc1970f139ea50f7e6adb45525b069e0636 Mon Sep 17 00:00:00 2001 From: Zheng Zengkai Date: Fri, 11 Aug 2023 18:25:49 +0800 Subject: drm/radeon: Use pci_dev_id() to simplify the code PCI core API pci_dev_id() can be used to get the BDF number for a pci device. We don't need to compose it mannually. Use pci_dev_id() to simplify the code a little bit. Signed-off-by: Zheng Zengkai Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 5771d1fcb073..603a78e41ba5 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c @@ -618,7 +618,7 @@ int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, atcs_input.size = sizeof(struct atcs_pref_req_input); /* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */ - atcs_input.client_id = rdev->pdev->devfn | (rdev->pdev->bus->number << 8); + atcs_input.client_id = pci_dev_id(rdev->pdev); atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK; atcs_input.flags = ATCS_WAIT_FOR_COMPLETION; if (advertise) -- cgit From 629425673b7764637d6052cff591e88215483e91 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:31:57 -0500 Subject: drm/amd: Fix SMU 13.0.4/13.0.11 GPU metrics average power The average power for the GPU metrics sysfs file contains the input power not the average power. The member that is set is called average power though, so correct it to the right value. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c index a4e87984645e..0951659299c1 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -257,7 +257,7 @@ static ssize_t smu_v13_0_4_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_gfx_activity = metrics.GfxActivity; gpu_metrics->average_mm_activity = metrics.UvdActivity; - gpu_metrics->average_socket_power = metrics.CurrentSocketPower; + gpu_metrics->average_socket_power = metrics.AverageSocketPower; gpu_metrics->average_gfx_power = metrics.Power[0]; gpu_metrics->average_soc_power = metrics.Power[1]; memcpy(&gpu_metrics->average_core_power[0], -- cgit From 05228211e89a882a005d30190cd10fb7282b4b25 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:31:58 -0500 Subject: drm/amd: Drop unnecessary helper for aldebaran aldebaran_get_gpu_power() is only called by one place and just calls aldebaran_get_smu_metrics_data(), so drop the helper. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 4e5043b6ce40..0dbb1a1c25d2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1094,16 +1094,6 @@ static int aldebaran_get_current_activity_percent(struct smu_context *smu, return ret; } -static int aldebaran_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return aldebaran_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, - value); -} - static int aldebaran_thermal_get_temperature(struct smu_context *smu, enum amd_pp_sensors sensor, uint32_t *value) @@ -1157,8 +1147,9 @@ static int aldebaran_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: - ret = aldebaran_get_gpu_power(smu, (uint32_t *)data); + ret = aldebaran_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: -- cgit From 4c64f2e420508aa6fdd5ae95ebf0451f3d97a013 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:31:59 -0500 Subject: drm/amd: Fix the return for average power on aldebaran Aldebaran can only return average socket power for the first die. The other dies return 0. Instead of returning a bad value, return -EOPNOTSUPP so that the attribute will be hidden. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 0dbb1a1c25d2..1341363ab01a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -625,9 +625,10 @@ static int aldebaran_get_smu_metrics_data(struct smu_context *smu, break; case METRICS_AVERAGE_SOCKETPOWER: /* Valid power data is available only from primary die */ - *value = aldebaran_is_primary(smu) ? - metrics->AverageSocketPower << 8 : - 0; + if (aldebaran_is_primary(smu)) + *value = metrics->AverageSocketPower << 8; + else + ret = -EOPNOTSUPP; break; case METRICS_TEMPERATURE_EDGE: *value = metrics->TemperatureEdge * -- cgit From 765bbbec16a159351f9dbfe415bc3c6c62a48ab9 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:32:00 -0500 Subject: drm/amd: Show both power attributes for vega20 Vega20 can offer average power in some versions of the PMFW and current power in others. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index b6dd7f8daf72..ad40395be602 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -2129,7 +2129,7 @@ static int vega20_get_metrics_table(struct pp_hwmgr *hwmgr, return ret; } -static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, +static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, int idx, uint32_t *query) { int ret = 0; @@ -2140,10 +2140,17 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, return ret; /* For the 40.46 release, they changed the value name */ - if (hwmgr->smu_version == 0x282e00) - *query = metrics_table.AverageSocketPower << 8; - else + switch (idx) { + case AMDGPU_PP_SENSOR_GPU_POWER: + if (hwmgr->smu_version == 0x282e00) + *query = metrics_table.AverageSocketPower << 8; + else + ret = -EOPNOTSUPP; + break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: *query = metrics_table.CurrSocketPower << 8; + break; + } return ret; } @@ -2253,9 +2260,10 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_POWER: case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: *size = 16; - ret = vega20_get_gpu_power(hwmgr, (uint32_t *)value); + ret = vega20_get_gpu_power(hwmgr, idx, (uint32_t *)value); break; case AMDGPU_PP_SENSOR_VDDGFX: val_vid = (RREG32_SOC15(SMUIO, 0, mmSMUSVI0_TEL_PLANE0) & -- cgit From 9366c2e87d08b88332a363adc537962ba3840fd9 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:32:01 -0500 Subject: drm/amd: Rename AMDGPU_PP_SENSOR_GPU_POWER Use the clearer name `AMDGPU_PP_SENSOR_GPU_AVG_POWER` instead. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- drivers/gpu/drm/amd/include/kgd_pp_interface.h | 2 +- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 4 ++-- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 4 ++-- drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 1 + 17 files changed, 19 insertions(+), 14 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 631c5ab3f7dc..99f4df133ed3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1019,7 +1019,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) case AMDGPU_INFO_SENSOR_GPU_AVG_POWER: /* get average GPU power */ if (amdgpu_dpm_read_sensor(adev, - AMDGPU_PP_SENSOR_GPU_POWER, + AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&ui32, &ui32_size)) { return -EINVAL; } diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 6582cdf2736f..84c5224d994c 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -132,7 +132,7 @@ enum amd_pp_sensors { AMDGPU_PP_SENSOR_MEM_TEMP, AMDGPU_PP_SENSOR_VCE_POWER, AMDGPU_PP_SENSOR_UVD_POWER, - AMDGPU_PP_SENSOR_GPU_POWER, + AMDGPU_PP_SENSOR_GPU_AVG_POWER, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, AMDGPU_PP_SENSOR_SS_APU_SHARE, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index bb4285159229..8133d968f75b 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2796,7 +2796,7 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, { unsigned int val; - val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_POWER); + val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_AVG_POWER); if (val < 0) return val; @@ -3460,7 +3460,7 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size)) seq_printf(m, "\t%u mV (VDDNB)\n", value); size = sizeof(uint32_t); - if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, (void *)&query, &size)) + if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size)) seq_printf(m, "\t%u.%u W (average GPU)\n", query >> 8, query & 0xff); size = sizeof(value); seq_printf(m, "\n"); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index ad40395be602..3b33af30eb0f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -2141,7 +2141,7 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, int idx, /* For the 40.46 release, they changed the value name */ switch (idx) { - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: if (hwmgr->smu_version == 0x282e00) *query = metrics_table.AverageSocketPower << 8; else @@ -2260,7 +2260,7 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: *size = 16; ret = vega20_get_gpu_power(hwmgr, idx, (uint32_t *)value); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index e5f629a23db6..704a2b577a0e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1130,7 +1130,7 @@ static int arcturus_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = arcturus_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c index 4840e4d69b10..9548bd3c624b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c @@ -212,7 +212,7 @@ static int cyan_skillfish_read_sensor(struct smu_context *smu, *(uint32_t *)data *= 100; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 06474bbb7382..18487ae10bcf 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -2202,7 +2202,7 @@ static int navi10_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = navi1x_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 6dead62095bb..4bb289f9b4b8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -1902,7 +1902,7 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = sienna_cichlid_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 8a2c9c7abea6..201cec599842 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -1540,7 +1540,7 @@ static int vangogh_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = vangogh_common_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index 7b5ccb935fc0..c8119491c516 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1315,6 +1315,7 @@ static int renoir_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 1341363ab01a..cc3169400c9b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1148,6 +1148,7 @@ static int aldebaran_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = aldebaran_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 203dc50c0fd5..c904da1f7a04 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -953,7 +953,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_0_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c index 0951659299c1..626591f54bc4 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -572,7 +572,7 @@ static int smu_v13_0_4_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_4_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c index 5f8e70d4c467..c6e7c2115a26 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c @@ -388,6 +388,7 @@ static int smu_v13_0_5_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index aedf1c41d4a4..5474024e0654 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -1213,6 +1213,7 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 880a83e53882..822b97190a20 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -934,7 +934,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_7_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index 14fe45d3b7b7..2e74d749efdd 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -479,6 +479,7 @@ static int yellow_carp_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; -- cgit From 15419813f2ef8b810bf2e11f5b2269acf776cb44 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 10 Aug 2023 05:32:02 -0500 Subject: drm/amd: Hide unsupported power attributes Some ASICS only offer one type of power attribute, so in the visible callback check whether the attributes are supported and hide if not supported. Signed-off-by: Mario Limonciello Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 8133d968f75b..5b1d73b00ef7 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -3179,6 +3179,7 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, struct amdgpu_device *adev = dev_get_drvdata(dev); umode_t effective_mode = attr->mode; uint32_t gc_ver = adev->ip_versions[GC_HWIP][0]; + uint32_t tmp; /* under multi-vf mode, the hwmon attributes are all not supported */ if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) @@ -3264,6 +3265,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, (attr == &sensor_dev_attr_power1_average.dev_attr.attr)) return 0; + /* not all products support both average and instantaneous */ + if (attr == &sensor_dev_attr_power1_average.dev_attr.attr && + amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&tmp) == -EOPNOTSUPP) + return 0; + if (attr == &sensor_dev_attr_power1_input.dev_attr.attr && + amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&tmp) == -EOPNOTSUPP) + return 0; + /* hide max/min values if we can't both query and manage the fan */ if (((amdgpu_dpm_set_fan_speed_pwm(adev, U32_MAX) == -EOPNOTSUPP) && (amdgpu_dpm_get_fan_speed_pwm(adev, NULL) == -EOPNOTSUPP) && -- cgit From 1347b15d5e8e167f8f29e7bfb26ce04d335430e9 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Sun, 13 Aug 2023 14:14:33 +0530 Subject: drm/amd/display: Replace ternary operator with min() in 'dm_helpers_parse_edid_caps' Fixes the following coccicheck: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c:120:41-42: WARNING opportunity for min() Cc: Harry Wentland Cc: Rodrigo Siqueira Cc: Aurabindo Pillai Cc: Alex Deucher Signed-off-by: Srinivasan Shanmugam Reviewed-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index e94eeeb97688..4b230933b28e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -117,7 +117,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps( if (sad_count <= 0) return result; - edid_caps->audio_mode_count = sad_count < DC_MAX_AUDIO_DESC_COUNT ? sad_count : DC_MAX_AUDIO_DESC_COUNT; + edid_caps->audio_mode_count = min(sad_count, DC_MAX_AUDIO_DESC_COUNT); for (i = 0; i < edid_caps->audio_mode_count; ++i) { struct cea_sad *sad = &sads[i]; -- cgit From b828e1004cce55a078ba7bb11e252c2499793025 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Sat, 12 Aug 2023 20:20:31 +0530 Subject: drm/amdgpu: Replace ternary operator with min() in 'amdgpu_iomem_write' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following coccicheck: drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c:2482:16-17: WARNING opportunity for min() min() macro is defined in include/linux/minmax.h. It avoids multiple evaluations of the arguments when non-constant and performs strict type-checking. Cc: Guchun Chen Cc: Christian König Cc: Alex Deucher Cc: "Pan, Xinhui" Signed-off-by: Srinivasan Shanmugam Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index f27bd4a3467a..4e51dce3aab5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -2474,7 +2474,7 @@ static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf, struct page *p; void *ptr; - bytes = bytes < size ? bytes : size; + bytes = min(bytes, size); addr = dom ? iommu_iova_to_phys(dom, addr) : addr; -- cgit From 2e0847a756acb69bc8196e5c604a6dcdf0cd0f82 Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Sat, 5 Aug 2023 21:58:46 -0400 Subject: drm/amd/display: [FW Promotion] Release 0.0.179.0 - Add defines to specify new PHY power states Acked-by: Stylon Wang Signed-off-by: Anthony Koo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 6a1571ffeaf9..7afa78b918b5 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -2144,6 +2144,10 @@ enum dmub_phy_fsm_state { DMUB_PHY_FSM_PLL_EN, DMUB_PHY_FSM_TX_EN, DMUB_PHY_FSM_FAST_LP, + DMUB_PHY_FSM_P2_PLL_OFF_CPM, + DMUB_PHY_FSM_P2_PLL_OFF_PG, + DMUB_PHY_FSM_P2_PLL_OFF, + DMUB_PHY_FSM_P2_PLL_ON, }; /** -- cgit From 7fc4ccf1b1f538c06057957c661f97840eee9378 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Mon, 7 Aug 2023 13:14:15 -0400 Subject: drm/amd/display: Promote DAL to 3.2.247 This version brings along following fixes: - Improve power saving feature - Clean up for code clarity - Fix crashing bug - Fix pipe allocation for older ASIC - Fix for gamut remap - Fix 8K 60Hz display in test cases - Fix bug in clock gating - Improve DP2 compliance Acked-by: Stylon Wang Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index fc9756ea7cc5..0d0bef8eb331 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -47,7 +47,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.246" +#define DC_VER "3.2.247" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit From 81a7be799af7cfb37e24f4d94bde8dcc8fb34c8a Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Wed, 28 Jun 2023 11:57:51 -0400 Subject: drm/amd/display: Update adaptive sync infopackets for replay Update infopackets for replay Signed-off-by: Bhawanpreet Lakha Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') 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 4d3d6009838c..268cb99a4c4b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6045,7 +6045,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket); - if (stream->link->psr_settings.psr_feature_enabled) { + if (stream->link->psr_settings.psr_feature_enabled || stream->link->replay_settings.replay_feature_enabled) { // // should decide stream support vsc sdp colorimetry capability // before building vsc info packet @@ -7785,7 +7785,7 @@ static void update_freesync_state_on_stream( aconn = (struct amdgpu_dm_connector *)new_stream->dm_stream_context; - if (aconn && aconn->as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) { + if (aconn && (aconn->as_type == FREESYNC_TYPE_PCON_IN_WHITELIST || aconn->vsdb_info.replay_mode)) { pack_sdp_v1_3 = aconn->pack_sdp_v1_3; if (aconn->vsdb_info.amd_vsdb_version == 1) diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c index ec64f19e1786..84f9b412a4f1 100644 --- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c @@ -149,6 +149,8 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream, /* VSC packet set to 4 for PSR-SU, or 2 for PSR1 */ if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) vsc_packet_revision = vsc_packet_rev4; + else if (stream->link->replay_settings.config.replay_supported) + vsc_packet_revision = vsc_packet_rev4; else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) vsc_packet_revision = vsc_packet_rev2; @@ -536,6 +538,9 @@ void mod_build_adaptive_sync_infopacket(const struct dc_stream_state *stream, case FREESYNC_TYPE_PCON_IN_WHITELIST: mod_build_adaptive_sync_infopacket_v1(info_packet); break; + case ADAPTIVE_SYNC_TYPE_EDP: + mod_build_adaptive_sync_infopacket_v1(info_packet); + break; case ADAPTIVE_SYNC_TYPE_NONE: case FREESYNC_TYPE_PCON_NOT_IN_WHITELIST: default: -- cgit From d34fecc6e91e802f567764ffd0f5c930bb1c398d Mon Sep 17 00:00:00 2001 From: Samir Dhume Date: Mon, 17 Jul 2023 11:30:56 -0400 Subject: drm/amdgpu/jpeg: sriov support for jpeg_v4_0_3 initialization table handshake with mmsch Signed-off-by: Samir Dhume Acked-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 171 +++++++++++++++++++++++++++---- 1 file changed, 151 insertions(+), 20 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c index 03967d84fce9..15612915bb6c 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c @@ -26,6 +26,7 @@ #include "soc15.h" #include "soc15d.h" #include "jpeg_v4_0_3.h" +#include "mmsch_v4_0_3.h" #include "vcn/vcn_4_0_3_offset.h" #include "vcn/vcn_4_0_3_sh_mask.h" @@ -41,6 +42,7 @@ static void jpeg_v4_0_3_set_irq_funcs(struct amdgpu_device *adev); static int jpeg_v4_0_3_set_powergating_state(void *handle, enum amd_powergating_state state); static void jpeg_v4_0_3_set_ras_funcs(struct amdgpu_device *adev); +static void jpeg_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring); static int amdgpu_ih_srcid_jpeg[] = { VCN_4_0__SRCID__JPEG_DECODE, @@ -171,6 +173,119 @@ static int jpeg_v4_0_3_sw_fini(void *handle) return r; } +static int jpeg_v4_0_3_start_sriov(struct amdgpu_device *adev) +{ + struct amdgpu_ring *ring; + uint64_t ctx_addr; + uint32_t param, resp, expected; + uint32_t tmp, timeout; + + struct amdgpu_mm_table *table = &adev->virt.mm_table; + uint32_t *table_loc; + uint32_t table_size; + uint32_t size, size_dw, item_offset; + uint32_t init_status; + int i, j, jpeg_inst; + + struct mmsch_v4_0_cmd_direct_write + direct_wt = { {0} }; + struct mmsch_v4_0_cmd_end end = { {0} }; + struct mmsch_v4_0_3_init_header header; + + direct_wt.cmd_header.command_type = + MMSCH_COMMAND__DIRECT_REG_WRITE; + end.cmd_header.command_type = + MMSCH_COMMAND__END; + + for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) { + jpeg_inst = GET_INST(JPEG, i); + + memset(&header, 0, sizeof(struct mmsch_v4_0_3_init_header)); + header.version = MMSCH_VERSION; + header.total_size = sizeof(struct mmsch_v4_0_3_init_header) >> 2; + + table_loc = (uint32_t *)table->cpu_addr; + table_loc += header.total_size; + + item_offset = header.total_size; + + for (j = 0; j < adev->jpeg.num_jpeg_rings; j++) { + ring = &adev->jpeg.inst[i].ring_dec[j]; + table_size = 0; + + tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_LOW); + MMSCH_V4_0_INSERT_DIRECT_WT(tmp, lower_32_bits(ring->gpu_addr)); + tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_HIGH); + MMSCH_V4_0_INSERT_DIRECT_WT(tmp, upper_32_bits(ring->gpu_addr)); + tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_SIZE); + MMSCH_V4_0_INSERT_DIRECT_WT(tmp, ring->ring_size / 4); + + if (j <= 3) { + header.mjpegdec0[j].table_offset = item_offset; + header.mjpegdec0[j].init_status = 0; + header.mjpegdec0[j].table_size = table_size; + } else { + header.mjpegdec1[j - 4].table_offset = item_offset; + header.mjpegdec1[j - 4].init_status = 0; + header.mjpegdec1[j - 4].table_size = table_size; + } + header.total_size += table_size; + item_offset += table_size; + } + + MMSCH_V4_0_INSERT_END(); + + /* send init table to MMSCH */ + size = sizeof(struct mmsch_v4_0_3_init_header); + table_loc = (uint32_t *)table->cpu_addr; + memcpy((void *)table_loc, &header, size); + + ctx_addr = table->gpu_addr; + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr)); + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr)); + + tmp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID); + tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK; + tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT); + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID, tmp); + + size = header.total_size; + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_SIZE, size); + + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP, 0); + + param = 0x00000001; + WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_HOST, param); + tmp = 0; + timeout = 1000; + resp = 0; + expected = MMSCH_VF_MAILBOX_RESP__OK; + init_status = + ((struct mmsch_v4_0_3_init_header *)(table_loc))->mjpegdec0[i].init_status; + while (resp != expected) { + resp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP); + + if (resp != 0) + break; + udelay(10); + tmp = tmp + 10; + if (tmp >= timeout) { + DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\ + " waiting for regMMSCH_VF_MAILBOX_RESP "\ + "(expected=0x%08x, readback=0x%08x)\n", + tmp, expected, resp); + return -EBUSY; + } + } + if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE && + init_status != MMSCH_VF_ENGINE_STATUS__PASS) + DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init status for jpeg: %x\n", + resp, init_status); + + } + return 0; +} + /** * jpeg_v4_0_3_hw_init - start and test JPEG block * @@ -183,31 +298,47 @@ static int jpeg_v4_0_3_hw_init(void *handle) struct amdgpu_ring *ring; int i, j, r, jpeg_inst; - for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { - jpeg_inst = GET_INST(JPEG, i); + if (amdgpu_sriov_vf(adev)) { + r = jpeg_v4_0_3_start_sriov(adev); + if (r) + return r; - ring = adev->jpeg.inst[i].ring_dec; + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { + ring = &adev->jpeg.inst[i].ring_dec[j]; + ring->wptr = 0; + ring->wptr_old = 0; + jpeg_v4_0_3_dec_ring_set_wptr(ring); + ring->sched.ready = true; + } + } + } else { + for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { + jpeg_inst = GET_INST(JPEG, i); - if (ring->use_doorbell) - adev->nbio.funcs->vcn_doorbell_range( - adev, ring->use_doorbell, - (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + - 9 * jpeg_inst, - adev->jpeg.inst[i].aid_id); + ring = adev->jpeg.inst[i].ring_dec; - for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { - ring = &adev->jpeg.inst[i].ring_dec[j]; if (ring->use_doorbell) - WREG32_SOC15_OFFSET( - VCN, GET_INST(VCN, i), - regVCN_JPEG_DB_CTRL, - (ring->pipe ? (ring->pipe - 0x15) : 0), - ring->doorbell_index + adev->nbio.funcs->vcn_doorbell_range( + adev, ring->use_doorbell, + (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + + 9 * jpeg_inst, + adev->jpeg.inst[i].aid_id); + + for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { + ring = &adev->jpeg.inst[i].ring_dec[j]; + if (ring->use_doorbell) + WREG32_SOC15_OFFSET( + VCN, GET_INST(VCN, i), + regVCN_JPEG_DB_CTRL, + (ring->pipe ? (ring->pipe - 0x15) : 0), + ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT | - VCN_JPEG_DB_CTRL__EN_MASK); - r = amdgpu_ring_test_helper(ring); - if (r) - return r; + VCN_JPEG_DB_CTRL__EN_MASK); + r = amdgpu_ring_test_helper(ring); + if (r) + return r; + } } } DRM_DEV_INFO(adev->dev, "JPEG decode initialized successfully.\n"); -- cgit From 0fc7d79b45f6fd5129c69cccc41385b09b5e63c1 Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Wed, 28 Jun 2023 11:56:45 -0400 Subject: drm/amd/display: Handle Replay related hpd irq Handle replay related hpd irqs Signed-off-by: Bhawanpreet Lakha Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- .../dc/link/protocols/link_dp_irq_handler.c | 66 ++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c index ef8739df91bc..e047bbeaa49a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c @@ -182,6 +182,68 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link) return false; } +static bool handle_hpd_irq_replay_sink(struct dc_link *link) +{ + union dpcd_replay_configuration replay_configuration; + /*AMD Replay version reuse DP_PSR_ERROR_STATUS for REPLAY_ERROR status.*/ + union psr_error_status replay_error_status; + + if (!link->replay_settings.replay_feature_enabled) + return false; + + dm_helpers_dp_read_dpcd( + link->ctx, + link, + DP_SINK_PR_REPLAY_STATUS, + &replay_configuration.raw, + sizeof(replay_configuration.raw)); + + dm_helpers_dp_read_dpcd( + link->ctx, + link, + DP_PSR_ERROR_STATUS, + &replay_error_status.raw, + sizeof(replay_error_status.raw)); + + link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR = + replay_error_status.bits.LINK_CRC_ERROR; + link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR = + replay_configuration.bits.DESYNC_ERROR_STATUS; + link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR = + replay_configuration.bits.STATE_TRANSITION_ERROR_STATUS; + + if (link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR || + link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR || + link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR) { + bool allow_active; + + /* Acknowledge and clear configuration bits */ + dm_helpers_dp_write_dpcd( + link->ctx, + link, + DP_SINK_PR_REPLAY_STATUS, + &replay_configuration.raw, + sizeof(replay_configuration.raw)); + + /* Acknowledge and clear error bits */ + dm_helpers_dp_write_dpcd( + link->ctx, + link, + DP_PSR_ERROR_STATUS,/*DpcdAddress_REPLAY_Error_Status*/ + &replay_error_status.raw, + sizeof(replay_error_status.raw)); + + /* Replay error, disable and re-enable Replay */ + if (link->replay_settings.replay_allow_active) { + allow_active = false; + edp_set_replay_allow_active(link, &allow_active, true, false, NULL); + allow_active = true; + edp_set_replay_allow_active(link, &allow_active, true, false, NULL); + } + } + return true; +} + void dp_handle_link_loss(struct dc_link *link) { struct pipe_ctx *pipes[MAX_PIPES]; @@ -360,6 +422,10 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, /* PSR-related error was detected and handled */ return true; + if (handle_hpd_irq_replay_sink(link)) + /* Replay-related error was detected and handled */ + return true; + /* If PSR-related error handled, Main link may be off, * so do not handle as a normal sink status change interrupt. */ -- cgit From dd12b858c246b81f6ad6d616857f04f1db33a544 Mon Sep 17 00:00:00 2001 From: Samir Dhume Date: Mon, 17 Jul 2023 11:09:38 -0400 Subject: drm/amdgpu/vcn: Skip vcn power-gating change for sriov CG/PG is handled on the host side. Signed-off-by: Samir Dhume Acked-by: Leo Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c index 503cd26d3fdd..f85d18cd74ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c @@ -1536,6 +1536,15 @@ static int vcn_v4_0_3_set_powergating_state(void *handle, struct amdgpu_device *adev = (struct amdgpu_device *)handle; int ret; + /* for SRIOV, guest should not control VCN Power-gating + * MMSCH FW should control Power-gating and clock-gating + * guest should avoid touching CGC and PG + */ + if (amdgpu_sriov_vf(adev)) { + adev->vcn.cur_state = AMD_PG_STATE_UNGATE; + return 0; + } + if (state == adev->vcn.cur_state) return 0; -- cgit From 1d02ae4ebd672a1140948e36daa5258b9b620434 Mon Sep 17 00:00:00 2001 From: Asad Kamal Date: Thu, 10 Aug 2023 20:44:54 +0800 Subject: drm/amd/pm: Update pci link width for smu v13.0.6 Update addresses of PCIE link width registers, & link width format used to populate gpu metrics table for smu v13.0.6 v2: Removed ESM register update v3: Updated patch subject and message Signed-off-by: Asad Kamal Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 5474024e0654..94043a037f8c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -81,9 +81,10 @@ #define EPSILON 1 #define smnPCIE_ESM_CTRL 0x193D0 -#define smnPCIE_LC_LINK_WIDTH_CNTL 0x1ab40288 +#define smnPCIE_LC_LINK_WIDTH_CNTL 0x1a340288 #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4 +#define MAX_LINK_WIDTH 6 static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), @@ -1947,6 +1948,7 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table struct amdgpu_device *adev = smu->adev; int ret = 0, inst0, xcc0; MetricsTable_t *metrics; + u16 link_width_level; inst0 = adev->sdma.instance[0].aid_id; xcc0 = GET_INST(GC, 0); @@ -1997,8 +1999,12 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table gpu_metrics->throttle_status = 0; if (!(adev->flags & AMD_IS_APU)) { + link_width_level = smu_v13_0_6_get_current_pcie_link_width_level(smu); + if (link_width_level > MAX_LINK_WIDTH) + link_width_level = 0; + gpu_metrics->pcie_link_width = - smu_v13_0_6_get_current_pcie_link_width_level(smu); + DECODE_LANE_WIDTH(link_width_level); gpu_metrics->pcie_link_speed = smu_v13_0_6_get_current_pcie_link_speed(smu); } -- cgit From 400a39f1ec43d283b730c25b448dab3abb66886b Mon Sep 17 00:00:00 2001 From: James Zhu Date: Wed, 9 Aug 2023 16:45:04 -0400 Subject: drm/amdgpu: skip xcp drm device allocation when out of drm resource MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Return 0 when drm device alloc failed with -ENOSPC in order to allow amdgpu drive loading. But the xcp without drm device node assigned won't be visiable in user space. This helps amdgpu driver loading on system which has more than 64 nodes, the current limitation. The proposal to add more drm nodes is discussed in public, which will support up to 2^20 nodes totally. kernel drm: https://lore.kernel.org/lkml/20230724211428.3831636-1-michal.winiarski@intel.com/T/ libdrm: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/305 Signed-off-by: James Zhu Acked-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c | 13 ++++++++++++- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 9 ++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c index 9c9cca129498..565a1fa436d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c @@ -239,8 +239,13 @@ static int amdgpu_xcp_dev_alloc(struct amdgpu_device *adev) for (i = 1; i < MAX_XCP; i++) { ret = amdgpu_xcp_drm_dev_alloc(&p_ddev); - if (ret) + if (ret == -ENOSPC) { + dev_warn(adev->dev, + "Skip xcp node #%d when out of drm node resource.", i); + return 0; + } else if (ret) { return ret; + } /* Redirect all IOCTLs to the primary device */ adev->xcp_mgr->xcp[i].rdev = p_ddev->render->dev; @@ -328,6 +333,9 @@ int amdgpu_xcp_dev_register(struct amdgpu_device *adev, return 0; for (i = 1; i < MAX_XCP; i++) { + if (!adev->xcp_mgr->xcp[i].ddev) + break; + ret = drm_dev_register(adev->xcp_mgr->xcp[i].ddev, ent->driver_data); if (ret) return ret; @@ -345,6 +353,9 @@ void amdgpu_xcp_dev_unplug(struct amdgpu_device *adev) return; for (i = 1; i < MAX_XCP; i++) { + if (!adev->xcp_mgr->xcp[i].ddev) + break; + p_ddev = adev->xcp_mgr->xcp[i].ddev; drm_dev_unplug(p_ddev); p_ddev->render->dev = adev->xcp_mgr->xcp[i].rdev; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 63f7a21223c1..ff98fded9534 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1915,7 +1915,14 @@ int kfd_topology_add_device(struct kfd_node *gpu) const char *asic_name = amdgpu_asic_name[gpu->adev->asic_type]; gpu_id = kfd_generate_gpu_id(gpu); - pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id); + if (gpu->xcp && !gpu->xcp->ddev) { + dev_warn(gpu->adev->dev, + "Won't add GPU (ID: 0x%x) to topology since it has no drm node assigned.", + gpu_id); + return 0; + } else { + pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id); + } /* Check to see if this gpu device exists in the topology_device_list. * If so, assign the gpu to that device, -- cgit From e49311c44a6e5066c117715aadd48d06badfd144 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Tue, 15 Aug 2023 16:55:16 +0800 Subject: drm/amd/pm: allow the user to force BACO on smu v13.0.0/7 allow the user to force BACO on smu v13.0.0/7 Signed-off-by: Kenneth Feng Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 3 ++- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 895cda8e6934..52e9c7611013 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -2263,7 +2263,7 @@ int smu_v13_0_baco_set_state(struct smu_context *smu, if (state == SMU_BACO_STATE_ENTER) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, - smu_baco->maco_support ? + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? BACO_SEQ_BAMACO : BACO_SEQ_BACO, NULL); } else { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index c904da1f7a04..784a9d26d6bd 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -2206,7 +2206,8 @@ static int smu_v13_0_0_baco_enter(struct smu_context *smu) if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) return smu_v13_0_baco_set_armd3_sequence(smu, - smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO); else return smu_v13_0_baco_enter(smu); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 822b97190a20..32b0bb9d0385 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -2134,7 +2134,8 @@ static int smu_v13_0_7_baco_enter(struct smu_context *smu) if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) return smu_v13_0_baco_set_armd3_sequence(smu, - smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO); else return smu_v13_0_baco_enter(smu); } -- cgit From f1d1abd616ba008ca679af0e793217ec11c55113 Mon Sep 17 00:00:00 2001 From: Asad Kamal Date: Thu, 10 Aug 2023 22:08:40 +0800 Subject: drm/amd/pm: Update pci link speed for smu v13.0.6 Update pcie link speed registers for smu v13.0.6 & populate gpu metric table with pcie link speed rather than gen for smu v13_0_0, smu v13_0_6 & smu v13_0_7 v2: Update ESM register address Used macro to convert pcie gen to speed v3: Chaged macro to inline function for pcie gen to speed Signed-off-by: Asad Kamal Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h | 1 - drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 1 - drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 7 ++++++- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 16 ++++++++++++++-- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 7 ++++++- drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 2 ++ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 8 ++++++++ 7 files changed, 36 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h index 1b4e0e4716ea..a0e5ad0381d6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h @@ -64,7 +64,6 @@ #define LINK_SPEED_MAX 3 static const __maybe_unused uint16_t link_width[] = {0, 1, 2, 4, 8, 12, 16}; -static const __maybe_unused uint16_t link_speed[] = {25, 50, 80, 160}; static const struct smu_temperature_range __maybe_unused smu11_thermal_policy[] = { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 52e9c7611013..f1282fc4b90a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -83,7 +83,6 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin"); #define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE static const int link_width[] = {0, 1, 2, 4, 8, 12, 16}; -static const int link_speed[] = {25, 50, 80, 160}; const int pmfw_decoded_link_speed[5] = {1, 2, 3, 4, 5}; const int pmfw_decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16}; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 784a9d26d6bd..8b7403ba89d7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -102,6 +102,8 @@ #define PP_OD_FEATURE_UCLK_FMAX 3 #define PP_OD_FEATURE_GFX_VF_CURVE 4 +#define LINK_SPEED_MAX 3 + static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -1760,7 +1762,10 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = metrics->AvgFanRpm; gpu_metrics->pcie_link_width = metrics->PcieWidth; - gpu_metrics->pcie_link_speed = metrics->PcieRate; + if ((metrics->PcieRate - 1) > LINK_SPEED_MAX) + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1); + else + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate); gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 94043a037f8c..6ed9cd0a1e4e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -80,12 +80,17 @@ /* possible frequency drift (1Mhz) */ #define EPSILON 1 -#define smnPCIE_ESM_CTRL 0x193D0 +#define smnPCIE_ESM_CTRL 0x93D0 #define smnPCIE_LC_LINK_WIDTH_CNTL 0x1a340288 #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4 #define MAX_LINK_WIDTH 6 +#define smnPCIE_LC_SPEED_CNTL 0x1a340290 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5 +#define LINK_SPEED_MAX 4 + static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -1930,6 +1935,7 @@ smu_v13_0_6_get_current_pcie_link_width_level(struct smu_context *smu) static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; + uint32_t speed_level; uint32_t esm_ctrl; /* TODO: confirm this on real target */ @@ -1937,7 +1943,13 @@ static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu) if ((esm_ctrl >> 15) & 0x1FFFF) return (((esm_ctrl >> 8) & 0x3F) + 128); - return smu_v13_0_get_current_pcie_link_speed(smu); + speed_level = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & + PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) + >> PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; + if (speed_level > LINK_SPEED_MAX) + speed_level = 0; + + return pcie_gen_to_speed(speed_level + 1); } static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 32b0bb9d0385..94ef5b4d116d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -78,6 +78,8 @@ #define PP_OD_FEATURE_UCLK_FMAX 3 #define PP_OD_FEATURE_GFX_VF_CURVE 4 +#define LINK_SPEED_MAX 3 + static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -1736,7 +1738,10 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = metrics->AvgFanRpm; gpu_metrics->pcie_link_width = metrics->PcieWidth; - gpu_metrics->pcie_link_speed = metrics->PcieRate; + if ((metrics->PcieRate - 1) > LINK_SPEED_MAX) + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1); + else + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate); gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index 442d267088bc..12618a583e97 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -39,6 +39,8 @@ #define MP1_C2PMSG_90__CONTENT_MASK 0xFFFFFFFFL +const int link_speed[] = {25, 50, 80, 160, 320, 640}; + #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) #type static const char * const __smu_message_names[] = { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index d7cd358a53bd..cc590e27d88a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -30,6 +30,14 @@ #define FDO_PWM_MODE_STATIC 1 #define FDO_PWM_MODE_STATIC_RPM 5 +extern const int link_speed[]; + +/* Helper to Convert from PCIE Gen 1/2/3/4/5/6 to 0.1 GT/s speed units */ +static inline int pcie_gen_to_speed(uint32_t gen) +{ + return ((gen == 0) ? link_speed[0] : link_speed[gen - 1]); +} + int smu_cmn_send_msg_without_waiting(struct smu_context *smu, uint16_t msg_index, uint32_t param); -- cgit From b5cdadedaafe15cc940322990081060598570f28 Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Mon, 14 Aug 2023 19:52:16 +0530 Subject: drm/amdgpu: Remove gfxoff check in GFX v9.4.3 GFXOFF feature is not there for GFX 9.4.3 ASICs. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index d8d6807e7b96..57ed4e5c294c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -337,13 +337,11 @@ static uint64_t gfx_v9_4_3_get_gpu_clock_counter(struct amdgpu_device *adev) { uint64_t clock; - amdgpu_gfx_off_ctrl(adev, false); mutex_lock(&adev->gfx.gpu_clock_mutex); WREG32_SOC15(GC, GET_INST(GC, 0), regRLC_CAPTURE_GPU_CLOCK_COUNT, 1); clock = (uint64_t)RREG32_SOC15(GC, GET_INST(GC, 0), regRLC_GPU_CLOCK_COUNT_LSB) | ((uint64_t)RREG32_SOC15(GC, GET_INST(GC, 0), regRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); mutex_unlock(&adev->gfx.gpu_clock_mutex); - amdgpu_gfx_off_ctrl(adev, true); return clock; } -- cgit From 603b9a575d571557cf2de0d745d88b7c59b35be7 Mon Sep 17 00:00:00 2001 From: Tim Huang Date: Mon, 14 Aug 2023 15:13:04 +0800 Subject: drm/amdgpu: skip fence GFX interrupts disable/enable for S0ix GFX v11.0.1 reported fence fallback timer expired issue on SDMA and GFX rings after S0ix resume. This is generated by EOP interrupts are disabled when S0ix suspend but fails to re-enable when resume because of the GFX is in GFXOFF. [ 203.349571] [drm] Fence fallback timer expired on ring sdma0 [ 203.349572] [drm] Fence fallback timer expired on ring gfx_0.0.0 [ 203.861635] [drm] Fence fallback timer expired on ring gfx_0.0.0 For S0ix, GFX is in GFXOFF state, avoid to touch the GFX registers to configure the fence driver interrupts for rings that belong to GFX. The interrupts configuration will be restored by GFXOFF exit. Signed-off-by: Tim Huang Reviewed-by: Mario Limonciello Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 41 +++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index c694b41f6461..7537f5aa76f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -551,6 +551,41 @@ int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev) return 0; } +/** + * amdgpu_fence_need_ring_interrupt_restore - helper function to check whether + * fence driver interrupts need to be restored. + * + * @ring: ring that to be checked + * + * Interrupts for rings that belong to GFX IP don't need to be restored + * when the target power state is s0ix. + * + * Return true if need to restore interrupts, false otherwise. + */ +static bool amdgpu_fence_need_ring_interrupt_restore(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + bool is_gfx_power_domain = false; + + switch (ring->funcs->type) { + case AMDGPU_RING_TYPE_SDMA: + /* SDMA 5.x+ is part of GFX power domain so it's covered by GFXOFF */ + if (adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(5, 0, 0)) + is_gfx_power_domain = true; + break; + case AMDGPU_RING_TYPE_GFX: + case AMDGPU_RING_TYPE_COMPUTE: + case AMDGPU_RING_TYPE_KIQ: + case AMDGPU_RING_TYPE_MES: + is_gfx_power_domain = true; + break; + default: + break; + } + + return !(adev->in_s0ix && is_gfx_power_domain); +} + /** * amdgpu_fence_driver_hw_fini - tear down the fence driver * for all possible rings. @@ -579,7 +614,8 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) amdgpu_fence_driver_force_completion(ring); if (!drm_dev_is_unplugged(adev_to_drm(adev)) && - ring->fence_drv.irq_src) + ring->fence_drv.irq_src && + amdgpu_fence_need_ring_interrupt_restore(ring)) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); @@ -655,7 +691,8 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev) continue; /* enable the interrupt */ - if (ring->fence_drv.irq_src) + if (ring->fence_drv.irq_src && + amdgpu_fence_need_ring_interrupt_restore(ring)) amdgpu_irq_get(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); } -- cgit From 0dee726395333fea833eaaf838bc80962df886c8 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 18 May 2023 11:52:51 -0500 Subject: drm/amd: flush any delayed gfxoff on suspend entry DCN 3.1.4 is reported to hang on s2idle entry if graphics activity is happening during entry. This is because GFXOFF was scheduled as delayed but RLC gets disabled in s2idle entry sequence which will hang GFX IP if not already in GFXOFF. To help this problem, flush any delayed work for GFXOFF early in s2idle entry sequence to ensure that it's off when RLC is changed. commit 4b31b92b143f ("drm/amdgpu: complete gfxoff allow signal during suspend without delay") modified power gating flow so that if called in s0ix that it ensured that GFXOFF wasn't put in work queue but instead processed immediately. This is dead code due to commit 10cb67eb8a1b ("drm/amdgpu: skip CG/PG for gfx during S0ix") because GFXOFF will now not be explicitly called as part of the suspend entry code. Remove that dead code. Signed-off-by: Mario Limonciello Signed-off-by: Tim Huang Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 9 +-------- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1b3bd77d82da..e77f048c99d8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4160,6 +4160,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); cancel_delayed_work_sync(&adev->delayed_init_work); + flush_delayed_work(&adev->gfx.gfx_off_delay_work); amdgpu_ras_suspend(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index c76b6bfc4dab..2382921710ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -700,15 +700,8 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) { - /* If going to s2idle, no need to wait */ - if (adev->in_s0ix) { - if (!amdgpu_dpm_set_powergating_by_smu(adev, - AMD_IP_BLOCK_TYPE_GFX, true)) - adev->gfx.gfx_off_state = true; - } else { - schedule_delayed_work(&adev->gfx.gfx_off_delay_work, + schedule_delayed_work(&adev->gfx.gfx_off_delay_work, delay); - } } } else { if (adev->gfx.gfx_off_req_count == 0) { -- cgit From e20ff051707c010685b638d314b360cea4b68bac Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Fri, 4 Aug 2023 09:52:23 +0530 Subject: drm/amdgpu: Add memory vendor information For ASICs with GC v9.4.3, determine the vendor information from scratch register. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 880460cd3239..f9a5a2c0573e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1998,6 +1998,19 @@ static int gmc_v9_0_init_mem_ranges(struct amdgpu_device *adev) return 0; } +static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev) +{ + static const u32 regBIF_BIOS_SCRATCH_4 = 0x50; + u32 vram_info; + + if (!amdgpu_sriov_vf(adev)) { + vram_info = RREG32(regBIF_BIOS_SCRATCH_4); + adev->gmc.vram_vendor = vram_info & 0xF; + } + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; + adev->gmc.vram_width = 128 * 64; +} + static int gmc_v9_0_sw_init(void *handle) { int r, vram_width = 0, vram_type = 0, vram_vendor = 0, dma_addr_bits; @@ -2010,15 +2023,12 @@ static int gmc_v9_0_sw_init(void *handle) spin_lock_init(&adev->gmc.invalidate_lock); - if (!(adev->bios) || adev->gmc.is_app_apu) { + if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 3)) { + gmc_v9_4_3_init_vram_info(adev); + } else if (!adev->bios) { if (adev->flags & AMD_IS_APU) { - if (adev->gmc.is_app_apu) { - adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; - adev->gmc.vram_width = 128 * 64; - } else { - adev->gmc.vram_type = AMDGPU_VRAM_TYPE_DDR4; - adev->gmc.vram_width = 64 * 64; - } + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_DDR4; + adev->gmc.vram_width = 64 * 64; } else { adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; adev->gmc.vram_width = 128 * 64; -- cgit From ef35c7ba60410926d0501e45aad299656a83826c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Aug 2023 17:25:37 -0400 Subject: Revert "Revert "drm/amdgpu/display: change pipe policy for DCN 2.0"" This reverts commit 27dd79c00aeab36cd7542c7a4481a32549038659. It appears MPC_SPLIT_DYNAMIC still causes problems with multiple displays on DCN2.0 hardware. Switch back to MPC_SPLIT_AVOID_MULT_DISP. This increases power usage with multiple displays, but avoids hangs. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2475 Cc: Rodrigo Siqueira Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 66b74bb5d936..d587f807dfd7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -712,7 +712,7 @@ static const struct dc_debug_options debug_defaults_drv = { .timing_trace = false, .clock_trace = true, .disable_pplib_clock_request = true, - .pipe_split_policy = MPC_SPLIT_DYNAMIC, + .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP, .force_single_disp_pipe_split = false, .disable_dcc = DCC_ENABLE, .vsr_support = true, -- cgit