From 534e3ea6726674c8a8f16e74820a7188e54f710f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Feb 2021 15:13:55 -0500 Subject: [PATCH 01/60] Revert "drm/amd/display: fix unused variable warning" This reverts commit 4c3a3292730c56591472717d8c5c0faf74f6c6bb. Bhawan's fix is better (less ifdefs), so revert this and apply Bhawan's. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 67fd9f4ef93e..f47551c9b2f1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5374,9 +5374,7 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_device *adev = drm_to_adev(crtc->dev); struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); -#if defined(CONFIG_DRM_AMD_DC_DCN) struct amdgpu_display_manager *dm = &adev->dm; -#endif int rc = 0; if (enable) { From 6eed1f3fba404dc0a1835c3a96694ea4152cd50e Mon Sep 17 00:00:00 2001 From: Bhawanpreet Lakha Date: Wed, 20 Jan 2021 12:23:06 -0500 Subject: [PATCH 02/60] drm/amd/display: Fix unused variable warning [Why] The dm struct is only being used if DCN config is defined and this causes a unused variable warning if DCN option is not set. [How] Remove the compile flag so the variable is used (there also seems to be a duplicate guard due to a bad rebase) so remove the outer guard to fix the warning. Fixes this warning drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c: In function 'dm_set_vblank': drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5380:33: warning: unused variable 'dm' [-Wunused-variable] Fixes: 98ab5f3513f9 ("drm/amd/display: Fix deadlock during gpu reset v3") Cc: Alex Deucher Cc: Nicholas Kazlauskas Cc: Stephen Rothwell Acked-by: Alex Deucher Reviewed-by: Harry Wentland Signed-off-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f47551c9b2f1..8a44b6ba8595 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5394,7 +5394,6 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) if (!dc_interrupt_set(adev->dm.dc, irq_source, enable)) return -EBUSY; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (amdgpu_in_reset(adev)) return 0; @@ -5414,7 +5413,6 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) mutex_unlock(&dm->dc_lock); -#endif return 0; } From ebdd2e9d1aef29a2eb7b797abe6d0e048ce00a7f Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Mon, 1 Feb 2021 15:02:30 +0100 Subject: [PATCH 03/60] drm/amdgpu: cleanup struct amdgpu_ring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch consist of below related changes: 1 Rename ring->priority to ring->hw_prio. 2 Assign correct hardware ring priority. 3 Remove ring->priority_mutex as ring priority remains unchanged after initialization. 4 Remove unused ring->num_jobs. v3: remove ring->num_jobs. v2: remove ring->priority_mutex. Fixes: 33abcb1f5a17 ("drm/amdgpu: set compute queue priority at mqd_init") Signed-off-by: Nirmoy Das Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 8 ++------ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 6 +----- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 1a612f51ecd9..b644c78475fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -166,7 +166,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, unsigned int max_dw, struct amdgpu_irq_src *irq_src, unsigned int irq_type, unsigned int hw_prio) { - int r, i; + int r; int sched_hw_submission = amdgpu_sched_hw_submission; u32 *num_sched; u32 hw_ip; @@ -258,8 +258,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, } ring->max_dw = max_dw; - ring->priority = DRM_SCHED_PRIORITY_NORMAL; - mutex_init(&ring->priority_mutex); + ring->hw_prio = hw_prio; if (!ring->no_scheduler) { hw_ip = ring->funcs->type; @@ -268,9 +267,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, &ring->sched; } - for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_COUNT; ++i) - atomic_set(&ring->num_jobs[i], 0); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 7112137689db..2ada80ce42f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -242,11 +242,7 @@ struct amdgpu_ring { struct dma_fence *vmid_wait; bool has_compute_vm_bug; bool no_scheduler; - - atomic_t num_jobs[DRM_SCHED_PRIORITY_COUNT]; - struct mutex priority_mutex; - /* protected by priority_mutex */ - int priority; + int hw_prio; #if defined(CONFIG_DEBUG_FS) struct dentry *ent; From 8c0225d79273968a65e73a4204fba023ae02714d Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Mon, 1 Feb 2021 12:12:34 +0100 Subject: [PATCH 04/60] drm/amdgpu: enable only one high prio compute queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For high priority compute to work properly we need to enable wave limiting on gfx pipe. Wave limiting is done through writing into mmSPI_WCL_PIPE_PERCENT_GFX register. Enable only one high priority compute queue to avoid race condition between multiple high priority compute queues writing that register simultaneously. Signed-off-by: Nirmoy Das Acked-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 15 ++++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | 2 +- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 6 ++---- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 6 ++---- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 7 ++----- 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index cd2c676a2797..8e0a6c62322e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -193,15 +193,16 @@ static bool amdgpu_gfx_is_multipipe_capable(struct amdgpu_device *adev) } bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev, - int pipe, int queue) + struct amdgpu_ring *ring) { - bool multipipe_policy = amdgpu_gfx_is_multipipe_capable(adev); - int cond; - /* Policy: alternate between normal and high priority */ - cond = multipipe_policy ? pipe : queue; - - return ((cond % 2) != 0); + /* Policy: use 1st queue as high priority compute queue if we + * have more than one compute queue. + */ + if (adev->gfx.num_compute_rings > 1 && + ring == &adev->gfx.compute_ring[0]) + return true; + return false; } void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h index 6b5a8f4642cc..72dbcd2bc6a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h @@ -380,7 +380,7 @@ void amdgpu_queue_mask_bit_to_mec_queue(struct amdgpu_device *adev, int bit, bool amdgpu_gfx_is_mec_queue_enabled(struct amdgpu_device *adev, int mec, int pipe, int queue); bool amdgpu_gfx_is_high_priority_compute_queue(struct amdgpu_device *adev, - int pipe, int queue); + struct amdgpu_ring *ring); int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev, int me, int pipe, int queue); void amdgpu_gfx_bit_to_me_queue(struct amdgpu_device *adev, int bit, diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 024460b9775d..8ac2af225436 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -4491,8 +4491,7 @@ static int gfx_v10_0_compute_ring_init(struct amdgpu_device *adev, int ring_id, irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP + ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec) + ring->pipe; - hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->pipe, - ring->queue) ? + hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring) ? AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL; /* type-2 packets are deprecated on MEC, use type-3 instead */ r = amdgpu_ring_init(adev, ring, 1024, @@ -6544,8 +6543,7 @@ static void gfx_v10_0_compute_mqd_set_priority(struct amdgpu_ring *ring, struct struct amdgpu_device *adev = ring->adev; if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) { - if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->pipe, - ring->queue)) { + if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring)) { mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH; mqd->cp_hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 37639214cbbb..b0284c4659ba 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -1923,8 +1923,7 @@ static int gfx_v8_0_compute_ring_init(struct amdgpu_device *adev, int ring_id, + ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec) + ring->pipe; - hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->pipe, - ring->queue) ? + hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring) ? AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_RING_PRIO_DEFAULT; /* type-2 packets are deprecated on MEC, use type-3 instead */ r = amdgpu_ring_init(adev, ring, 1024, @@ -4442,8 +4441,7 @@ static void gfx_v8_0_mqd_set_priority(struct amdgpu_ring *ring, struct vi_mqd *m struct amdgpu_device *adev = ring->adev; if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) { - if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->pipe, - ring->queue)) { + if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring)) { mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH; mqd->cp_hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index a896e3d0fcf8..7b13f9dd965a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -2227,8 +2227,7 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id, irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP + ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec) + ring->pipe; - hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->pipe, - ring->queue) ? + hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring) ? AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL; /* type-2 packets are deprecated on MEC, use type-3 instead */ return amdgpu_ring_init(adev, ring, 1024, @@ -3390,9 +3389,7 @@ static void gfx_v9_0_mqd_set_priority(struct amdgpu_ring *ring, struct v9_mqd *m struct amdgpu_device *adev = ring->adev; if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) { - if (amdgpu_gfx_is_high_priority_compute_queue(adev, - ring->pipe, - ring->queue)) { + if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring)) { mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH; mqd->cp_hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM; From 0a52a6cacca6030374fca7087e8556b382cca0e3 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 27 Jan 2021 11:35:54 +0100 Subject: [PATCH 05/60] drm/amdgpu: add wave limit functionality for gfx8,9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave limiting can be use to load balance high priority compute jobs along with gfx jobs. When enabled, this will reserve ~75% of waves for compute jobs. We do not need this from gfx10 onwards because >=gfx10 has asynchronous compute tunneling to replace wave limit requirement. Signed-off-by: Nirmoy Das Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 + drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 18 +++++++++++++++++- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 21 ++++++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 2ada80ce42f5..56acec1075ac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -197,6 +197,7 @@ struct amdgpu_ring_funcs { void (*soft_recovery)(struct amdgpu_ring *ring, unsigned vmid); int (*preempt_ib)(struct amdgpu_ring *ring); void (*emit_mem_sync)(struct amdgpu_ring *ring); + void (*emit_wave_limit)(struct amdgpu_ring *ring, bool enable); }; struct amdgpu_ring { diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index b0284c4659ba..bdfd29a22b3d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -29,6 +29,7 @@ #include "amdgpu.h" #include "amdgpu_gfx.h" +#include "amdgpu_ring.h" #include "vi.h" #include "vi_structs.h" #include "vid.h" @@ -6845,6 +6846,19 @@ static void gfx_v8_0_emit_mem_sync_compute(struct amdgpu_ring *ring) amdgpu_ring_write(ring, 0x0000000A); /* poll interval */ } +#define mmSPI_WCL_PIPE_PERCENT_GFX_DEFAULT 0x07ffffff +static void gfx_v8_0_emit_wave_limit(struct amdgpu_ring *ring, bool enable) +{ + uint32_t val; + + /* mmSPI_WCL_PIPE_PERCENT_GFX is 7 bit multiplier register to limit + * number of gfx waves. Setting 5 bit will make sure gfx only gets + * around 25% of gpu resources. + */ + val = enable ? 0x1f : mmSPI_WCL_PIPE_PERCENT_GFX_DEFAULT; + amdgpu_ring_emit_wreg(ring, mmSPI_WCL_PIPE_PERCENT_GFX, val); +} + static const struct amd_ip_funcs gfx_v8_0_ip_funcs = { .name = "gfx_v8_0", .early_init = gfx_v8_0_early_init, @@ -6928,7 +6942,8 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { 7 + /* gfx_v8_0_ring_emit_pipeline_sync */ VI_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + /* gfx_v8_0_ring_emit_vm_flush */ 7 + 7 + 7 + /* gfx_v8_0_ring_emit_fence_compute x3 for user fence, vm fence */ - 7, /* gfx_v8_0_emit_mem_sync_compute */ + 7 + /* gfx_v8_0_emit_mem_sync_compute */ + 5, /* gfx_v8_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */ .emit_ib_size = 7, /* gfx_v8_0_ring_emit_ib_compute */ .emit_ib = gfx_v8_0_ring_emit_ib_compute, .emit_fence = gfx_v8_0_ring_emit_fence_compute, @@ -6942,6 +6957,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { .pad_ib = amdgpu_ring_generic_pad_ib, .emit_wreg = gfx_v8_0_ring_emit_wreg, .emit_mem_sync = gfx_v8_0_emit_mem_sync_compute, + .emit_wave_limit = gfx_v8_0_emit_wave_limit, }; static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_kiq = { diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 7b13f9dd965a..027997e95e46 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -52,6 +52,7 @@ #include "asic_reg/pwr/pwr_10_0_offset.h" #include "asic_reg/pwr/pwr_10_0_sh_mask.h" +#include "asic_reg/gc/gc_9_0_default.h" #define GFX9_NUM_GFX_RINGS 1 #define GFX9_MEC_HPD_SIZE 4096 @@ -6667,6 +6668,22 @@ static void gfx_v9_0_emit_mem_sync(struct amdgpu_ring *ring) amdgpu_ring_write(ring, 0x0000000A); /* POLL_INTERVAL */ } +static void gfx_v9_0_emit_wave_limit(struct amdgpu_ring *ring, bool enable) +{ + struct amdgpu_device *adev = ring->adev; + uint32_t val; + + + /* mmSPI_WCL_PIPE_PERCENT_GFX is 7 bit multiplier register to limit + * number of gfx waves. Setting 5 bit will make sure gfx only gets + * around 25% of gpu resources. + */ + val = enable ? 0x1f : mmSPI_WCL_PIPE_PERCENT_GFX_DEFAULT; + amdgpu_ring_emit_wreg(ring, + SOC15_REG_OFFSET(GC, 0, mmSPI_WCL_PIPE_PERCENT_GFX), + val); +} + static const struct amd_ip_funcs gfx_v9_0_ip_funcs = { .name = "gfx_v9_0", .early_init = gfx_v9_0_early_init, @@ -6756,7 +6773,8 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = { SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + 2 + /* gfx_v9_0_ring_emit_vm_flush */ 8 + 8 + 8 + /* gfx_v9_0_ring_emit_fence x3 for user fence, vm fence */ - 7, /* gfx_v9_0_emit_mem_sync */ + 7 + /* gfx_v9_0_emit_mem_sync */ + 5, /* gfx_v9_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */ .emit_ib_size = 7, /* gfx_v9_0_ring_emit_ib_compute */ .emit_ib = gfx_v9_0_ring_emit_ib_compute, .emit_fence = gfx_v9_0_ring_emit_fence, @@ -6772,6 +6790,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = { .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait, .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait, .emit_mem_sync = gfx_v9_0_emit_mem_sync, + .emit_wave_limit = gfx_v9_0_emit_wave_limit, }; static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_kiq = { From 22e4f31529534e8237a5f7422e6d1990bca0e374 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 27 Jan 2021 15:38:30 +0100 Subject: [PATCH 06/60] drm/amdgpu: enable gfx wave limiting for high priority compute jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable gfx wave limiting for gfx jobs before pushing high priority compute jobs so that high priority compute jobs gets more resources to finish early. v2: use ring priority instead of job priority. Signed-off-by: Nirmoy Das Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 024d0a563a65..7645223ea0ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -195,6 +195,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync) ring->funcs->emit_mem_sync(ring); + if (ring->funcs->emit_wave_limit && + ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH) + ring->funcs->emit_wave_limit(ring, true); + if (ring->funcs->insert_start) ring->funcs->insert_start(ring); @@ -295,6 +299,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ring->current_ctx = fence_ctx; if (vm && ring->funcs->emit_switch_buffer) amdgpu_ring_emit_switch_buffer(ring); + + if (ring->funcs->emit_wave_limit && + ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH) + ring->funcs->emit_wave_limit(ring, false); + amdgpu_ring_commit(ring); return 0; } From 62826b86085dbcd38b88e8829e9650a85e2bc260 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Wed, 3 Feb 2021 18:15:13 +0800 Subject: [PATCH 07/60] drm/amd/pm: enable ACDC feature The power limit and clock ragne are different in AC mode and DC mode. Firmware does the setting after this feature is enabled. Signed-off-by: Kenneth Feng Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 3 +++ 1 file changed, 3 insertions(+) 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 e3ba40d9f83f..cf59f2218b7e 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 @@ -294,6 +294,9 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu, smu->adev->pg_flags & AMD_PG_SUPPORT_JPEG) *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MM_DPM_PG_BIT); + if (smu->dc_controlled_by_gpio) + *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ACDC_BIT); + return 0; } From 11964258fe733f82746b3d16c4448a3a9eea76b1 Mon Sep 17 00:00:00 2001 From: Kent Russell Date: Wed, 3 Feb 2021 13:02:09 -0500 Subject: [PATCH 08/60] drm/amdkfd: Get unique_id dynamically v2 Instead of caching the value during amdgpu_device_init, just call the function directly. This avoids issues where the unique_id hasn't been saved by the time that KFD's topology snapshot is done (e.g. Arcturus). KFD's topology information from the amdgpu_device was initially cached at KFD initialization due to amdkfd and amdgpu being separate modules. Now that they are combined together, we can directly call the functions that we need and avoid this unnecessary duplication and complexity. As a side-effect of this change, we also remove unique_id=0 for CPUs, which is obviously not unique. v2: Drop previous patch printing unique_id in hex Signed-off-by: Kent Russell Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 6 +++--- drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index a3fc23873819..0be72789ccbc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -497,8 +497,6 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, dev->node_props.num_sdma_queues_per_engine); sysfs_show_32bit_prop(buffer, offs, "num_cp_queues", dev->node_props.num_cp_queues); - sysfs_show_64bit_prop(buffer, offs, "unique_id", - dev->node_props.unique_id); if (dev->gpu) { log_max_watch_addr = @@ -529,6 +527,9 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, dev->node_props.capability); sysfs_show_32bit_prop(buffer, offs, "sdma_fw_version", dev->gpu->sdma_fw_version); + sysfs_show_64bit_prop(buffer, offs, "unique_id", + amdgpu_amdkfd_get_unique_id(dev->gpu->kgd)); + } return sysfs_show_32bit_prop(buffer, offs, "max_engine_clk_ccompute", @@ -1340,7 +1341,6 @@ int kfd_topology_add_device(struct kfd_dev *gpu) dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ? amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0; dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm); - dev->node_props.unique_id = amdgpu_amdkfd_get_unique_id(dev->gpu->kgd); kfd_fill_mem_clk_max_info(dev); kfd_fill_iolink_non_crat_info(dev); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h index 326d9b26b7aa..416fd910e12e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h @@ -57,7 +57,6 @@ struct kfd_node_properties { uint64_t hive_id; - uint64_t unique_id; uint32_t cpu_cores_count; uint32_t simd_count; uint32_t mem_banks_count; From 137aac26a2ed6d8b43a83eb842c5091aeb203b73 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 2 Feb 2021 10:20:52 -0500 Subject: [PATCH 09/60] drm/amdgpu/smu12: fix power reporting on renoir Align with Vangogh. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1467 Acked-by: Nirmoy Das Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ab15570305f7..f6844b90ca67 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1129,7 +1129,7 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu, *value = metrics->AverageUvdActivity / 100; break; case METRICS_AVERAGE_SOCKETPOWER: - *value = metrics->CurrentSocketPower << 8; + *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: *value = (metrics->GfxTemperature / 100) * From e83db77487d3cf9d42a5d417d39fc7af16fb6f1c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 2 Feb 2021 16:53:10 -0500 Subject: [PATCH 10/60] drm/amdgpu/gmc9: fix mmhub client mapping for arcturus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hw interface changed on arcturus so the old numbering scheme doesn't work. Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 66 +++++++++++++-------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index aedef9017c4c..3686e777c76c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -239,46 +239,44 @@ static const char *mmhub_client_ids_vega20[][2] = { }; static const char *mmhub_client_ids_arcturus[][2] = { + [0][0] = "DBGU1", + [1][0] = "XDP", [2][0] = "MP1", - [3][0] = "MP0", - [10][0] = "UTCL2", - [13][0] = "OSS", [14][0] = "HDP", - [15][0] = "SDMA0", - [32+15][0] = "SDMA1", - [64+15][0] = "SDMA2", - [96+15][0] = "SDMA3", - [128+15][0] = "SDMA4", - [160+11][0] = "JPEG", - [160+12][0] = "VCN", - [160+13][0] = "VCNU", - [160+15][0] = "SDMA5", - [192+10][0] = "UTCL2", - [192+11][0] = "JPEG1", - [192+12][0] = "VCN1", - [192+13][0] = "VCN1U", - [192+15][0] = "SDMA6", - [224+15][0] = "SDMA7", + [171][0] = "JPEG", + [172][0] = "VCN", + [173][0] = "VCNU", + [203][0] = "JPEG1", + [204][0] = "VCN1", + [205][0] = "VCN1U", + [256][0] = "SDMA0", + [257][0] = "SDMA1", + [258][0] = "SDMA2", + [259][0] = "SDMA3", + [260][0] = "SDMA4", + [261][0] = "SDMA5", + [262][0] = "SDMA6", + [263][0] = "SDMA7", + [384][0] = "OSS", [0][1] = "DBGU1", [1][1] = "XDP", [2][1] = "MP1", - [3][1] = "MP0", - [13][1] = "OSS", [14][1] = "HDP", - [15][1] = "SDMA0", - [32+15][1] = "SDMA1", - [64+15][1] = "SDMA2", - [96+15][1] = "SDMA3", - [128+15][1] = "SDMA4", - [160+11][1] = "JPEG", - [160+12][1] = "VCN", - [160+13][1] = "VCNU", - [160+15][1] = "SDMA5", - [192+11][1] = "JPEG1", - [192+12][1] = "VCN1", - [192+13][1] = "VCN1U", - [192+15][1] = "SDMA6", - [224+15][1] = "SDMA7", + [171][1] = "JPEG", + [172][1] = "VCN", + [173][1] = "VCNU", + [203][1] = "JPEG1", + [204][1] = "VCN1", + [205][1] = "VCN1U", + [256][1] = "SDMA0", + [257][1] = "SDMA1", + [258][1] = "SDMA2", + [259][1] = "SDMA3", + [260][1] = "SDMA4", + [261][1] = "SDMA5", + [262][1] = "SDMA6", + [263][1] = "SDMA7", + [384][1] = "OSS", }; static const struct soc15_reg_golden golden_settings_mmhub_1_0_0[] = From 680602d6c2d6ac850302b0cf4c03dcc6d9ea0fae Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Wed, 3 Feb 2021 18:40:52 +0800 Subject: [PATCH 11/60] drm/amd/pm: enable DCS Enable DCS V1: Enable Async DCS. V2: Add the ppfeaturemask bit to enable from the modprobe parameter. V3: 1. add the flag to skip APU support. 2. remove the hunk for workload selection since it doesn't impact the function. Signed-off-by: Kenneth Feng Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 8 ++++++-- drivers/gpu/drm/amd/include/amd_shared.h | 1 + drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 8fde2318a03c..9173da34dd22 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -132,8 +132,12 @@ uint amdgpu_pg_mask = 0xffffffff; uint amdgpu_sdma_phase_quantum = 32; char *amdgpu_disable_cu = NULL; char *amdgpu_virtual_display = NULL; -/* OverDrive(bit 14) disabled by default*/ -uint amdgpu_pp_feature_mask = 0xffffbfff; + +/* + * OverDrive(bit 14) disabled by default + * GFX DCS(bit 19) disabled by default + */ +uint amdgpu_pp_feature_mask = 0xfff7bfff; uint amdgpu_force_long_training; int amdgpu_job_hang_limit; int amdgpu_lbpw = -1; diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 9676016a37ce..43ed6291b2b8 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -213,6 +213,7 @@ enum PP_FEATURE_MASK { PP_ACG_MASK = 0x10000, PP_STUTTER_MODE = 0x20000, PP_AVFS_MASK = 0x40000, + PP_GFX_DCS_MASK = 0x80000, }; enum DC_FEATURE_MASK { 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 cf59f2218b7e..fd090d057d26 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 @@ -261,6 +261,11 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu, *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFX_GPO_BIT); } + if ((adev->pm.pp_feature & PP_GFX_DCS_MASK) && + (adev->asic_type > CHIP_SIENNA_CICHLID) && + !(adev->flags & AMD_IS_APU)) + *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_DCS_BIT); + if (adev->pm.pp_feature & PP_MCLK_DPM_MASK) *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT) From e1edaeafeb667688125ef1c4e2a098d2c798fc24 Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Mon, 1 Feb 2021 14:44:09 +0800 Subject: [PATCH 12/60] drm/amdgpu: support ASPM for some specific ASIC Support to program ASPM and LTR for Sienna Cichlid and forward ASIC. Disable ASPM for Sienna Cichlid and forward ASIC by default. Signed-off-by: Likun Gao Reviewed-by: Kenneth Feng Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h | 1 + drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c | 114 +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/nv.c | 15 +-- 3 files changed, 124 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h index 4ba0024aedf1..7c11bce4514b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h @@ -88,6 +88,7 @@ struct amdgpu_nbio_funcs { int (*ras_late_init)(struct amdgpu_device *adev); void (*enable_aspm)(struct amdgpu_device *adev, bool enable); + void (*program_aspm)(struct amdgpu_device *adev); }; struct amdgpu_nbio { diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c index b860f1c7b5b1..05ddec7ba7e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c @@ -34,6 +34,14 @@ #define smnCPM_CONTROL 0x11180460 #define smnPCIE_CNTL2 0x11180070 #define smnPCIE_LC_CNTL 0x11140280 +#define smnPCIE_LC_CNTL3 0x111402d4 +#define smnPCIE_LC_CNTL6 0x111402ec +#define smnPCIE_LC_CNTL7 0x111402f0 +#define smnBIF_CFG_DEV0_EPF0_DEVICE_CNTL2 0x1014008c +#define smnRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL 0x10123538 +#define smnBIF_CFG_DEV0_EPF0_PCIE_LTR_CAP 0x10140324 +#define smnPSWUSP0_PCIE_LC_CNTL2 0x111402c4 +#define smnNBIF_MGCG_CTRL_LCLK 0x1013a21c #define mmBIF_SDMA2_DOORBELL_RANGE 0x01d6 #define mmBIF_SDMA2_DOORBELL_RANGE_BASE_IDX 2 @@ -350,6 +358,111 @@ static void nbio_v2_3_enable_aspm(struct amdgpu_device *adev, WREG32_PCIE(smnPCIE_LC_CNTL, data); } +static void nbio_v2_3_program_ltr(struct amdgpu_device *adev) +{ + uint32_t def, data; + + WREG32_PCIE(smnRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL, 0x75EB); + + def = data = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP2); + data &= ~RCC_BIF_STRAP2__STRAP_LTR_IN_ASPML1_DIS_MASK; + if (def != data) + WREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP2, data); + + def = data = RREG32_PCIE(smnRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL); + data &= ~EP_PCIE_TX_LTR_CNTL__LTR_PRIV_MSG_DIS_IN_PM_NON_D0_MASK; + if (def != data) + WREG32_PCIE(smnRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL, data); + + def = data = RREG32_PCIE(smnBIF_CFG_DEV0_EPF0_DEVICE_CNTL2); + data |= BIF_CFG_DEV0_EPF0_DEVICE_CNTL2__LTR_EN_MASK; + if (def != data) + WREG32_PCIE(smnBIF_CFG_DEV0_EPF0_DEVICE_CNTL2, data); +} + +static void nbio_v2_3_program_aspm(struct amdgpu_device *adev) +{ + uint32_t def, data; + + def = data = RREG32_PCIE(smnPCIE_LC_CNTL); + data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK; + data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK; + data |= PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK; + if (def != data) + WREG32_PCIE(smnPCIE_LC_CNTL, data); + + def = data = RREG32_PCIE(smnPCIE_LC_CNTL7); + data |= PCIE_LC_CNTL7__LC_NBIF_ASPM_INPUT_EN_MASK; + if (def != data) + WREG32_PCIE(smnPCIE_LC_CNTL7, data); + + def = data = RREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK); + data |= NBIF_MGCG_CTRL_LCLK__NBIF_MGCG_REG_DIS_LCLK_MASK; + if (def != data) + WREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK, data); + + def = data = RREG32_PCIE(smnPCIE_LC_CNTL3); + data |= PCIE_LC_CNTL3__LC_DSC_DONT_ENTER_L23_AFTER_PME_ACK_MASK; + if (def != data) + WREG32_PCIE(smnPCIE_LC_CNTL3, data); + + def = data = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP3); + data &= ~RCC_BIF_STRAP3__STRAP_VLINK_ASPM_IDLE_TIMER_MASK; + data &= ~RCC_BIF_STRAP3__STRAP_VLINK_PM_L1_ENTRY_TIMER_MASK; + if (def != data) + WREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP3, data); + + def = data = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP5); + data &= ~RCC_BIF_STRAP5__STRAP_VLINK_LDN_ENTRY_TIMER_MASK; + if (def != data) + WREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP5, data); + + def = data = RREG32_PCIE(smnBIF_CFG_DEV0_EPF0_DEVICE_CNTL2); + data &= ~BIF_CFG_DEV0_EPF0_DEVICE_CNTL2__LTR_EN_MASK; + if (def != data) + WREG32_PCIE(smnBIF_CFG_DEV0_EPF0_DEVICE_CNTL2, data); + + WREG32_PCIE(smnBIF_CFG_DEV0_EPF0_PCIE_LTR_CAP, 0x10011001); + + def = data = RREG32_PCIE(smnPSWUSP0_PCIE_LC_CNTL2); + data |= PSWUSP0_PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L1_MASK | + PSWUSP0_PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L23_MASK; + data &= ~PSWUSP0_PCIE_LC_CNTL2__LC_RCV_L0_TO_RCV_L0S_DIS_MASK; + if (def != data) + WREG32_PCIE(smnPSWUSP0_PCIE_LC_CNTL2, data); + + def = data = RREG32_PCIE(smnPCIE_LC_CNTL6); + data |= PCIE_LC_CNTL6__LC_L1_POWERDOWN_MASK | + PCIE_LC_CNTL6__LC_RX_L0S_STANDBY_EN_MASK; + if (def != data) + WREG32_PCIE(smnPCIE_LC_CNTL6, data); + + nbio_v2_3_program_ltr(adev); + + def = data = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP3); + data |= 0x5DE0 << RCC_BIF_STRAP3__STRAP_VLINK_ASPM_IDLE_TIMER__SHIFT; + data |= 0x0010 << RCC_BIF_STRAP3__STRAP_VLINK_PM_L1_ENTRY_TIMER__SHIFT; + if (def != data) + WREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP3, data); + + def = data = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP5); + data |= 0x0010 << RCC_BIF_STRAP5__STRAP_VLINK_LDN_ENTRY_TIMER__SHIFT; + if (def != data) + WREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP5, data); + + def = data = RREG32_PCIE(smnPCIE_LC_CNTL); + data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK; + data |= 0x9 << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; + data |= 0x1 << PCIE_LC_CNTL__LC_PMI_TO_L1_DIS__SHIFT; + if (def != data) + WREG32_PCIE(smnPCIE_LC_CNTL, data); + + def = data = RREG32_PCIE(smnPCIE_LC_CNTL3); + data &= ~PCIE_LC_CNTL3__LC_DSC_DONT_ENTER_L23_AFTER_PME_ACK_MASK; + if (def != data) + WREG32_PCIE(smnPCIE_LC_CNTL3, data); +} + const struct amdgpu_nbio_funcs nbio_v2_3_funcs = { .get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset, .get_hdp_flush_done_offset = nbio_v2_3_get_hdp_flush_done_offset, @@ -370,4 +483,5 @@ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = { .init_registers = nbio_v2_3_init_registers, .remap_hdp_registers = nbio_v2_3_remap_hdp_registers, .enable_aspm = nbio_v2_3_enable_aspm, + .program_aspm = nbio_v2_3_program_aspm, }; diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index 66279f0c6808..59b220d08fc1 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -468,11 +468,14 @@ static void nv_pcie_gen3_enable(struct amdgpu_device *adev) static void nv_program_aspm(struct amdgpu_device *adev) { - - if (amdgpu_aspm == 0) + if (amdgpu_aspm != 1) return; - /* todo */ + if ((adev->asic_type >= CHIP_SIENNA_CICHLID) && + !(adev->flags & AMD_IS_APU) && + (adev->nbio.funcs->program_aspm)) + adev->nbio.funcs->program_aspm(adev); + } static void nv_enable_doorbell_aperture(struct amdgpu_device *adev, @@ -798,10 +801,10 @@ static int nv_update_umd_stable_pstate(struct amdgpu_device *adev, * The ASPM function is not fully enabled and verified on * Navi yet. Temporarily skip this until ASPM enabled. */ -#if 0 - if (adev->nbio.funcs->enable_aspm) + if ((adev->asic_type >= CHIP_SIENNA_CICHLID) && + !(adev->flags & AMD_IS_APU) && + (adev->nbio.funcs->enable_aspm)) adev->nbio.funcs->enable_aspm(adev, !enter); -#endif return 0; } From 2a53291ef2e607d449f60a3f11d1861a9671b8dd Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Wed, 3 Feb 2021 18:21:52 +0800 Subject: [PATCH 13/60] drm/amdgpu: add SMUIO 11.0.6 register headers Signed-off-by: Likun Gao Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- .../asic_reg/smuio/smuio_11_0_6_offset.h | 35 ++++++++++++++++ .../asic_reg/smuio/smuio_11_0_6_sh_mask.h | 41 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_offset.h create mode 100644 drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_sh_mask.h diff --git a/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_offset.h b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_offset.h new file mode 100644 index 000000000000..55facadea54b --- /dev/null +++ b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_offset.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 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) 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 _smuio_11_0_6_OFFSET_HEADER +#define _smuio_11_0_6_OFFSET_HEADER + + + +// addressBlock: smuio_smuio_SmuSmuioDec +// base address: 0x5a000 +#define mmCGTT_ROM_CLK_CTRL0 0x00e4 +#define mmCGTT_ROM_CLK_CTRL0_BASE_IDX 0 +#define mmROM_INDEX 0x00e5 +#define mmROM_INDEX_BASE_IDX 0 +#define mmROM_DATA 0x00e6 +#define mmROM_DATA_BASE_IDX 0 + +#endif diff --git a/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_sh_mask.h new file mode 100644 index 000000000000..7d6a2fac2839 --- /dev/null +++ b/drivers/gpu/drm/amd/include/asic_reg/smuio/smuio_11_0_6_sh_mask.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 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) 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 _smuio_11_0_6_SH_MASK_HEADER +#define _smuio_11_0_6_SH_MASK_HEADER + + +//CGTT_ROM_CLK_CTRL0 +#define CGTT_ROM_CLK_CTRL0__ON_DELAY__SHIFT 0x0 +#define CGTT_ROM_CLK_CTRL0__OFF_HYSTERESIS__SHIFT 0x4 +#define CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1__SHIFT 0x1e +#define CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0__SHIFT 0x1f +#define CGTT_ROM_CLK_CTRL0__ON_DELAY_MASK 0x0000000FL +#define CGTT_ROM_CLK_CTRL0__OFF_HYSTERESIS_MASK 0x00000FF0L +#define CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK 0x40000000L +#define CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK 0x80000000L +//ROM_INDEX +#define ROM_INDEX__ROM_INDEX__SHIFT 0x0 +#define ROM_INDEX__ROM_INDEX_MASK 0x01FFFFFFL +//ROM_DATA +#define ROM_DATA__ROM_DATA__SHIFT 0x0 +#define ROM_DATA__ROM_DATA_MASK 0xFFFFFFFFL + +#endif From 1deb98534c239d4f45e10ebe62eade4f07352d16 Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Wed, 3 Feb 2021 18:16:34 +0800 Subject: [PATCH 14/60] drm/amdgpu: implement smuio v11_0_6 callbacks Implement smuio v11_0_6 callbacks which will used by Sienna_Cichlid and forward ASIC. Signed-off-by: Likun Gao Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/Makefile | 3 +- drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c | 41 ++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.h | 30 ++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c create mode 100644 drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.h diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index f8903abcdb88..13ebb1f71e49 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -171,7 +171,8 @@ amdgpu-y += \ # add SMUIO block amdgpu-y += \ smuio_v9_0.o \ - smuio_v11_0.o + smuio_v11_0.o \ + smuio_v11_0_6.o # add amdkfd interfaces amdgpu-y += amdgpu_amdkfd.o diff --git a/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c b/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c new file mode 100644 index 000000000000..16aef32a6004 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c @@ -0,0 +1,41 @@ +/* + * Copyright 2021 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. + * + */ +#include "amdgpu.h" +#include "smuio_v11_0_6.h" +#include "smuio/smuio_11_0_6_offset.h" +#include "smuio/smuio_11_0_6_sh_mask.h" + +static u32 smuio_v11_0_6_get_rom_index_offset(struct amdgpu_device *adev) +{ + return SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX); +} + +static u32 smuio_v11_0_6_get_rom_data_offset(struct amdgpu_device *adev) +{ + return SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA); +} + +const struct amdgpu_smuio_funcs smuio_v11_0_6_funcs = { + .get_rom_index_offset = smuio_v11_0_6_get_rom_index_offset, + .get_rom_data_offset = smuio_v11_0_6_get_rom_data_offset, +}; diff --git a/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.h b/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.h new file mode 100644 index 000000000000..3c3f4ab0bc9b --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.h @@ -0,0 +1,30 @@ +/* + * Copyright 2021 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 __SMUIO_V11_0_6_H__ +#define __SMUIO_V11_0_6_H__ + +#include "soc15_common.h" + +extern const struct amdgpu_smuio_funcs smuio_v11_0_6_funcs; + +#endif /* __SMUIO_V11_0_6_H__ */ From 0bf7f2dcb9a65dcc9efb47e3a393108499d6a110 Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Wed, 3 Feb 2021 18:23:49 +0800 Subject: [PATCH 15/60] drm/amdgpu: switch to use smuio callbacks for NV family Switch to smuio callbacks: use smuio v11_0_6 callbacks for Sienna_cichlid and forward ASIC, use smuio v11_0 callbacks for the other NV family ASIC. Signed-off-by: Likun Gao Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/nv.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index 59b220d08fc1..c39be4d93817 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -38,7 +38,6 @@ #include "gc/gc_10_1_0_offset.h" #include "gc/gc_10_1_0_sh_mask.h" -#include "smuio/smuio_11_0_0_offset.h" #include "mp/mp_11_0_offset.h" #include "soc15.h" @@ -61,6 +60,8 @@ #include "dce_virtual.h" #include "mes_v10_1.h" #include "mxgpu_nv.h" +#include "smuio_v11_0.h" +#include "smuio_v11_0_6.h" static const struct amd_ip_funcs nv_common_ip_funcs; @@ -202,6 +203,7 @@ static bool nv_read_bios_from_rom(struct amdgpu_device *adev, { u32 *dw_ptr; u32 i, length_dw; + u32 rom_index_offset, rom_data_offset; if (bios == NULL) return false; @@ -214,11 +216,16 @@ static bool nv_read_bios_from_rom(struct amdgpu_device *adev, dw_ptr = (u32 *)bios; length_dw = ALIGN(length_bytes, 4) / 4; + rom_index_offset = + adev->smuio.funcs->get_rom_index_offset(adev); + rom_data_offset = + adev->smuio.funcs->get_rom_data_offset(adev); + /* set rom index to 0 */ - WREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX), 0); + WREG32(rom_index_offset, 0); /* read out the rom data */ for (i = 0; i < length_dw; i++) - dw_ptr[i] = RREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA)); + dw_ptr[i] = RREG32(rom_data_offset); return true; } @@ -564,6 +571,11 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) } adev->hdp.funcs = &hdp_v5_0_funcs; + if (adev->asic_type >= CHIP_SIENNA_CICHLID) + adev->smuio.funcs = &smuio_v11_0_6_funcs; + else + adev->smuio.funcs = &smuio_v11_0_funcs; + if (adev->asic_type == CHIP_SIENNA_CICHLID) adev->gmc.xgmi.supported = true; From 1001f2a1f33dfe88bc7581d0177d01e9d299999c Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Wed, 3 Feb 2021 18:45:42 +0800 Subject: [PATCH 16/60] drm/amdgpu: support rom clockgating related function for NV family Add functions to support enable/disable rom clock gating and get rom clock gating status. Signed-off-by: Likun Gao Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/nv.c | 4 +++ drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c | 36 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index c39be4d93817..efacf5fd8191 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -1144,6 +1144,8 @@ static int nv_common_set_clockgating_state(void *handle, state == AMD_CG_STATE_GATE); adev->hdp.funcs->update_clock_gating(adev, state == AMD_CG_STATE_GATE); + adev->smuio.funcs->update_rom_clock_gating(adev, + state == AMD_CG_STATE_GATE); break; default: break; @@ -1169,6 +1171,8 @@ static void nv_common_get_clockgating_state(void *handle, u32 *flags) adev->hdp.funcs->get_clock_gating_state(adev, flags); + adev->smuio.funcs->get_clock_gating_state(adev, flags); + return; } diff --git a/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c b/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c index 16aef32a6004..3a18dbb55c32 100644 --- a/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c +++ b/drivers/gpu/drm/amd/amdgpu/smuio_v11_0_6.c @@ -35,7 +35,43 @@ static u32 smuio_v11_0_6_get_rom_data_offset(struct amdgpu_device *adev) return SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA); } +static void smuio_v11_0_6_update_rom_clock_gating(struct amdgpu_device *adev, bool enable) +{ + u32 def, data; + + /* enable/disable ROM CG is not supported on APU */ + if (adev->flags & AMD_IS_APU) + return; + + def = data = RREG32_SOC15(SMUIO, 0, mmCGTT_ROM_CLK_CTRL0); + + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_ROM_MGCG)) + data &= ~(CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK | + CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK); + else + data |= CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK | + CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK; + + if (def != data) + WREG32_SOC15(SMUIO, 0, mmCGTT_ROM_CLK_CTRL0, data); +} + +static void smuio_v11_0_6_get_clock_gating_state(struct amdgpu_device *adev, u32 *flags) +{ + u32 data; + + /* CGTT_ROM_CLK_CTRL0 is not available for APU */ + if (adev->flags & AMD_IS_APU) + return; + + data = RREG32_SOC15(SMUIO, 0, mmCGTT_ROM_CLK_CTRL0); + if (!(data & CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK)) + *flags |= AMD_CG_SUPPORT_ROM_MGCG; +} + const struct amdgpu_smuio_funcs smuio_v11_0_6_funcs = { .get_rom_index_offset = smuio_v11_0_6_get_rom_index_offset, .get_rom_data_offset = smuio_v11_0_6_get_rom_data_offset, + .update_rom_clock_gating = smuio_v11_0_6_update_rom_clock_gating, + .get_clock_gating_state = smuio_v11_0_6_get_clock_gating_state, }; From de4b7cd8cb87c12559e0545d9c9c631cb2e8ee6f Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Wed, 3 Feb 2021 17:20:51 +0800 Subject: [PATCH 17/60] drm/amd/pm/swsmu: unify the init soft gpu metrics function the soft gpu metrics is not asic related data structure. unify them to reduce duplicate code. Signed-off-by: Kevin Wang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 4 --- drivers/gpu/drm/amd/pm/inc/smu_v12_0.h | 2 -- .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 4 ++- .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 4 ++- .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 4 ++- .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 24 ---------------- .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 4 ++- .../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 4 ++- .../gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c | 12 -------- drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 28 +++++++++++++++++++ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 2 ++ 11 files changed, 45 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h index c7d57e9555cc..e49c2d08a983 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h @@ -272,10 +272,6 @@ int smu_v11_0_get_current_pcie_link_speed_level(struct smu_context *smu); int smu_v11_0_get_current_pcie_link_speed(struct smu_context *smu); -void smu_v11_0_init_gpu_metrics_v1_0(struct gpu_metrics_v1_0 *gpu_metrics); - -void smu_v11_0_init_gpu_metrics_v2_0(struct gpu_metrics_v2_0 *gpu_metrics); - int smu_v11_0_gfx_ulv_control(struct smu_context *smu, bool enablement); diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v12_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v12_0.h index fa2e8cb07967..02de3b6199e5 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v12_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v12_0.h @@ -60,7 +60,5 @@ int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_ int smu_v12_0_set_driver_table_location(struct smu_context *smu); -void smu_v12_0_init_gpu_metrics_v2_0(struct gpu_metrics_v2_0 *gpu_metrics); - #endif #endif 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 f0cc4de9ced5..45564a776e9b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -2239,7 +2239,7 @@ static ssize_t arcturus_get_gpu_metrics(struct smu_context *smu, if (ret) return ret; - smu_v11_0_init_gpu_metrics_v1_0(gpu_metrics); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 0); gpu_metrics->temperature_edge = metrics.TemperatureEdge; gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; @@ -2276,6 +2276,8 @@ static ssize_t arcturus_get_gpu_metrics(struct smu_context *smu, gpu_metrics->pcie_link_speed = arcturus_get_current_pcie_link_speed(smu); + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + *table = (void *)gpu_metrics; return sizeof(struct gpu_metrics_v1_0); 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 f7f78daffd27..6e641f1513d8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -2314,7 +2314,7 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, mutex_unlock(&smu->metrics_lock); - smu_v11_0_init_gpu_metrics_v1_0(gpu_metrics); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 0); gpu_metrics->temperature_edge = metrics.TemperatureEdge; gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; @@ -2354,6 +2354,8 @@ static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, gpu_metrics->pcie_link_speed = smu_v11_0_get_current_pcie_link_speed(smu); + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + *table = (void *)gpu_metrics; return sizeof(struct gpu_metrics_v1_0); 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 fd090d057d26..b9e47f3b0231 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 @@ -2958,7 +2958,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, if (ret) return ret; - smu_v11_0_init_gpu_metrics_v1_0(gpu_metrics); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 0); gpu_metrics->temperature_edge = metrics->TemperatureEdge; gpu_metrics->temperature_hotspot = metrics->TemperatureHotspot; @@ -3001,6 +3001,8 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, gpu_metrics->pcie_link_speed = smu_v11_0_get_current_pcie_link_speed(smu); + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + *table = (void *)gpu_metrics; return sizeof(struct gpu_metrics_v1_0); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index cf6176afd4d5..36d651342a76 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -2021,30 +2021,6 @@ int smu_v11_0_get_current_pcie_link_speed(struct smu_context *smu) return link_speed[speed_level]; } -void smu_v11_0_init_gpu_metrics_v1_0(struct gpu_metrics_v1_0 *gpu_metrics) -{ - memset(gpu_metrics, 0xFF, sizeof(struct gpu_metrics_v1_0)); - - gpu_metrics->common_header.structure_size = - sizeof(struct gpu_metrics_v1_0); - gpu_metrics->common_header.format_revision = 1; - gpu_metrics->common_header.content_revision = 0; - - gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); -} - -void smu_v11_0_init_gpu_metrics_v2_0(struct gpu_metrics_v2_0 *gpu_metrics) -{ - memset(gpu_metrics, 0xFF, sizeof(struct gpu_metrics_v2_0)); - - gpu_metrics->common_header.structure_size = - sizeof(struct gpu_metrics_v2_0); - gpu_metrics->common_header.format_revision = 2; - gpu_metrics->common_header.content_revision = 0; - - gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); -} - int smu_v11_0_gfx_ulv_control(struct smu_context *smu, bool enablement) { 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 f0f06ef47b9e..42271e80c0b4 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -1406,7 +1406,7 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, if (ret) return ret; - smu_v11_0_init_gpu_metrics_v2_0(gpu_metrics); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 0); gpu_metrics->temperature_gfx = metrics.GfxTemperature; gpu_metrics->temperature_soc = metrics.SocTemperature; @@ -1442,6 +1442,8 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, gpu_metrics->throttle_status = metrics.ThrottlerStatus; + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + *table = (void *)gpu_metrics; return sizeof(struct gpu_metrics_v2_0); 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 f6844b90ca67..cde0ff87e281 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1257,7 +1257,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu, if (ret) return ret; - smu_v12_0_init_gpu_metrics_v2_0(gpu_metrics); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 0); gpu_metrics->temperature_gfx = metrics.GfxTemperature; gpu_metrics->temperature_soc = metrics.SocTemperature; @@ -1298,6 +1298,8 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu, gpu_metrics->fan_pwm = metrics.FanPwm; + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + *table = (void *)gpu_metrics; return sizeof(struct gpu_metrics_v2_0); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c index 06abf2a7ce9e..6cc4855c8a37 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c @@ -278,15 +278,3 @@ int smu_v12_0_set_driver_table_location(struct smu_context *smu) return ret; } - -void smu_v12_0_init_gpu_metrics_v2_0(struct gpu_metrics_v2_0 *gpu_metrics) -{ - memset(gpu_metrics, 0xFF, sizeof(struct gpu_metrics_v2_0)); - - gpu_metrics->common_header.structure_size = - sizeof(struct gpu_metrics_v2_0); - gpu_metrics->common_header.format_revision = 2; - gpu_metrics->common_header.content_revision = 0; - - 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 d9ecaa04d14e..bb620fdd4cd2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -746,3 +746,31 @@ int smu_cmn_get_metrics_table(struct smu_context *smu, return ret; } + +void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev) +{ + struct metrics_table_header *header = (struct metrics_table_header *)table; + uint16_t structure_size; + +#define METRICS_VERSION(a, b) ((a << 16) | b ) + + switch (METRICS_VERSION(frev, crev)) { + case METRICS_VERSION(1, 0): + structure_size = sizeof(struct gpu_metrics_v1_0); + break; + case METRICS_VERSION(2, 0): + structure_size = sizeof(struct gpu_metrics_v2_0); + break; + default: + break; + } + +#undef METRICS_VERSION + + memset(header, 0xFF, structure_size); + + header->format_revision = frev; + header->content_revision = crev; + header->structure_size = structure_size; + +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index 08ccf2d3257c..c69250185575 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -97,5 +97,7 @@ int smu_cmn_get_metrics_table(struct smu_context *smu, void *metrics_table, bool bypass_cache); +void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev); + #endif #endif From be8901c2ee3a16f8a28c0c165c2766643a84acb8 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Wed, 3 Feb 2021 17:36:51 +0800 Subject: [PATCH 18/60] drm/amdgpu: optimize list operation in amdgpu_xgmi simplify the list operation. Signed-off-by: Kevin Wang Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 541ef6be390f..659b385b27b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -324,7 +324,7 @@ static void amdgpu_xgmi_sysfs_rem_dev_info(struct amdgpu_device *adev, struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) { - struct amdgpu_hive_info *hive = NULL, *tmp = NULL; + struct amdgpu_hive_info *hive = NULL; int ret; if (!adev->gmc.xgmi.hive_id) @@ -337,11 +337,9 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) mutex_lock(&xgmi_mutex); - if (!list_empty(&xgmi_hive_list)) { - list_for_each_entry_safe(hive, tmp, &xgmi_hive_list, node) { - if (hive->hive_id == adev->gmc.xgmi.hive_id) - goto pro_end; - } + list_for_each_entry(hive, &xgmi_hive_list, node) { + if (hive->hive_id == adev->gmc.xgmi.hive_id) + goto pro_end; } hive = kzalloc(sizeof(*hive), GFP_KERNEL); From 11f1a5538ba5f1c4462c806560a343b5258f22b8 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Fri, 29 Jan 2021 14:06:16 +0800 Subject: [PATCH 19/60] drm/amdgpu: Add otg vertical IRQ Source [Why & How] In order to get appropriate timing for registers which read/write is vertical line sensitive, add new IRQ source variable. This interrupt is triggered by specific vertical line, Signed-off-by: Wayne Lin Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index f4ff8ddb52d4..dbf8c8a0878c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -891,6 +891,7 @@ struct amdgpu_device { /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ struct work_struct hotplug_work; struct amdgpu_irq_src crtc_irq; + struct amdgpu_irq_src vline0_irq; struct amdgpu_irq_src vupdate_irq; struct amdgpu_irq_src pageflip_irq; struct amdgpu_irq_src hpd_irq; From 320eca62fe61ca1efded0d2a95392e4f20e53b46 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Wed, 20 Jan 2021 17:22:30 +0800 Subject: [PATCH 20/60] drm/amd/display: Add otg vertical interrupt0 support in DCN1.0 [Why & How] On DCN1.0, need otg vertical line interrupt to get appropriate timing to achieve specific feature request. Add otg vertical interrupt0 support for registers which operation is vertical sensitive. Signed-off-by: Wayne Lin Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 22 +++++++++++++ .../display/dc/irq/dcn10/irq_service_dcn10.c | 31 +++++++++++++++++++ drivers/gpu/drm/amd/display/dc/irq_types.h | 1 + 3 files changed, 54 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 26ed70e5538a..e0000c180ed1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -662,6 +662,20 @@ static int amdgpu_dm_set_crtc_irq_state(struct amdgpu_device *adev, __func__); } +static int amdgpu_dm_set_vline0_irq_state(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + unsigned int crtc_id, + enum amdgpu_interrupt_state state) +{ + return dm_irq_state( + adev, + source, + crtc_id, + state, + IRQ_TYPE_VLINE0, + __func__); +} + static int amdgpu_dm_set_vupdate_irq_state(struct amdgpu_device *adev, struct amdgpu_irq_src *source, unsigned int crtc_id, @@ -681,6 +695,11 @@ static const struct amdgpu_irq_src_funcs dm_crtc_irq_funcs = { .process = amdgpu_dm_irq_handler, }; +static const struct amdgpu_irq_src_funcs dm_vline0_irq_funcs = { + .set = amdgpu_dm_set_vline0_irq_state, + .process = amdgpu_dm_irq_handler, +}; + static const struct amdgpu_irq_src_funcs dm_vupdate_irq_funcs = { .set = amdgpu_dm_set_vupdate_irq_state, .process = amdgpu_dm_irq_handler, @@ -702,6 +721,9 @@ void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev) adev->crtc_irq.num_types = adev->mode_info.num_crtc; adev->crtc_irq.funcs = &dm_crtc_irq_funcs; + adev->vline0_irq.num_types = adev->mode_info.num_crtc; + adev->vline0_irq.funcs = &dm_vline0_irq_funcs; + adev->vupdate_irq.num_types = adev->mode_info.num_crtc; adev->vupdate_irq.funcs = &dm_vupdate_irq_funcs; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c index f956b3bde680..34f43cb650f8 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c @@ -58,6 +58,18 @@ enum dc_irq_source to_dal_irq_source_dcn10( return DC_IRQ_SOURCE_VBLANK5; case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP: return DC_IRQ_SOURCE_VBLANK6; + case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC1_VLINE0; + case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC2_VLINE0; + case DCN_1_0__SRCID__OTG3_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC3_VLINE0; + case DCN_1_0__SRCID__OTG4_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC4_VLINE0; + case DCN_1_0__SRCID__OTG5_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC5_VLINE0; + case DCN_1_0__SRCID__OTG6_VERTICAL_INTERRUPT0_CONTROL: + return DC_IRQ_SOURCE_DC6_VLINE0; case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT: return DC_IRQ_SOURCE_VUPDATE1; case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT: @@ -167,6 +179,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vline0_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { .set = NULL, .ack = NULL @@ -241,6 +258,14 @@ static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { .funcs = &vblank_irq_info_funcs\ } +#define vline0_int_entry(reg_num)\ + [DC_IRQ_SOURCE_DC1_VLINE0 + reg_num] = {\ + IRQ_REG_ENTRY(OTG, reg_num,\ + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE,\ + OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_CLEAR),\ + .funcs = &vline0_irq_info_funcs\ + } + #define dummy_irq_entry() \ {\ .funcs = &dummy_irq_info_funcs\ @@ -349,6 +374,12 @@ irq_source_info_dcn10[DAL_IRQ_SOURCES_NUMBER] = { vblank_int_entry(3), vblank_int_entry(4), vblank_int_entry(5), + vline0_int_entry(0), + vline0_int_entry(1), + vline0_int_entry(2), + vline0_int_entry(3), + vline0_int_entry(4), + vline0_int_entry(5), }; static const struct irq_service_funcs irq_service_funcs_dcn10 = { diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h index d0ccd81ad5b4..87812d81fed3 100644 --- a/drivers/gpu/drm/amd/display/dc/irq_types.h +++ b/drivers/gpu/drm/amd/display/dc/irq_types.h @@ -160,6 +160,7 @@ enum irq_type IRQ_TYPE_PFLIP = DC_IRQ_SOURCE_PFLIP1, IRQ_TYPE_VUPDATE = DC_IRQ_SOURCE_VUPDATE1, IRQ_TYPE_VBLANK = DC_IRQ_SOURCE_VBLANK1, + IRQ_TYPE_VLINE0 = DC_IRQ_SOURCE_DC1_VLINE0, }; #define DAL_VALID_IRQ_SRC_NUM(src) \ From f8bf64501873ab750166200a698f3b0cc6983a65 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 3 Feb 2021 13:02:59 +0100 Subject: [PATCH 21/60] drm/amdgpu: enable wave limit on non high prio cs pipes To achieve the best QoS for high priority compute jobs it is required to limit waves on other compute pipes as well. This patch will set min value in non high priority mmSPI_WCL_PIPE_PERCENT_CS[0-3] registers to minimize the impact of normal/low priority compute jobs over high priority compute jobs. Signed-off-by: Nirmoy Das Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 50 ++++++++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 46 +++++++++++++++++++++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index bdfd29a22b3d..84d2eaa38101 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -6846,10 +6846,45 @@ static void gfx_v8_0_emit_mem_sync_compute(struct amdgpu_ring *ring) amdgpu_ring_write(ring, 0x0000000A); /* poll interval */ } + +/* mmSPI_WCL_PIPE_PERCENT_CS[0-7]_DEFAULT values are same */ +#define mmSPI_WCL_PIPE_PERCENT_CS_DEFAULT 0x0000007f +static void gfx_v8_0_emit_wave_limit_cs(struct amdgpu_ring *ring, + uint32_t pipe, bool enable) +{ + uint32_t val; + uint32_t wcl_cs_reg; + + val = enable ? 0x1 : mmSPI_WCL_PIPE_PERCENT_CS_DEFAULT; + + switch (pipe) { + case 0: + wcl_cs_reg = mmSPI_WCL_PIPE_PERCENT_CS0; + break; + case 1: + wcl_cs_reg = mmSPI_WCL_PIPE_PERCENT_CS1; + break; + case 2: + wcl_cs_reg = mmSPI_WCL_PIPE_PERCENT_CS2; + break; + case 3: + wcl_cs_reg = mmSPI_WCL_PIPE_PERCENT_CS3; + break; + default: + DRM_DEBUG("invalid pipe %d\n", pipe); + return; + } + + amdgpu_ring_emit_wreg(ring, wcl_cs_reg, val); + +} + #define mmSPI_WCL_PIPE_PERCENT_GFX_DEFAULT 0x07ffffff static void gfx_v8_0_emit_wave_limit(struct amdgpu_ring *ring, bool enable) { + struct amdgpu_device *adev = ring->adev; uint32_t val; + int i; /* mmSPI_WCL_PIPE_PERCENT_GFX is 7 bit multiplier register to limit * number of gfx waves. Setting 5 bit will make sure gfx only gets @@ -6857,6 +6892,18 @@ static void gfx_v8_0_emit_wave_limit(struct amdgpu_ring *ring, bool enable) */ val = enable ? 0x1f : mmSPI_WCL_PIPE_PERCENT_GFX_DEFAULT; amdgpu_ring_emit_wreg(ring, mmSPI_WCL_PIPE_PERCENT_GFX, val); + + /* Restrict waves for normal/low priority compute queues as well + * to get best QoS for high priority compute jobs. + * + * amdgpu controls only 1st ME(0-3 CS pipes). + */ + for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++) { + if (i != ring->pipe) + gfx_v8_0_emit_wave_limit_cs(ring, i, enable); + + } + } static const struct amd_ip_funcs gfx_v8_0_ip_funcs = { @@ -6943,7 +6990,8 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { VI_FLUSH_GPU_TLB_NUM_WREG * 5 + 7 + /* gfx_v8_0_ring_emit_vm_flush */ 7 + 7 + 7 + /* gfx_v8_0_ring_emit_fence_compute x3 for user fence, vm fence */ 7 + /* gfx_v8_0_emit_mem_sync_compute */ - 5, /* gfx_v8_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */ + 5 + /* gfx_v8_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */ + 15, /* for updating 3 mmSPI_WCL_PIPE_PERCENT_CS registers */ .emit_ib_size = 7, /* gfx_v8_0_ring_emit_ib_compute */ .emit_ib = gfx_v8_0_ring_emit_ib_compute, .emit_fence = gfx_v8_0_ring_emit_fence_compute, diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 027997e95e46..65db88bb6cbc 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -6668,10 +6668,42 @@ static void gfx_v9_0_emit_mem_sync(struct amdgpu_ring *ring) amdgpu_ring_write(ring, 0x0000000A); /* POLL_INTERVAL */ } +static void gfx_v9_0_emit_wave_limit_cs(struct amdgpu_ring *ring, + uint32_t pipe, bool enable) +{ + struct amdgpu_device *adev = ring->adev; + uint32_t val; + uint32_t wcl_cs_reg; + + /* mmSPI_WCL_PIPE_PERCENT_CS[0-7]_DEFAULT values are same */ + val = enable ? 0x1 : mmSPI_WCL_PIPE_PERCENT_CS0_DEFAULT; + + switch (pipe) { + case 0: + wcl_cs_reg = SOC15_REG_OFFSET(GC, 0, mmSPI_WCL_PIPE_PERCENT_CS0); + break; + case 1: + wcl_cs_reg = SOC15_REG_OFFSET(GC, 0, mmSPI_WCL_PIPE_PERCENT_CS1); + break; + case 2: + wcl_cs_reg = SOC15_REG_OFFSET(GC, 0, mmSPI_WCL_PIPE_PERCENT_CS2); + break; + case 3: + wcl_cs_reg = SOC15_REG_OFFSET(GC, 0, mmSPI_WCL_PIPE_PERCENT_CS3); + break; + default: + DRM_DEBUG("invalid pipe %d\n", pipe); + return; + } + + amdgpu_ring_emit_wreg(ring, wcl_cs_reg, val); + +} static void gfx_v9_0_emit_wave_limit(struct amdgpu_ring *ring, bool enable) { struct amdgpu_device *adev = ring->adev; uint32_t val; + int i; /* mmSPI_WCL_PIPE_PERCENT_GFX is 7 bit multiplier register to limit @@ -6682,6 +6714,17 @@ static void gfx_v9_0_emit_wave_limit(struct amdgpu_ring *ring, bool enable) amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(GC, 0, mmSPI_WCL_PIPE_PERCENT_GFX), val); + + /* Restrict waves for normal/low priority compute queues as well + * to get best QoS for high priority compute jobs. + * + * amdgpu controls only 1st ME(0-3 CS pipes). + */ + for (i = 0; i < adev->gfx.mec.num_pipe_per_mec; i++) { + if (i != ring->pipe) + gfx_v9_0_emit_wave_limit_cs(ring, i, enable); + + } } static const struct amd_ip_funcs gfx_v9_0_ip_funcs = { @@ -6774,7 +6817,8 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = { 2 + /* gfx_v9_0_ring_emit_vm_flush */ 8 + 8 + 8 + /* gfx_v9_0_ring_emit_fence x3 for user fence, vm fence */ 7 + /* gfx_v9_0_emit_mem_sync */ - 5, /* gfx_v9_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */ + 5 + /* gfx_v9_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */ + 15, /* for updating 3 mmSPI_WCL_PIPE_PERCENT_CS registers */ .emit_ib_size = 7, /* gfx_v9_0_ring_emit_ib_compute */ .emit_ib = gfx_v9_0_ring_emit_ib_compute, .emit_fence = gfx_v9_0_ring_emit_fence, From b36c1024dc32bf5aa2c2d5b0b4701bb4ff2b8842 Mon Sep 17 00:00:00 2001 From: Xiaomeng Hou Date: Wed, 20 Jan 2021 14:45:12 +0800 Subject: [PATCH 22/60] drm/amd/pm: update the smu v11.5 smc header for vangogh Add PP messages for reading/setting Fast PPT and Slow PPT limit. Signed-off-by: Xiaomeng Hou Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/inc/smu_types.h | 4 ++++ drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/inc/smu_types.h b/drivers/gpu/drm/amd/pm/inc/smu_types.h index 68c87d4b1ce3..aa4822202587 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_types.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_types.h @@ -210,6 +210,10 @@ __SMU_DUMMY_MAP(DisallowGpo), \ __SMU_DUMMY_MAP(Enable2ndUSB20Port), \ __SMU_DUMMY_MAP(RequestActiveWgp), \ + __SMU_DUMMY_MAP(SetFastPPTLimit), \ + __SMU_DUMMY_MAP(SetSlowPPTLimit), \ + __SMU_DUMMY_MAP(GetFastPPTLimit), \ + __SMU_DUMMY_MAP(GetSlowPPTLimit), \ #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) SMU_MSG_##type diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h index 55d7892e4e0e..fe130a497d6c 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_5_ppsmc.h @@ -104,7 +104,11 @@ #define PPSMC_MSG_DramLogSetDramBufferSize 0x46 #define PPSMC_MSG_RequestActiveWgp 0x47 #define PPSMC_MSG_QueryActiveWgp 0x48 -#define PPSMC_Message_Count 0x49 +#define PPSMC_MSG_SetFastPPTLimit 0x49 +#define PPSMC_MSG_SetSlowPPTLimit 0x4A +#define PPSMC_MSG_GetFastPPTLimit 0x4B +#define PPSMC_MSG_GetSlowPPTLimit 0x4C +#define PPSMC_Message_Count 0x4D //Argument for PPSMC_MSG_GfxDeviceDriverReset enum { From 52d720b1a8003609d89950f721f431c7eea1ac0e Mon Sep 17 00:00:00 2001 From: Xiaomeng Hou Date: Fri, 5 Feb 2021 18:51:13 +0800 Subject: [PATCH 23/60] drm/amd/pm: modify the power limit level parameter from bool to enum type The original smu_get_power_limit callback accepts the power limit level parameter as bool which limits to max and current. For possible needs to retrieve other level like min, extend the parameter type using enum. Signed-off-by: Xiaomeng Hou Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 4 ++-- drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 9 ++++++++- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 13 +++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index cf475ac01b27..39899e7989a2 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -3073,7 +3073,7 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev, } if (is_support_sw_smu(adev)) { - smu_get_power_limit(&adev->smu, &limit, true); + smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_MAX); size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); } else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) { adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true); @@ -3107,7 +3107,7 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev, } if (is_support_sw_smu(adev)) { - smu_get_power_limit(&adev->smu, &limit, false); + smu_get_power_limit(&adev->smu, &limit, SMU_PPT_LIMIT_CURRENT); size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); } else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) { adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false); diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h index 44279c2afccb..82a5f4a4faf5 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h @@ -161,6 +161,13 @@ enum smu_power_src_type SMU_POWER_SOURCE_COUNT, }; +enum smu_ppt_limit_level +{ + SMU_PPT_LIMIT_MIN = -1, + SMU_PPT_LIMIT_CURRENT, + SMU_PPT_LIMIT_MAX, +}; + enum smu_memory_pool_size { SMU_MEMORY_POOL_SIZE_ZERO = 0, @@ -1218,7 +1225,7 @@ int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed); int smu_get_power_limit(struct smu_context *smu, uint32_t *limit, - bool max_setting); + enum smu_ppt_limit_level limit_level); int smu_set_power_limit(struct smu_context *smu, uint32_t limit); int smu_print_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf); diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index c00f3f531965..9017024642bb 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2044,14 +2044,23 @@ int smu_set_fan_speed_rpm(struct smu_context *smu, uint32_t speed) int smu_get_power_limit(struct smu_context *smu, uint32_t *limit, - bool max_setting) + enum smu_ppt_limit_level limit_level) { if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; mutex_lock(&smu->mutex); - *limit = (max_setting ? smu->max_power_limit : smu->current_power_limit); + switch (limit_level) { + case SMU_PPT_LIMIT_CURRENT: + *limit = smu->current_power_limit; + break; + case SMU_PPT_LIMIT_MAX: + *limit = smu->max_power_limit; + break; + default: + break; + } mutex_unlock(&smu->mutex); From ae07970a0621d67a8bc0dc5b44e3fc652bd2ba20 Mon Sep 17 00:00:00 2001 From: Xiaomeng Hou Date: Mon, 25 Jan 2021 15:59:14 +0800 Subject: [PATCH 24/60] drm/amd/pm: add support for hwmon control of slow and fast PPT limit on vangogh Implement hwmon API for reading/setting slow and fast PPT limit. APU power is managed to system-level requirements through the PPT (package power tracking) feature. PPT is intended to limit power to the requirements of the power source and could be dynamically updated to maximize APU performance within the system power budget. Here FAST_PPT_LIMIT manages the ~10 ms moving average of APU power, while SLOW_PPT_LIMIT manages the configurable, thermally significant moving average of APU power (default ~5000 ms). User could read slow/fast ppt limit using command "cat power*_cap" or "sensors" in the hwmon device directory. User could adjust values of slow/fast ppt limit as needed depending on workloads through command "echo ## > power*_cap". Example: $ echo 15000000 > power1_cap $ echo 18000000 > power2_cap $ sensors amdgpu-pci-0300 Adapter: PCI adapter slowPPT: 9.04W (cap = 15.00 W) fastPPT: 9.04W (cap = 18.00 W) v2: align with existing interfaces for the getting/setting of PPT limits. Encode the upper 8 bits of limit value to distinguish slow and fast power limit type. Signed-off-by: Xiaomeng Hou Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 45 ++++++- drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 12 ++ drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 9 ++ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 61 ++++++---- .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 8 +- .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 113 ++++++++++++++++++ 6 files changed, 217 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 39899e7989a2..5fa65f191a37 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -3059,7 +3059,8 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev, char *buf) { struct amdgpu_device *adev = dev_get_drvdata(dev); - uint32_t limit = 0; + int limit_type = to_sensor_dev_attr(attr)->index; + uint32_t limit = limit_type << 24; ssize_t size; int r; @@ -3093,7 +3094,8 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev, char *buf) { struct amdgpu_device *adev = dev_get_drvdata(dev); - uint32_t limit = 0; + int limit_type = to_sensor_dev_attr(attr)->index; + uint32_t limit = limit_type << 24; ssize_t size; int r; @@ -3122,6 +3124,15 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev, return size; } +static ssize_t amdgpu_hwmon_show_power_label(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int limit_type = to_sensor_dev_attr(attr)->index; + + return snprintf(buf, PAGE_SIZE, "%s\n", + limit_type == SMU_FAST_PPT_LIMIT ? "fastPPT" : "slowPPT"); +} static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev, struct device_attribute *attr, @@ -3129,6 +3140,7 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev, size_t count) { struct amdgpu_device *adev = dev_get_drvdata(dev); + int limit_type = to_sensor_dev_attr(attr)->index; int err; u32 value; @@ -3143,7 +3155,7 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev, return err; value = value / 1000000; /* convert to Watt */ - + value |= limit_type << 24; err = pm_runtime_get_sync(adev_to_drm(adev)->dev); if (err < 0) { @@ -3355,6 +3367,12 @@ static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, 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); +static SENSOR_DEVICE_ATTR(power1_label, S_IRUGO, amdgpu_hwmon_show_power_label, NULL, 0); +static SENSOR_DEVICE_ATTR(power2_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 1); +static SENSOR_DEVICE_ATTR(power2_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 1); +static SENSOR_DEVICE_ATTR(power2_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 1); +static SENSOR_DEVICE_ATTR(power2_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 1); +static SENSOR_DEVICE_ATTR(power2_label, S_IRUGO, amdgpu_hwmon_show_power_label, NULL, 1); static SENSOR_DEVICE_ATTR(freq1_input, S_IRUGO, amdgpu_hwmon_show_sclk, NULL, 0); static SENSOR_DEVICE_ATTR(freq1_label, S_IRUGO, amdgpu_hwmon_show_sclk_label, NULL, 0); static SENSOR_DEVICE_ATTR(freq2_input, S_IRUGO, amdgpu_hwmon_show_mclk, NULL, 0); @@ -3393,6 +3411,12 @@ static struct attribute *hwmon_attributes[] = { &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, + &sensor_dev_attr_power1_label.dev_attr.attr, + &sensor_dev_attr_power2_average.dev_attr.attr, + &sensor_dev_attr_power2_cap_max.dev_attr.attr, + &sensor_dev_attr_power2_cap_min.dev_attr.attr, + &sensor_dev_attr_power2_cap.dev_attr.attr, + &sensor_dev_attr_power2_label.dev_attr.attr, &sensor_dev_attr_freq1_input.dev_attr.attr, &sensor_dev_attr_freq1_label.dev_attr.attr, &sensor_dev_attr_freq2_input.dev_attr.attr, @@ -3485,8 +3509,9 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, effective_mode &= ~S_IWUSR; } - if (((adev->flags & AMD_IS_APU) || - adev->family == AMDGPU_FAMILY_SI) && /* not implemented yet */ + if (((adev->family == AMDGPU_FAMILY_SI) || + ((adev->flags & AMD_IS_APU) && + (adev->asic_type != CHIP_VANGOGH))) && /* not implemented yet */ (attr == &sensor_dev_attr_power1_cap_max.dev_attr.attr || attr == &sensor_dev_attr_power1_cap_min.dev_attr.attr|| attr == &sensor_dev_attr_power1_cap.dev_attr.attr)) @@ -3549,6 +3574,16 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, attr == &sensor_dev_attr_temp3_label.dev_attr.attr)) return 0; + /* only Vangogh has fast PPT limit and power labels */ + if (!(adev->asic_type == CHIP_VANGOGH) && + (attr == &sensor_dev_attr_power2_average.dev_attr.attr || + attr == &sensor_dev_attr_power2_cap_max.dev_attr.attr || + attr == &sensor_dev_attr_power2_cap_min.dev_attr.attr || + attr == &sensor_dev_attr_power2_cap.dev_attr.attr || + attr == &sensor_dev_attr_power2_label.dev_attr.attr || + attr == &sensor_dev_attr_power1_label.dev_attr.attr)) + return 0; + return effective_mode; } diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h index 82a5f4a4faf5..10b0624ade65 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h @@ -161,6 +161,12 @@ enum smu_power_src_type SMU_POWER_SOURCE_COUNT, }; +enum smu_ppt_limit_type +{ + SMU_DEFAULT_PPT_LIMIT = 0, + SMU_FAST_PPT_LIMIT, +}; + enum smu_ppt_limit_level { SMU_PPT_LIMIT_MIN = -1, @@ -708,6 +714,12 @@ struct pptable_funcs { */ int (*get_power_limit)(struct smu_context *smu); + /** + * @get_ppt_limit: Get the device's ppt limits. + */ + int (*get_ppt_limit)(struct smu_context *smu, uint32_t *ppt_limit, + enum smu_ppt_limit_type limit_type, enum smu_ppt_limit_level limit_level); + /** * @set_df_cstate: Set data fabric cstate. */ diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h index e49c2d08a983..d4cddd2390a2 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h @@ -129,6 +129,15 @@ struct smu_11_0_power_context { enum smu_11_0_power_state power_state; }; +struct smu_11_5_power_context { + uint32_t power_source; + uint8_t in_power_limit_boost_mode; + enum smu_11_0_power_state power_state; + + uint32_t current_fast_ppt_limit; + uint32_t max_fast_ppt_limit; +}; + enum smu_v11_0_baco_seq { BACO_SEQ_BACO = 0, BACO_SEQ_MSR, diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 9017024642bb..d143ef1b460b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -2046,29 +2046,7 @@ int smu_get_power_limit(struct smu_context *smu, uint32_t *limit, enum smu_ppt_limit_level limit_level) { - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) - return -EOPNOTSUPP; - - mutex_lock(&smu->mutex); - - switch (limit_level) { - case SMU_PPT_LIMIT_CURRENT: - *limit = smu->current_power_limit; - break; - case SMU_PPT_LIMIT_MAX: - *limit = smu->max_power_limit; - break; - default: - break; - } - - mutex_unlock(&smu->mutex); - - return 0; -} - -int smu_set_power_limit(struct smu_context *smu, uint32_t limit) -{ + uint32_t limit_type = *limit >> 24; int ret = 0; if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) @@ -2076,6 +2054,43 @@ int smu_set_power_limit(struct smu_context *smu, uint32_t limit) mutex_lock(&smu->mutex); + if (limit_type != SMU_DEFAULT_PPT_LIMIT) { + if (smu->ppt_funcs->get_ppt_limit) + ret = smu->ppt_funcs->get_ppt_limit(smu, limit, limit_type, limit_level); + } else { + switch (limit_level) { + case SMU_PPT_LIMIT_CURRENT: + *limit = smu->current_power_limit; + break; + case SMU_PPT_LIMIT_MAX: + *limit = smu->max_power_limit; + break; + default: + break; + } + } + + mutex_unlock(&smu->mutex); + + return ret; +} + +int smu_set_power_limit(struct smu_context *smu, uint32_t limit) +{ + uint32_t limit_type = limit >> 24; + int ret = 0; + + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) + return -EOPNOTSUPP; + + mutex_lock(&smu->mutex); + + if (limit_type != SMU_DEFAULT_PPT_LIMIT) + if (smu->ppt_funcs->set_power_limit) { + ret = smu->ppt_funcs->set_power_limit(smu, limit); + goto out; + } + if (limit > smu->max_power_limit) { dev_err(smu->adev->dev, "New power limit (%d) is over the max allowed %d\n", diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index 36d651342a76..90585461a56e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -474,12 +474,14 @@ int smu_v11_0_fini_smc_tables(struct smu_context *smu) int smu_v11_0_init_power(struct smu_context *smu) { struct smu_power_context *smu_power = &smu->smu_power; + size_t size = smu->adev->asic_type == CHIP_VANGOGH ? + sizeof(struct smu_11_5_power_context) : + sizeof(struct smu_11_0_power_context); - smu_power->power_context = kzalloc(sizeof(struct smu_11_0_power_context), - GFP_KERNEL); + smu_power->power_context = kzalloc(size, GFP_KERNEL); if (!smu_power->power_context) return -ENOMEM; - smu_power->power_context_size = sizeof(struct smu_11_0_power_context); + smu_power->power_context_size = size; return 0; } 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 42271e80c0b4..3277014b5881 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -122,6 +122,10 @@ static struct cmn2asic_msg_mapping vangogh_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(SetSoftMinCclk, PPSMC_MSG_SetSoftMinCclk, 0), MSG_MAP(SetSoftMaxCclk, PPSMC_MSG_SetSoftMaxCclk, 0), MSG_MAP(RequestActiveWgp, PPSMC_MSG_RequestActiveWgp, 0), + MSG_MAP(SetFastPPTLimit, PPSMC_MSG_SetFastPPTLimit, 0), + MSG_MAP(SetSlowPPTLimit, PPSMC_MSG_SetSlowPPTLimit, 0), + MSG_MAP(GetFastPPTLimit, PPSMC_MSG_GetFastPPTLimit, 0), + MSG_MAP(GetSlowPPTLimit, PPSMC_MSG_GetSlowPPTLimit, 0), }; static struct cmn2asic_mapping vangogh_feature_mask_map[SMU_FEATURE_COUNT] = { @@ -1773,6 +1777,112 @@ static int vangogh_mode2_reset(struct smu_context *smu) return vangogh_mode_reset(smu, SMU_RESET_MODE_2); } +static int vangogh_get_power_limit(struct smu_context *smu) +{ + struct smu_11_5_power_context *power_context = + smu->smu_power.power_context; + uint32_t ppt_limit; + int ret = 0; + + if (smu->adev->pm.fw_version < 0x43f1e00) + return ret; + + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetSlowPPTLimit, &ppt_limit); + if (ret) { + dev_err(smu->adev->dev, "Get slow PPT limit failed!\n"); + return ret; + } + /* convert from milliwatt to watt */ + smu->current_power_limit = ppt_limit / 1000; + smu->max_power_limit = 29; + + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPPTLimit, &ppt_limit); + if (ret) { + dev_err(smu->adev->dev, "Get fast PPT limit failed!\n"); + return ret; + } + /* convert from milliwatt to watt */ + power_context->current_fast_ppt_limit = ppt_limit / 1000; + power_context->max_fast_ppt_limit = 30; + + return ret; +} + +static int vangogh_get_ppt_limit(struct smu_context *smu, + uint32_t *ppt_limit, + enum smu_ppt_limit_type type, + enum smu_ppt_limit_level level) +{ + struct smu_11_5_power_context *power_context = + smu->smu_power.power_context; + + if (!power_context) + return -EOPNOTSUPP; + + if (type == SMU_FAST_PPT_LIMIT) { + switch (level) { + case SMU_PPT_LIMIT_MAX: + *ppt_limit = power_context->max_fast_ppt_limit; + break; + case SMU_PPT_LIMIT_CURRENT: + *ppt_limit = power_context->current_fast_ppt_limit; + break; + default: + break; + } + } + + return 0; +} + +static int vangogh_set_power_limit(struct smu_context *smu, uint32_t ppt_limit) +{ + struct smu_11_5_power_context *power_context = + smu->smu_power.power_context; + uint32_t limit_type = ppt_limit >> 24; + int ret = 0; + + if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { + dev_err(smu->adev->dev, "Setting new power limit is not supported!\n"); + return -EOPNOTSUPP; + } + + switch (limit_type) { + case SMU_DEFAULT_PPT_LIMIT: + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetSlowPPTLimit, + ppt_limit * 1000, /* convert from watt to milliwatt */ + NULL); + if (ret) + return ret; + + smu->current_power_limit = ppt_limit; + break; + case SMU_FAST_PPT_LIMIT: + ppt_limit &= ~(SMU_FAST_PPT_LIMIT << 24); + if (ppt_limit > power_context->max_fast_ppt_limit) { + dev_err(smu->adev->dev, + "New power limit (%d) is over the max allowed %d\n", + ppt_limit, power_context->max_fast_ppt_limit); + return ret; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetFastPPTLimit, + ppt_limit * 1000, /* convert from watt to milliwatt */ + NULL); + if (ret) + return ret; + + power_context->current_fast_ppt_limit = ppt_limit; + break; + default: + return -EINVAL; + } + + return ret; +} + static const struct pptable_funcs vangogh_ppt_funcs = { .check_fw_status = smu_v11_0_check_fw_status, @@ -1809,6 +1919,9 @@ static const struct pptable_funcs vangogh_ppt_funcs = { .post_init = vangogh_post_smu_init, .mode2_reset = vangogh_mode2_reset, .gfx_off_control = smu_v11_0_gfx_off_control, + .get_ppt_limit = vangogh_get_ppt_limit, + .get_power_limit = vangogh_get_power_limit, + .set_power_limit = vangogh_set_power_limit, }; void vangogh_set_ppt_funcs(struct smu_context *smu) From 25bd55276b5ab4d27312749849cae42415eebfb5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 10:31:38 -0500 Subject: [PATCH 25/60] drm/amdgpu/si: minor clean up of reset code Drop duplicate reset method logging, whitespace changes. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/si.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index 3cf0589bfea5..75422764b2d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c @@ -1270,7 +1270,7 @@ static int si_gpu_pci_config_reset(struct amdgpu_device *adev) u32 i; int r = -EINVAL; - dev_info(adev->dev, "GPU pci config reset\n"); + amdgpu_atombios_scratch_regs_engine_hung(adev, true); /* set mclk/sclk to bypass */ si_set_clk_bypass_mode(adev); @@ -1294,6 +1294,7 @@ static int si_gpu_pci_config_reset(struct amdgpu_device *adev) } udelay(1); } + amdgpu_atombios_scratch_regs_engine_hung(adev, false); return r; } @@ -1304,12 +1305,8 @@ static int si_asic_reset(struct amdgpu_device *adev) dev_info(adev->dev, "PCI CONFIG reset\n"); - amdgpu_atombios_scratch_regs_engine_hung(adev, true); - r = si_gpu_pci_config_reset(adev); - amdgpu_atombios_scratch_regs_engine_hung(adev, false); - return r; } From 44ab8bb0bb63feedd59afdda83218a608fd9780a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 10:38:13 -0500 Subject: [PATCH 26/60] drm/amdgpu/cik: minor clean up of reset code Drop duplicate reset method logging, whitespace changes. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/cik.c | 33 +++++++++++--------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 13737b317f7c..4d6832cc7fb0 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -1251,13 +1251,22 @@ static void kv_restore_regs_for_reset(struct amdgpu_device *adev, WREG32(mmGMCON_RENG_EXECUTE, save->gmcon_reng_execute); } -static int cik_gpu_pci_config_reset(struct amdgpu_device *adev) +/** + * cik_asic_pci_config_reset - soft reset GPU + * + * @adev: amdgpu_device pointer + * + * Use PCI Config method to reset the GPU. + * + * Returns 0 for success. + */ +static int cik_asic_pci_config_reset(struct amdgpu_device *adev) { struct kv_reset_save_regs kv_save = { 0 }; u32 i; int r = -EINVAL; - dev_info(adev->dev, "GPU pci config reset\n"); + amdgpu_atombios_scratch_regs_engine_hung(adev, true); if (adev->flags & AMD_IS_APU) kv_save_regs_for_reset(adev, &kv_save); @@ -1285,26 +1294,6 @@ static int cik_gpu_pci_config_reset(struct amdgpu_device *adev) if (adev->flags & AMD_IS_APU) kv_restore_regs_for_reset(adev, &kv_save); - return r; -} - -/** - * cik_asic_pci_config_reset - soft reset GPU - * - * @adev: amdgpu_device pointer - * - * Use PCI Config method to reset the GPU. - * - * Returns 0 for success. - */ -static int cik_asic_pci_config_reset(struct amdgpu_device *adev) -{ - int r; - - amdgpu_atombios_scratch_regs_engine_hung(adev, true); - - r = cik_gpu_pci_config_reset(adev); - amdgpu_atombios_scratch_regs_engine_hung(adev, false); return r; From d5ab066917a5438459e5464fd17432685a2aedc7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 10:45:40 -0500 Subject: [PATCH 27/60] drm/amdgpu/vi: minor clean up of reset code Drop duplicate reset method logging, whitespace changes. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vi.c | 36 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index d56b474b3a21..eafb76aebd00 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -642,11 +642,21 @@ static int vi_read_register(struct amdgpu_device *adev, u32 se_num, return -EINVAL; } -static int vi_gpu_pci_config_reset(struct amdgpu_device *adev) +/** + * vi_asic_pci_config_reset - soft reset GPU + * + * @adev: amdgpu_device pointer + * + * Use PCI Config method to reset the GPU. + * + * Returns 0 for success. + */ +static int vi_asic_pci_config_reset(struct amdgpu_device *adev) { u32 i; + int r = -EINVAL; - dev_info(adev->dev, "GPU pci config reset\n"); + amdgpu_atombios_scratch_regs_engine_hung(adev, true); /* disable BM */ pci_clear_master(adev->pdev); @@ -661,29 +671,11 @@ static int vi_gpu_pci_config_reset(struct amdgpu_device *adev) /* enable BM */ pci_set_master(adev->pdev); adev->has_hw_reset = true; - return 0; + r = 0; + break; } udelay(1); } - return -EINVAL; -} - -/** - * vi_asic_pci_config_reset - soft reset GPU - * - * @adev: amdgpu_device pointer - * - * Use PCI Config method to reset the GPU. - * - * Returns 0 for success. - */ -static int vi_asic_pci_config_reset(struct amdgpu_device *adev) -{ - int r; - - amdgpu_atombios_scratch_regs_engine_hung(adev, true); - - r = vi_gpu_pci_config_reset(adev); amdgpu_atombios_scratch_regs_engine_hung(adev, false); From af484df800e356725c39f52e7cbe8b47f1753453 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 10:29:19 -0500 Subject: [PATCH 28/60] drm/amdgpu: add generic pci reset as an option This allows us to use generic PCI reset mechanisms (FLR, SBR) as a reset mechanism to verify that the generic PCI reset mechanisms are working properly. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 ++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index dbf8c8a0878c..9717cb43eb26 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -579,7 +579,8 @@ enum amd_reset_method { AMD_RESET_METHOD_MODE0, AMD_RESET_METHOD_MODE1, AMD_RESET_METHOD_MODE2, - AMD_RESET_METHOD_BACO + AMD_RESET_METHOD_BACO, + AMD_RESET_METHOD_PCI, }; /* @@ -1228,6 +1229,7 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev); int amdgpu_device_gpu_recover(struct amdgpu_device *adev, struct amdgpu_job* job); void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); +int amdgpu_device_pci_reset(struct amdgpu_device *adev); bool amdgpu_device_need_post(struct amdgpu_device *adev); void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 51bea409e513..e6a72a7fc311 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -929,6 +929,18 @@ void amdgpu_device_pci_config_reset(struct amdgpu_device *adev) pci_write_config_dword(adev->pdev, 0x7c, AMDGPU_ASIC_RESET_DATA); } +/** + * amdgpu_device_pci_reset - reset the GPU using generic PCI means + * + * @adev: amdgpu_device pointer + * + * Resets the GPU using generic pci reset interfaces (FLR, SBR, etc.). + */ +int amdgpu_device_pci_reset(struct amdgpu_device *adev) +{ + return pci_reset_function(adev->pdev); +} + /* * GPU doorbell aperture helpers function. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 9173da34dd22..80c46f648d5c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -793,9 +793,9 @@ module_param_named(tmz, amdgpu_tmz, int, 0444); /** * DOC: reset_method (int) - * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco) + * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco, 5 = pci) */ -MODULE_PARM_DESC(reset_method, "GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco/bamaco)"); +MODULE_PARM_DESC(reset_method, "GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco/bamaco, 5 = pci)"); module_param_named(reset_method, amdgpu_reset_method, int, 0444); /** From ffbfd081b47cf4b23dc6e2923534ad8984fe6ec6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 11:13:53 -0500 Subject: [PATCH 29/60] drm/amdgpu/si: add PCI reset support Use generic PCI reset for GPU reset if the user specifies PCI reset as the reset mechanism. This should in general only be used for validation. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/si.c | 37 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index 75422764b2d3..6b5cf7882a12 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c @@ -1299,17 +1299,6 @@ static int si_gpu_pci_config_reset(struct amdgpu_device *adev) return r; } -static int si_asic_reset(struct amdgpu_device *adev) -{ - int r; - - dev_info(adev->dev, "PCI CONFIG reset\n"); - - r = si_gpu_pci_config_reset(adev); - - return r; -} - static bool si_asic_supports_baco(struct amdgpu_device *adev) { return false; @@ -1318,14 +1307,34 @@ static bool si_asic_supports_baco(struct amdgpu_device *adev) static enum amd_reset_method si_asic_reset_method(struct amdgpu_device *adev) { - if (amdgpu_reset_method != AMD_RESET_METHOD_LEGACY && - amdgpu_reset_method != -1) + if (amdgpu_reset_method == AMD_RESET_METHOD_PCI) + return amdgpu_reset_method; + else if (amdgpu_reset_method != AMD_RESET_METHOD_LEGACY && + amdgpu_reset_method != -1) dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", - amdgpu_reset_method); + amdgpu_reset_method); return AMD_RESET_METHOD_LEGACY; } +static int si_asic_reset(struct amdgpu_device *adev) +{ + int r; + + switch (si_asic_reset_method(adev)) { + case AMD_RESET_METHOD_PCI: + dev_info(adev->dev, "PCI reset\n"); + r = amdgpu_device_pci_reset(adev); + break; + default: + dev_info(adev->dev, "PCI CONFIG reset\n"); + r = si_gpu_pci_config_reset(adev); + break; + } + + return r; +} + static u32 si_get_config_memsize(struct amdgpu_device *adev) { return RREG32(mmCONFIG_MEMSIZE); From 1176a1e0b9d50255d733a1e04c039405a3ab5948 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 11:24:49 -0500 Subject: [PATCH 30/60] drm/amdgpu/soc15: add PCI reset support Use generic PCI reset for GPU reset if the user specifies PCI reset as the reset mechanism. This should in general only be used for validation. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 2396be16c28e..e865495d3ead 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -479,7 +479,8 @@ soc15_asic_reset_method(struct amdgpu_device *adev) if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 || amdgpu_reset_method == AMD_RESET_METHOD_MODE2 || - amdgpu_reset_method == AMD_RESET_METHOD_BACO) + amdgpu_reset_method == AMD_RESET_METHOD_BACO || + amdgpu_reset_method == AMD_RESET_METHOD_PCI) return amdgpu_reset_method; if (amdgpu_reset_method != -1) @@ -524,15 +525,18 @@ static int soc15_asic_reset(struct amdgpu_device *adev) return 0; switch (soc15_asic_reset_method(adev)) { - case AMD_RESET_METHOD_BACO: - dev_info(adev->dev, "BACO reset\n"); - return soc15_asic_baco_reset(adev); - case AMD_RESET_METHOD_MODE2: - dev_info(adev->dev, "MODE2 reset\n"); - return amdgpu_dpm_mode2_reset(adev); - default: - dev_info(adev->dev, "MODE1 reset\n"); - return soc15_asic_mode1_reset(adev); + case AMD_RESET_METHOD_PCI: + dev_info(adev->dev, "PCI reset\n"); + return amdgpu_device_pci_reset(adev); + case AMD_RESET_METHOD_BACO: + dev_info(adev->dev, "BACO reset\n"); + return soc15_asic_baco_reset(adev); + case AMD_RESET_METHOD_MODE2: + dev_info(adev->dev, "MODE2 reset\n"); + return amdgpu_dpm_mode2_reset(adev); + default: + dev_info(adev->dev, "MODE1 reset\n"); + return soc15_asic_mode1_reset(adev); } } From f172865a3632b85f29c2af9b044f4dd51581740f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 11:24:00 -0500 Subject: [PATCH 31/60] drm/amdgpu/nv: add PCI reset support Use generic PCI reset for GPU reset if the user specifies PCI reset as the reset mechanism. This should in general only be used for validation. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/nv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index efacf5fd8191..160fa5f59805 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -391,7 +391,8 @@ nv_asic_reset_method(struct amdgpu_device *adev) if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 || amdgpu_reset_method == AMD_RESET_METHOD_MODE2 || - amdgpu_reset_method == AMD_RESET_METHOD_BACO) + amdgpu_reset_method == AMD_RESET_METHOD_BACO || + amdgpu_reset_method == AMD_RESET_METHOD_PCI) return amdgpu_reset_method; if (amdgpu_reset_method != -1) @@ -423,6 +424,10 @@ static int nv_asic_reset(struct amdgpu_device *adev) return 0; switch (nv_asic_reset_method(adev)) { + case AMD_RESET_METHOD_PCI: + dev_info(adev->dev, "PCI reset\n"); + ret = amdgpu_device_pci_reset(adev); + break; case AMD_RESET_METHOD_BACO: dev_info(adev->dev, "BACO reset\n"); From a8d3d80a8ca3df47a846937809fc1e1d8e8fbce2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 09:11:14 -0500 Subject: [PATCH 32/60] drm/amdgpu: drop extra drm_kms_helper_poll_enable/disable calls These are already called in amdgpu_device_suspend/resume which are already called in the same functions. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 -- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e6a72a7fc311..0ee6514ee55c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1445,10 +1445,8 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, amdgpu_device_resume(dev, true); dev->switch_power_state = DRM_SWITCH_POWER_ON; - drm_kms_helper_poll_enable(dev); } else { pr_info("switched off\n"); - drm_kms_helper_poll_disable(dev); dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; amdgpu_device_suspend(dev, true); amdgpu_device_cache_pci_state(pdev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 80c46f648d5c..0b07cc15ebdd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1348,7 +1348,6 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev) adev->in_runpm = true; if (amdgpu_device_supports_atpx(drm_dev)) drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - drm_kms_helper_poll_disable(drm_dev); ret = amdgpu_device_suspend(drm_dev, false); if (ret) @@ -1405,7 +1404,6 @@ static int amdgpu_pmops_runtime_resume(struct device *dev) amdgpu_device_baco_exit(drm_dev); } ret = amdgpu_device_resume(drm_dev, false); - drm_kms_helper_poll_enable(drm_dev); if (amdgpu_device_supports_atpx(drm_dev)) drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; adev->in_runpm = false; From ad887af9b6d0d5d7866a3953563fb0fee7556ea8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 09:29:08 -0500 Subject: [PATCH 33/60] drm/amdgpu: use runpm flag rather than fbcon for kfd runtime suspend (v2) the flag used by kfd is not actually related to fbcon, it just happens to align. Use the runpm flag instead so that we can decouple it from the fbcon flag. v2: fix resume as well Reviewed-by: Felix Kuehling Reviewed-by: Rajneesh Bhardwaj Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0ee6514ee55c..b7ebd424bbc7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3734,7 +3734,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) r = amdgpu_device_ip_suspend_phase1(adev); - amdgpu_amdkfd_suspend(adev, !fbcon); + amdgpu_amdkfd_suspend(adev, adev->in_runpm); /* evict vram memory */ amdgpu_bo_evict_vram(adev); @@ -3818,7 +3818,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) } } } - r = amdgpu_amdkfd_resume(adev, !fbcon); + r = amdgpu_amdkfd_resume(adev, adev->in_runpm); if (r) return r; From cef8b03bbc0b727e1ef9e45d612a6487a7063205 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 4 Feb 2021 09:32:17 -0500 Subject: [PATCH 34/60] drm/amdgpu: reset runpm flag if device suspend fails If device suspend fails when we attempt to runtime suspend, reset the runpm flag. Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 0b07cc15ebdd..03c529630c21 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1350,8 +1350,10 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev) drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; ret = amdgpu_device_suspend(drm_dev, false); - if (ret) + if (ret) { + adev->in_runpm = false; return ret; + } if (amdgpu_device_supports_atpx(drm_dev)) { /* Only need to handle PCI state in the driver for ATPX From 6ef28889b413448eccde1776d79dd093c3106118 Mon Sep 17 00:00:00 2001 From: Kenneth Feng Date: Sun, 7 Feb 2021 09:51:44 +0800 Subject: [PATCH 35/60] drm/amd/pm: enable LCLK DS Enable LCLK deep sleep and it works if we enable ASPM: modprobe amdgpu aspm=1 Signed-off-by: Kenneth Feng Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 3 +++ 1 file changed, 3 insertions(+) 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 b9e47f3b0231..af73e1430af5 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 @@ -302,6 +302,9 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu, if (smu->dc_controlled_by_gpio) *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ACDC_BIT); + if (amdgpu_aspm == 1) + *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_LCLK_BIT); + return 0; } From 27859ee3df9761a944535e45a96098027450808c Mon Sep 17 00:00:00 2001 From: Tao Zhou Date: Fri, 5 Feb 2021 14:22:23 +0800 Subject: [PATCH 36/60] drm/amdgpu: enable gpu recovery for dimgrey_cavefish As dimgrey_cavefish driver is stable enough, set gpu recovery as default in HW hang for dimgrey_cavefish. Signed-off-by: Tao Zhou Reviewed-by: Jiansong Chen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b7ebd424bbc7..7052dc35d278 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4221,6 +4221,7 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev) case CHIP_NAVI12: case CHIP_SIENNA_CICHLID: case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: break; default: goto disabled; From bd0c064c161c4bbfe69b50851c10955a9066deff Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Tue, 19 Jan 2021 16:52:57 -0500 Subject: [PATCH 37/60] drm/amd/display: Add return code instead of boolean for future use Signed-off-by: Fangzhi Zuo Reviewed-by: Mikita Lipski Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 3244a6ea7a65..5159399f8239 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 @@ -526,11 +526,11 @@ bool dm_helpers_submit_i2c( bool dm_helpers_dp_write_dsc_enable( struct dc_context *ctx, const struct dc_stream_state *stream, - bool enable -) + bool enable) { uint8_t enable_dsc = enable ? 1 : 0; struct amdgpu_dm_connector *aconnector; + uint8_t ret; if (!stream) return false; @@ -541,13 +541,13 @@ bool dm_helpers_dp_write_dsc_enable( if (!aconnector->dsc_aux) return false; - return (drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1) >= 0); + ret = drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1); } if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT) return dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1); - return false; + return (ret > 0); } bool dm_helpers_is_dp_sink_present(struct dc_link *link) From 166590ccb92c9805045b94b6ee53edd166de2bcd Mon Sep 17 00:00:00 2001 From: Derek Lai Date: Tue, 26 Jan 2021 10:42:45 +0800 Subject: [PATCH 38/60] drm/amd/display: Add DIG_CLOCK_PATTERN in the transmitter control [Why and How] VBIOS program DIG_CLK_PATTERN using engine ID instead of PHY ID. Workaround by writing value for 0x1f (for HDMI) after calling vbios. Signed-off-by: Derek Lai Reviewed-by: Tony Cheng Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 15 +++++++++++++++ .../drm/amd/display/dc/dcn10/dcn10_link_encoder.h | 11 +++++++++++ .../drm/amd/display/dc/dcn20/dcn20_link_encoder.c | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index 81db0179f7ea..59024653430c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -956,6 +956,21 @@ void dcn10_link_encoder_enable_tmds_output( } } +void dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa( + struct link_encoder *enc, + enum clock_source_id clock_source, + enum dc_color_depth color_depth, + enum signal_type signal, + uint32_t pixel_clock) +{ + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); + + dcn10_link_encoder_enable_tmds_output( + enc, clock_source, color_depth, signal, pixel_clock); + + REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F); +} + /* enables DP PHY output */ void dcn10_link_encoder_enable_dp_output( struct link_encoder *enc, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h index d4caad670855..3e1a582e4b88 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h @@ -42,6 +42,7 @@ #define LE_DCN_COMMON_REG_LIST(id) \ SRI(DIG_BE_CNTL, DIG, id), \ SRI(DIG_BE_EN_CNTL, DIG, id), \ + SRI(DIG_CLOCK_PATTERN, DIG, id), \ SRI(TMDS_CTL_BITS, DIG, id), \ SRI(DP_CONFIG, DP, id), \ SRI(DP_DPHY_CNTL, DP, id), \ @@ -83,6 +84,7 @@ struct dcn10_link_enc_hpd_registers { struct dcn10_link_enc_registers { uint32_t DIG_BE_CNTL; uint32_t DIG_BE_EN_CNTL; + uint32_t DIG_CLOCK_PATTERN; uint32_t DP_CONFIG; uint32_t DP_DPHY_CNTL; uint32_t DP_DPHY_INTERNAL_CTRL; @@ -168,6 +170,7 @@ struct dcn10_link_enc_registers { LE_SF(DIG0_DIG_BE_CNTL, DIG_HPD_SELECT, mask_sh),\ LE_SF(DIG0_DIG_BE_CNTL, DIG_MODE, mask_sh),\ LE_SF(DIG0_DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, mask_sh),\ + LE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh),\ LE_SF(DIG0_TMDS_CTL_BITS, TMDS_CTL0, mask_sh), \ LE_SF(DP0_DP_DPHY_CNTL, DPHY_BYPASS, mask_sh),\ LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE0, mask_sh),\ @@ -218,6 +221,7 @@ struct dcn10_link_enc_registers { type DIG_HPD_SELECT;\ type DIG_MODE;\ type DIG_FE_SOURCE_SELECT;\ + type DIG_CLOCK_PATTERN;\ type DPHY_BYPASS;\ type DPHY_ATEST_SEL_LANE0;\ type DPHY_ATEST_SEL_LANE1;\ @@ -536,6 +540,13 @@ void dcn10_link_encoder_enable_tmds_output( enum signal_type signal, uint32_t pixel_clock); +void dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa( + struct link_encoder *enc, + enum clock_source_id clock_source, + enum dc_color_depth color_depth, + enum signal_type signal, + uint32_t pixel_clock); + /* enables DP PHY output */ void dcn10_link_encoder_enable_dp_output( struct link_encoder *enc, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c index 15c2ff264ff6..fa013496e26b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c @@ -363,7 +363,7 @@ static const struct link_encoder_funcs dcn20_link_enc_funcs = { dcn10_link_encoder_validate_output_with_stream, .hw_init = enc2_hw_init, .setup = dcn10_link_encoder_setup, - .enable_tmds_output = dcn10_link_encoder_enable_tmds_output, + .enable_tmds_output = dcn10_link_encoder_enable_tmds_output_with_clk_pattern_wa, .enable_dp_output = dcn20_link_encoder_enable_dp_output, .enable_dp_mst_output = dcn10_link_encoder_enable_dp_mst_output, .disable_output = dcn10_link_encoder_disable_output, From 765ff7ad584aef2f0aaadb153b0c496bd4e170f7 Mon Sep 17 00:00:00 2001 From: Qingqing Zhuo Date: Fri, 22 Jan 2021 19:16:25 -0500 Subject: [PATCH 39/60] drm/amd/display: DP HDCP Compliance 1A-08/09 tests fail [Why] Current implementation of mod_hdcp_hdcp2_validate_ake_cert() does not process HDCP status message TA_HDCP2_MSG_AUTHENTICATION_STATUS__SIGNATURE_CERTIFICAT_ERROR. As a result, when there is a signature certificate error, mod_hdcp_hdcp2_validate_ake_cert would return the default status, which is success. [How] For all messages other than TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS and TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED, return status as failure. Signed-off-by: Qingqing Zhuo Reviewed-by: Bhawanpreet Lakha Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c index b26ed64eaf98..904ce9b88088 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -548,6 +548,8 @@ enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp) TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) { hdcp->connection.is_hdcp2_revoked = 1; status = MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED; + } else { + status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE; } } mutex_unlock(&psp->hdcp_context.mutex); From b14e4f200461cc820c63dd112acc21e1a60aa90e Mon Sep 17 00:00:00 2001 From: Jun Lei Date: Tue, 26 Jan 2021 09:23:02 -0500 Subject: [PATCH 40/60] drm/amd/display: revert support for DID2.0 dsc passthrough 3x4K60 displays over MST with DSC enabled was not able to light up due to this patch. Signed-off-by: Jun Lei Reviewed-by: Anthony Koo Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dsc.h | 7 ++--- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 1 - drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 29 ++++++++------------ 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h index e99273bff46d..ec55b77727d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h @@ -51,7 +51,6 @@ struct dc_dsc_policy { int min_slice_height; // Must not be less than 8 uint32_t max_target_bpp; uint32_t min_target_bpp; - uint32_t preferred_bpp_x16; bool enable_dsc_when_not_needed; }; @@ -63,8 +62,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, bool dc_dsc_compute_bandwidth_range( const struct display_stream_compressor *dsc, uint32_t dsc_min_slice_height_override, - uint32_t min_bpp_x16, - uint32_t max_bpp_x16, + uint32_t min_bpp, + uint32_t max_bpp, const struct dsc_dec_dpcd_caps *dsc_sink_caps, const struct dc_crtc_timing *timing, struct dc_dsc_bw_range *range); @@ -79,7 +78,7 @@ bool dc_dsc_compute_config( struct dc_dsc_config *dsc_cfg); void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, - uint32_t max_target_bpp_limit_override_x16, + uint32_t max_target_bpp_limit_override, struct dc_dsc_policy *policy); void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit); diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index 09e8be5f7a1e..b41e6367b15e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -769,7 +769,6 @@ struct dc_crtc_timing { #endif struct dc_crtc_timing_flags flags; - uint32_t dsc_fixed_bits_per_pixel_x16; /* DSC target bitrate in 1/16 of bpp (e.g. 128 -> 8bpp) */ struct dc_dsc_config dsc_cfg; }; diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index 82a805088204..c62d0eddc9c6 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -369,11 +369,6 @@ static bool decide_dsc_target_bpp_x16( /* enough bandwidth without dsc */ *target_bpp_x16 = 0; should_use_dsc = false; - } else if (policy->preferred_bpp_x16 > 0 && - policy->preferred_bpp_x16 <= range.max_target_bpp_x16 && - policy->preferred_bpp_x16 >= range.min_target_bpp_x16) { - *target_bpp_x16 = policy->preferred_bpp_x16; - should_use_dsc = true; } else if (target_bandwidth_kbps >= range.max_kbps) { /* use max target bpp allowed */ *target_bpp_x16 = range.max_target_bpp_x16; @@ -550,7 +545,7 @@ static bool setup_dsc_config( int target_bandwidth_kbps, const struct dc_crtc_timing *timing, int min_slice_height_override, - int max_dsc_target_bpp_limit_override_x16, + int max_dsc_target_bpp_limit_override, struct dc_dsc_config *dsc_cfg) { struct dsc_enc_caps dsc_common_caps; @@ -569,7 +564,7 @@ static bool setup_dsc_config( memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); - dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override_x16, &policy); + dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override, &policy); pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right; pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; @@ -870,8 +865,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, const uint8_t *dpcd_dsc_basic_da bool dc_dsc_compute_bandwidth_range( const struct display_stream_compressor *dsc, uint32_t dsc_min_slice_height_override, - uint32_t min_bpp_x16, - uint32_t max_bpp_x16, + uint32_t min_bpp, + uint32_t max_bpp, const struct dsc_dec_dpcd_caps *dsc_sink_caps, const struct dc_crtc_timing *timing, struct dc_dsc_bw_range *range) @@ -888,10 +883,10 @@ bool dc_dsc_compute_bandwidth_range( if (is_dsc_possible) is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing, - dsc_min_slice_height_override, max_bpp_x16, &config); + dsc_min_slice_height_override, max_bpp, &config); if (is_dsc_possible) - get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, &dsc_common_caps, timing, range); + get_dsc_bandwidth_range(min_bpp, max_bpp, &dsc_common_caps, timing, range); return is_dsc_possible; } @@ -900,7 +895,7 @@ bool dc_dsc_compute_config( const struct display_stream_compressor *dsc, const struct dsc_dec_dpcd_caps *dsc_sink_caps, uint32_t dsc_min_slice_height_override, - uint32_t max_target_bpp_limit_override_x16, + uint32_t max_target_bpp_limit_override, uint32_t target_bandwidth_kbps, const struct dc_crtc_timing *timing, struct dc_dsc_config *dsc_cfg) @@ -913,11 +908,11 @@ bool dc_dsc_compute_config( &dsc_enc_caps, target_bandwidth_kbps, timing, dsc_min_slice_height_override, - max_target_bpp_limit_override_x16, dsc_cfg); + max_target_bpp_limit_override, dsc_cfg); return is_dsc_possible; } -void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override_x16, struct dc_dsc_policy *policy) +void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override, struct dc_dsc_policy *policy) { uint32_t bpc = 0; @@ -972,15 +967,13 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t return; } - policy->preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16; - /* internal upper limit, default 16 bpp */ if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit) policy->max_target_bpp = dsc_policy_max_target_bpp_limit; /* apply override */ - if (max_target_bpp_limit_override_x16 && policy->max_target_bpp > max_target_bpp_limit_override_x16 / 16) - policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16; + if (max_target_bpp_limit_override && policy->max_target_bpp > max_target_bpp_limit_override) + policy->max_target_bpp = max_target_bpp_limit_override; /* enable DSC when not needed, default false */ if (dsc_policy_enable_dsc_when_not_needed) From 6fce5bcee582809b63b14a853ab2efed7a4f5c2e Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Fri, 22 Jan 2021 16:28:14 -0500 Subject: [PATCH 41/60] drm/amd/display: move edp sink present detection to hw init [Why] At SW init, we may not be ready to do detect eDP sink. Signed-off-by: Eric Yang Reviewed-by: Jun Lei Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 40 +++++++++++++----------- drivers/gpu/drm/amd/display/dc/dc_link.h | 2 ++ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 8d5378f53243..c9aede2f783d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -205,27 +205,9 @@ static bool create_links( link = link_create(&link_init_params); if (link) { - bool should_destory_link = false; - - if (link->connector_signal == SIGNAL_TYPE_EDP) { - if (dc->config.edp_not_connected) { - if (!IS_DIAG_DC(dc->ctx->dce_environment)) - should_destory_link = true; - } else { - enum dc_connection_type type; - dc_link_detect_sink(link, &type); - if (type == dc_connection_none) - should_destory_link = true; - } - } - - if (dc->config.force_enum_edp || !should_destory_link) { dc->links[dc->link_count] = link; link->dc = dc; ++dc->link_count; - } else { - link_destroy(&link); - } } } @@ -1016,8 +998,30 @@ struct dc *dc_create(const struct dc_init_data *init_params) return NULL; } +static void detect_edp_presence(struct dc *dc) +{ + struct dc_link *edp_link = get_edp_link(dc); + bool edp_sink_present = true; + + if (!edp_link) + return; + + if (dc->config.edp_not_connected) { + edp_sink_present = false; + } else { + enum dc_connection_type type; + dc_link_detect_sink(edp_link, &type); + if (type == dc_connection_none) + edp_sink_present = false; + } + + edp_link->edp_sink_present = edp_sink_present; +} + void dc_hardware_init(struct dc *dc) { + + detect_edp_presence(dc); if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW) dc->hwss.init_hw(dc); } diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index d5d8f0ad9233..e189f16bc026 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -103,6 +103,8 @@ struct dc_link { bool lttpr_non_transparent_mode; bool is_internal_display; + bool edp_sink_present; + /* caps is the same as reported_link_cap. link_traing use * reported_link_cap. Will clean up. TODO */ From 7a03fdf628af0c66ab2714278f786b7b97a2a1ac Mon Sep 17 00:00:00 2001 From: Lang Yu Date: Wed, 27 Jan 2021 10:32:55 +0800 Subject: [PATCH 42/60] drm/amd/display: fix 64bit division issue on 32bit OS Replace "/" with div_u64 for 64bit division on 32bit OS. Signed-off-by: Lang Yu Reviewed-by: Nicholas Kazlauskas Acked-by: Anson Jacob Acked-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 8506739a22f7..fa5059f71727 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -3688,8 +3688,8 @@ uint32_t dc_link_bandwidth_kbps( * but the difference is minimal and is in a safe direction, * which all works well around potential ambiguity of DP 1.4a spec. */ - link_bw_kbps = mul_u64_u32_shr(BIT_ULL(32) * 970LL / 1000, - link_bw_kbps, 32); + long long fec_link_bw_kbps = link_bw_kbps * 970LL; + link_bw_kbps = (uint32_t)(div64_s64(fec_link_bw_kbps, 1000LL)); } return link_bw_kbps; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index 17ec63253fc3..bc942725b9d8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -240,7 +240,7 @@ static bool calc_fb_divider_checking_tolerance( pll_settings->calculated_pix_clk_100hz = actual_calculated_clock_100hz; pll_settings->vco_freq = - actual_calculated_clock_100hz * post_divider / 10; + div_u64(actual_calculated_clock_100hz * post_divider, 10); return true; } return false; 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 064f158ce671..6505373483bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -3506,7 +3506,8 @@ void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s calculated_states[i].dram_speed_mts = uclk_states[i] * 16 / 1000; // FCLK:UCLK ratio is 1.08 - min_fclk_required_by_uclk = mul_u64_u32_shr(BIT_ULL(32) * 1080 / 1000000, uclk_states[i], 32); + min_fclk_required_by_uclk = div_u64(((unsigned long long)uclk_states[i]) * 1080, + 1000000); calculated_states[i].fabricclk_mhz = (min_fclk_required_by_uclk < min_dcfclk) ? min_dcfclk : min_fclk_required_by_uclk; From 148816f93fa0db19029dc91e09ad7842251fc720 Mon Sep 17 00:00:00 2001 From: Wyatt Wood Date: Mon, 18 Jan 2021 14:51:02 -0500 Subject: [PATCH 43/60] drm/amd/display: Initialize dmub_rb_cmd unions to 0 [Why] Since dmub_rb_cmds are not initialized to 0, the header is filled with invalid data. This is causing issues on the fw side. [How] Initialize dmub_rb_cmd unions to 0. Signed-off-by: Wyatt Wood Reviewed-by: Josip Pavic Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c | 3 +++ drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c | 3 ++- drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 6 +++++- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c | 4 +++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index 0cf130dc4e52..453aaa5757bd 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -57,6 +57,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc) union dmub_rb_cmd cmd; uint32_t fractional_pwm = (dc->dc->config.disable_fractional_pwm == false) ? 1 : 0; + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_pwm_frac.header.type = DMUB_CMD__ABM; cmd.abm_set_pwm_frac.header.sub_type = DMUB_CMD__ABM_SET_PWM_FRAC; cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.fractional_pwm = fractional_pwm; @@ -135,6 +136,7 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level) union dmub_rb_cmd cmd; struct dc_context *dc = abm->ctx; + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_level.header.type = DMUB_CMD__ABM; cmd.abm_set_level.header.sub_type = DMUB_CMD__ABM_SET_LEVEL; cmd.abm_set_level.abm_set_level_data.level = level; @@ -160,6 +162,7 @@ static bool dmub_abm_init_config(struct abm *abm, // Copy iramtable into cw7 memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes); + memset(&cmd, 0, sizeof(cmd)); // Fw will copy from cw7 to fw_state cmd.abm_init_config.header.type = DMUB_CMD__ABM; cmd.abm_init_config.header.sub_type = DMUB_CMD__ABM_INIT_CONFIG; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c index d399270fd17e..c97ee5abc0ef 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c @@ -33,8 +33,9 @@ void dmub_hw_lock_mgr_cmd(struct dc_dmub_srv *dmub_srv, union dmub_hw_lock_flags *hw_locks, struct dmub_hw_lock_inst_flags *inst_flags) { - union dmub_rb_cmd cmd = { 0 }; + union dmub_rb_cmd cmd; + memset(&cmd, 0, sizeof(cmd)); cmd.lock_hw.header.type = DMUB_CMD__HW_LOCK; cmd.lock_hw.header.sub_type = 0; cmd.lock_hw.header.payload_bytes = sizeof(struct dmub_cmd_lock_hw_data); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 4228caa74119..69e34bef274c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -101,6 +101,7 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state * if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED) return false; + memset(&cmd, 0, sizeof(cmd)); cmd.psr_set_version.header.type = DMUB_CMD__PSR; cmd.psr_set_version.header.sub_type = DMUB_CMD__PSR_SET_VERSION; switch (stream->link->psr_settings.psr_version) { @@ -131,7 +132,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait) uint32_t retry_count; enum dc_psr_state state = PSR_STATE0; - + memset(&cmd, 0, sizeof(cmd)); cmd.psr_enable.header.type = DMUB_CMD__PSR; if (enable) @@ -184,6 +185,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level) if (state == PSR_STATE0) return; + memset(&cmd, 0, sizeof(cmd)); cmd.psr_set_level.header.type = DMUB_CMD__PSR; cmd.psr_set_level.header.sub_type = DMUB_CMD__PSR_SET_LEVEL; cmd.psr_set_level.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data); @@ -233,6 +235,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, link->link_enc->funcs->psr_program_secondary_packet(link->link_enc, psr_context->sdpTransmitLineNumDeadline); + memset(&cmd, 0, sizeof(cmd)); cmd.psr_copy_settings.header.type = DMUB_CMD__PSR; cmd.psr_copy_settings.header.sub_type = DMUB_CMD__PSR_COPY_SETTINGS; cmd.psr_copy_settings.header.payload_bytes = sizeof(struct dmub_cmd_psr_copy_settings_data); @@ -285,6 +288,7 @@ static void dmub_psr_force_static(struct dmub_psr *dmub) union dmub_rb_cmd cmd; struct dc_context *dc = dmub->ctx; + memset(&cmd, 0, sizeof(cmd)); cmd.psr_force_static.header.type = DMUB_CMD__PSR; cmd.psr_force_static.header.sub_type = DMUB_CMD__PSR_FORCE_STATIC; cmd.psr_enable.header.payload_bytes = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c index 96ee0b82f458..d3b643089603 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c @@ -123,7 +123,7 @@ void dcn21_optimize_pwr_state( * PHY will hang on the next mode set attempt. * if enable PLL follow by disable PLL (without executing lane enable/disable), * RDPCS_PHY_DP_MPLLB_STATE remains 1, - * which indicate that PLL disable attempt actually didn’t go through. + * which indicate that PLL disable attempt actually didn't go through. * As a workaround, insert PHY lane enable/disable before PLL disable. */ void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx) @@ -143,6 +143,7 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t optio struct dc_context *dc = abm->ctx; uint32_t ramping_boundary = 0xFFFF; + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_pipe.header.type = DMUB_CMD__ABM; cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE; cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst; @@ -212,6 +213,7 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, if (abm && panel_cntl) dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_NORMAL, panel_cntl->inst); + memset(&cmd, 0, sizeof(cmd)); cmd.abm_set_backlight.header.type = DMUB_CMD__ABM; cmd.abm_set_backlight.header.sub_type = DMUB_CMD__ABM_SET_BACKLIGHT; cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp; From 91a51fbf24e2d9e996987c7fadf666152a9f536a Mon Sep 17 00:00:00 2001 From: Wesley Chalmers Date: Fri, 29 Jan 2021 12:37:37 -0500 Subject: [PATCH 44/60] drm/amd/display: DIO Supported for virtual displays [WHY] Virtual displays do not use the backend of the pipe, and so have infinite backend bandwidth. [HOW] Add a skip_dio_check bool to the VBA struct, which is used to override the DIOSupport calculations. Signed-off-by: Wesley Chalmers Reviewed-by: Jun Lei Acked-by: Anson Jacob Acked-by: Chris Park Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 ++ .../gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c | 7 ++++--- .../drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 7 ++++--- .../gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c | 7 ++++--- .../gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c | 2 +- drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h | 1 + drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c | 2 ++ drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h | 1 + 8 files changed, 19 insertions(+), 10 deletions(-) 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 6505373483bb..a0a4ab47a1c0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2097,6 +2097,7 @@ int dcn20_populate_dml_pipes_from_context( pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2; pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst; pipes[pipe_cnt].dout.dp_lanes = 4; + 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])) { @@ -2150,6 +2151,7 @@ int dcn20_populate_dml_pipes_from_context( break; default: /* In case there is no signal, set dp with 4 lanes to allow max config */ + pipes[pipe_cnt].dout.is_virtual = 1; pipes[pipe_cnt].dout.output_type = dm_dp; pipes[pipe_cnt].dout.dp_lanes = 4; } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index f33e3de08176..0f3f510fd83b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -4168,10 +4168,11 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->DIOSupport[i] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - if (locals->OutputBppPerState[i][k] == BPP_INVALID - || (mode_lib->vba.OutputFormat[k] == dm_420 + if (!mode_lib->vba.skip_dio_check[k] + && (locals->OutputBppPerState[i][k] == BPP_INVALID + || (mode_lib->vba.OutputFormat[k] == dm_420 && mode_lib->vba.Interlace[k] == true - && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) { + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) { locals->DIOSupport[i] = false; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c index 47e8e71113ee..210c96cd5b03 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -4289,10 +4289,11 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->DIOSupport[i] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - if (locals->OutputBppPerState[i][k] == BPP_INVALID - || (mode_lib->vba.OutputFormat[k] == dm_420 + if (!mode_lib->vba.skip_dio_check[k] + && (locals->OutputBppPerState[i][k] == BPP_INVALID + || (mode_lib->vba.OutputFormat[k] == dm_420 && mode_lib->vba.Interlace[k] == true - && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) { + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) { locals->DIOSupport[i] = false; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c index 0bcec113ecac..398210d1af34 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c @@ -4257,10 +4257,11 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->DIOSupport[i] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - if (locals->OutputBppPerState[i][k] == BPP_INVALID - || (mode_lib->vba.OutputFormat[k] == dm_420 + if (!mode_lib->vba.skip_dio_check[k] + && (locals->OutputBppPerState[i][k] == BPP_INVALID + || (mode_lib->vba.OutputFormat[k] == dm_420 && mode_lib->vba.Interlace[k] == true - && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) { + && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true))) { locals->DIOSupport[i] = false; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index 8fdb34aa70ff..bc07082c1357 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -4263,7 +4263,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (i = 0; i < v->soc.num_states; i++) { v->DIOSupport[i] = true; for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) { - if (v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi) + if (!v->skip_dio_check[k] && v->BlendingAndTiming[k] == k && (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_hdmi) && (v->OutputBppPerState[i][k] == 0 || (v->OutputFormat[k] == dm_420 && v->Interlace[k] == true && v->ProgressiveToInterlaceUnitInOPP == true))) { v->DIOSupport[i] = false; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index dd0c3b1780d7..0c5128187e08 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -297,6 +297,7 @@ struct _vcs_dpi_display_output_params_st { int num_active_wb; int output_bpc; int output_type; + int is_virtual; int output_format; int dsc_slices; int max_audio_sample_rate; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c index c9fbb33f05a3..bc0485a59018 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c @@ -451,6 +451,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) dout->output_bpp; mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] = (enum output_encoder_class) (dout->output_type); + mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] = + dout->is_virtual; if (!dout->dsc_enable) mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h index 3529fedc4c52..025aa5bd8ea0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h @@ -340,6 +340,7 @@ struct vba_vars_st { unsigned int DSCInputBitPerComponent[DC__NUM_DPP__MAX]; enum output_format_class OutputFormat[DC__NUM_DPP__MAX]; enum output_encoder_class Output[DC__NUM_DPP__MAX]; + bool skip_dio_check[DC__NUM_DPP__MAX]; unsigned int BlendingAndTiming[DC__NUM_DPP__MAX]; bool SynchronizedVBlank; unsigned int NumberOfCursors[DC__NUM_DPP__MAX]; From e75f5634630c10de86df63ce6893cc1165dff108 Mon Sep 17 00:00:00 2001 From: Dale Zhao Date: Wed, 27 Jan 2021 20:04:52 +0800 Subject: [PATCH 45/60] drm/amd/display: fix type mismatch error for return variable It is possible for ret_vsnprintf to be assigned negative value in error cases. As an unsigned variable, negative values which are stored in their 2's complement form gets treated as a positive number. This will led to treating bad cases as good ones. eg: -1 gets stored as 0xFFFFFFFF on a 32 bit system Signed-off-by: Dale Zhao Reviewed-by: Yongqiang Sun Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c index 7f4766e45dff..e8b6065fffad 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c @@ -47,7 +47,7 @@ unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...) { - unsigned int ret_vsnprintf; + int ret_vsnprintf; unsigned int chars_printed; va_list args; From d448521edaf31681d344045842b2a4f05f90e96a Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Mon, 1 Feb 2021 10:01:02 -0500 Subject: [PATCH 46/60] drm/amd/display: [FW Promotion] Release 0.0.51 Add new definition and union for dmub_rb_cmd_dig1_transmitter_control Signed-off-by: Anthony Koo Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) 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 5aaa35c8c172..072b4e7e624b 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -47,10 +47,10 @@ /* Firmware versioning. */ #ifdef DMUB_EXPOSE_VERSION -#define DMUB_FW_VERSION_GIT_HASH 0xca1cd48c9 +#define DMUB_FW_VERSION_GIT_HASH 0x6444c02e7 #define DMUB_FW_VERSION_MAJOR 0 #define DMUB_FW_VERSION_MINOR 0 -#define DMUB_FW_VERSION_REVISION 50 +#define DMUB_FW_VERSION_REVISION 51 #define DMUB_FW_VERSION_TEST 0 #define DMUB_FW_VERSION_VBIOS 0 #define DMUB_FW_VERSION_HOTFIX 0 @@ -491,13 +491,34 @@ struct dmub_rb_cmd_enable_disp_power_gating { struct dmub_cmd_enable_disp_power_gating_data power_gating; }; -struct dmub_cmd_dig1_transmitter_control_data { +struct dmub_dig_transmitter_control_data_v1_7 { + uint8_t phyid; /**< 0=UNIPHYA, 1=UNIPHYB, 2=UNIPHYC, 3=UNIPHYD, 4=UNIPHYE, 5=UNIPHYF */ + uint8_t action; /**< Defined as ATOM_TRANSMITER_ACTION_xxx */ + union { + uint8_t digmode; /**< enum atom_encode_mode_def */ + uint8_t dplaneset; /**< DP voltage swing and pre-emphasis value, "DP_LANE_SET__xDB_y_zV" */ + } mode_laneset; + uint8_t lanenum; /**< Number of lanes */ + union { + uint32_t symclk_10khz; /**< Symbol Clock in 10Khz */ + } symclk_units; + uint8_t hpdsel; /**< =1: HPD1, =2: HPD2, ..., =6: HPD6, =0: HPD is not assigned */ + uint8_t digfe_sel; /**< DIG front-end selection, bit0 means DIG0 FE is enabled */ + uint8_t connobj_id; /**< Connector Object Id defined in ObjectId.h */ + uint8_t reserved0; /**< For future use */ + uint8_t reserved1; /**< For future use */ + uint8_t reserved2[3]; /**< For future use */ + uint32_t reserved3[11]; /**< For future use */ +}; + +union dmub_cmd_dig1_transmitter_control_data { struct dig_transmitter_control_parameters_v1_6 dig; + struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7; }; struct dmub_rb_cmd_dig1_transmitter_control { struct dmub_cmd_header header; - struct dmub_cmd_dig1_transmitter_control_data transmitter_control; + union dmub_cmd_dig1_transmitter_control_data transmitter_control; }; struct dmub_rb_cmd_dpphy_init { From ef4dd6b2757e4f047b3d9fd38f13eb576d30ba83 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Mon, 1 Feb 2021 10:47:41 -0500 Subject: [PATCH 47/60] drm/amd/display: 3.2.122 This version brings along following fixes: - Fix error handling in dc/dcn10/dcn10_hw_sequencer_debug.c - DIO Supported for virtual displays - memset dmub_rb_cmd to 0 which fixes issues talking with firmware - fix 64bit division issue on 32bit OS - move edp sink present detection to hw init to fix hang - reverts a patch that caused 3x4K60 displays over MST with DSC enabled to not light up Signed-off-by: Aric Cyr Acked-by: Anson Jacob Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 739a39eeb941..4eee3a55fa30 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -42,7 +42,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.121" +#define DC_VER "3.2.122" #define MAX_SURFACES 3 #define MAX_PLANES 6 From 006cc1a213cf9ff3d1307ff2d5c51e6c8d62a758 Mon Sep 17 00:00:00 2001 From: Jiawei Gu Date: Fri, 5 Feb 2021 17:45:18 +0800 Subject: [PATCH 48/60] drm/amdgpu: extend MAX_KIQ_REG_TRY to 1000 Extend retry times of KIQ to avoid starvation situation caused by long time full access of GPU by other VFs. Signed-off-by: Jiawei Gu Reviewed-by: Emily.Deng Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9717cb43eb26..86452f4f3c82 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -287,7 +287,7 @@ enum amdgpu_kiq_irq { #define MAX_KIQ_REG_WAIT 5000 /* in usecs, 5ms */ #define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */ -#define MAX_KIQ_REG_TRY 80 /* 20 -> 80 */ +#define MAX_KIQ_REG_TRY 1000 int amdgpu_device_ip_set_clockgating_state(void *dev, enum amd_ip_block_type block_type, From d7ef887f2f8e7ac2ce03d4f5290d96daca613e2f Mon Sep 17 00:00:00 2001 From: Xiaojian Du Date: Wed, 20 Jan 2021 10:39:10 +0800 Subject: [PATCH 49/60] drm/amd/pm: make the error log more clear for fine grain tuning function This patch is to make the error log more clear for fine grain tuning function, it covers Raven/Raven2/Picasso/Renoir/Vangogh. The fine grain tuning function uses the sysfs file -- pp_od_clk_voltage, but only when another sysfs file -- power_dpm_force_performance_level is switched to "manual" mode, it is allowed to access "pp_od_clk_voltage". Signed-off-by: Xiaojian Du Acked-by: Huang Rui Acked-by: Kevin Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 3 ++- drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 88322781e447..ed05a30d1139 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -1487,7 +1487,7 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr, } if (!smu10_data->fine_grain_enabled) { - pr_err("Fine grain not started\n"); + pr_err("pp_od_clk_voltage is not accessible if power_dpm_force_perfomance_level is not in manual mode!\n"); return -EINVAL; } 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 3277014b5881..093b01159408 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -1461,7 +1461,8 @@ static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TAB struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); if (!(smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)) { - dev_warn(smu->adev->dev, "Fine grain is not enabled!\n"); + dev_warn(smu->adev->dev, + "pp_od_clk_voltage is not accessible if power_dpm_force_perfomance_level is not in manual mode!\n"); return -EINVAL; } 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 cde0ff87e281..5faa509f0dba 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -350,7 +350,8 @@ static int renoir_od_edit_dpm_table(struct smu_context *smu, struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); if (!(smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL)) { - dev_warn(smu->adev->dev, "Fine grain is not enabled!\n"); + dev_warn(smu->adev->dev, + "pp_od_clk_voltage is not accessible if power_dpm_force_perfomance_level is not in manual mode!\n"); return -EINVAL; } From 802b8c83557c19e3ba1d9790e8956288c8b03dac Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Tue, 9 Feb 2021 16:29:23 +0800 Subject: [PATCH 50/60] drm/amdgpu: fix unnecessary NULL check warnings Remove NULL checks before vfree() to fix these warnings: drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:102:2-8: WARNING: NULL check before some freeing functions is not needed. Signed-off-by: Tian Tao Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 594a0108e90f..3e240b952e79 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -98,8 +98,7 @@ static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p, return 0; error_free: - if (info) - kvfree(info); + kvfree(info); return r; } From 910f1601addae3e430fc7d3cd589d7622c5df693 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 3 Feb 2021 14:03:50 -0500 Subject: [PATCH 51/60] Revert "drm/amd/display: Update NV1x SR latency values" This reverts commit 4a3dea8932d3b1199680d2056dd91d31d94d70b7. This causes blank screens for some users. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1388 Cc: Alvin Lee Cc: Jun Lei Cc: Rodrigo Siqueira Reviewed-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 a0a4ab47a1c0..a2cbafab663c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -297,8 +297,8 @@ static struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = { }, }, .num_states = 5, - .sr_exit_time_us = 11.6, - .sr_enter_plus_exit_time_us = 13.9, + .sr_exit_time_us = 8.6, + .sr_enter_plus_exit_time_us = 10.9, .urgent_latency_us = 4.0, .urgent_latency_pixel_data_only_us = 4.0, .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, From 17c900cb5d6a53443dbd26d999ae6fdd96ecc505 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Mon, 8 Feb 2021 18:29:28 +0800 Subject: [PATCH 52/60] drm/amd/display: Simplify bool comparison Fix the following coccicheck warning: ./drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h:319:11-23: WARNING: Comparison to bool. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h index ffd37696b6b9..316301fc1e30 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h @@ -309,9 +309,9 @@ static inline bool should_set_clock(bool safe_to_lower, int calc_clk, int cur_cl static inline bool should_update_pstate_support(bool safe_to_lower, bool calc_support, bool cur_support) { if (cur_support != calc_support) { - if (calc_support == true && safe_to_lower) + if (calc_support && safe_to_lower) return true; - else if (calc_support == false && !safe_to_lower) + else if (!calc_support && !safe_to_lower) return true; } From a29d4b3d3caf91beba12187e4c78ec28e4a29c09 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Mon, 8 Feb 2021 18:17:38 +0800 Subject: [PATCH 53/60] drm/radeon: Simplify bool comparison Fix the following coccicheck warning: ./drivers/gpu/drm/radeon/rs690.c:190:6-35: WARNING: Comparison to bool. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/rs690.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index c296f94f9700..7bc302a89232 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -187,7 +187,7 @@ static void rs690_mc_init(struct radeon_device *rdev) /* FastFB shall be used with UMA memory. Here it is simply disabled when sideport * memory is present. */ - if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) { + if (!rdev->mc.igp_sideport_enabled && radeon_fastfb == 1) { DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n", (unsigned long long)rdev->mc.aper_base, k8_addr); rdev->mc.aper_base = (resource_size_t)k8_addr; From 4112c00354004cbb1bf56f0114fa9951bf6b13ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 4 Feb 2021 02:46:20 -0500 Subject: [PATCH 54/60] drm/amdgpu: fix CGTS_TCC_DISABLE register offset on gfx10.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes incorrect TCC harvesting info reported to userspace. The impact was a very very tiny performance degradation (unnecessary GL2 cache flushes). Signed-off-by: Marek Olšák Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 8ac2af225436..45d1172b7bff 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -70,6 +70,11 @@ #define GB_ADDR_CONFIG__NUM_PKRS__SHIFT 0x8 #define GB_ADDR_CONFIG__NUM_PKRS_MASK 0x00000700L +#define mmCGTS_TCC_DISABLE_gc_10_3 0x5006 +#define mmCGTS_TCC_DISABLE_gc_10_3_BASE_IDX 1 +#define mmCGTS_USER_TCC_DISABLE_gc_10_3 0x5007 +#define mmCGTS_USER_TCC_DISABLE_gc_10_3_BASE_IDX 1 + #define mmCP_MEC_CNTL_Sienna_Cichlid 0x0f55 #define mmCP_MEC_CNTL_Sienna_Cichlid_BASE_IDX 0 #define mmRLC_SAFE_MODE_Sienna_Cichlid 0x4ca0 @@ -98,10 +103,6 @@ #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0 -#define mmCGTS_TCC_DISABLE_Vangogh 0x5006 -#define mmCGTS_TCC_DISABLE_Vangogh_BASE_IDX 1 -#define mmCGTS_USER_TCC_DISABLE_Vangogh 0x5007 -#define mmCGTS_USER_TCC_DISABLE_Vangogh_BASE_IDX 1 #define mmGOLDEN_TSC_COUNT_UPPER_Vangogh 0x0025 #define mmGOLDEN_TSC_COUNT_UPPER_Vangogh_BASE_IDX 1 #define mmGOLDEN_TSC_COUNT_LOWER_Vangogh 0x0026 @@ -4938,15 +4939,12 @@ static void gfx_v10_0_get_tcc_info(struct amdgpu_device *adev) /* TCCs are global (not instanced). */ uint32_t tcc_disable; - switch (adev->asic_type) { - case CHIP_VANGOGH: - tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE_Vangogh) | - RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE_Vangogh); - break; - default: + if (adev->asic_type >= CHIP_SIENNA_CICHLID) { + tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE_gc_10_3) | + RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE_gc_10_3); + } else { tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE) | - RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE); - break; + RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE); } adev->gfx.config.tcc_disabled_mask = From e96b1b2974989c6a25507b527843ede7594efc85 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 10 Feb 2021 18:11:04 +0100 Subject: [PATCH 55/60] drm/amdgpu/display: remove hdcp_srm sysfs on device removal Fixes: 9037246bb2da5 ("drm/amd/display: Add sysfs interface for set/get srm") Signed-off-by: Nirmoy Das Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 3 ++- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 8a44b6ba8595..94cd5ddd67ef 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1128,7 +1128,7 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) #ifdef CONFIG_DRM_AMD_DC_HDCP if (adev->dm.hdcp_workqueue) { - hdcp_destroy(adev->dm.hdcp_workqueue); + hdcp_destroy(&adev->dev->kobj, adev->dm.hdcp_workqueue); adev->dm.hdcp_workqueue = NULL; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index b297ddc24d3a..0cdbfcd475ec 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -376,7 +376,7 @@ static void event_cpirq(struct work_struct *work) } -void hdcp_destroy(struct hdcp_workqueue *hdcp_work) +void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work) { int i = 0; @@ -385,6 +385,7 @@ void hdcp_destroy(struct hdcp_workqueue *hdcp_work) cancel_delayed_work_sync(&hdcp_work[i].watchdog_timer_dwork); } + sysfs_remove_bin_file(kobj, &hdcp_work[0].attr); kfree(hdcp_work->srm); kfree(hdcp_work->srm_temp); kfree(hdcp_work); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h index 5159b3a5e5b0..09294ff122fe 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h @@ -69,7 +69,7 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work, void hdcp_reset_display(struct hdcp_workqueue *work, unsigned int link_index); void hdcp_handle_cpirq(struct hdcp_workqueue *work, unsigned int link_index); -void hdcp_destroy(struct hdcp_workqueue *work); +void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *work); struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, struct cp_psp *cp_psp, struct dc *dc); From f2d51b20d747e027e81ab3c3f24a6c833ada3fb3 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 10 Feb 2021 15:23:30 -0600 Subject: [PATCH 56/60] drm/amd/display: Fix potential integer overflow Fix potential integer overflow by casting actual_calculated_clock_100hz to u64, in order to give the compiler complete information about the proper arithmetic to use. Notice that such variable is used in a context that expects an expression of type u64 (64 bits, unsigned) and the following expression is currently being evaluated using 32-bit arithmetic: actual_calculated_clock_100hz * post_divider Fixes: 7a03fdf628af ("drm/amd/display: fix 64bit division issue on 32bit OS") Addresses-Coverity-ID: 1501691 ("Unintentional integer overflow") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index bc942725b9d8..dec58b3c42e4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -240,7 +240,7 @@ static bool calc_fb_divider_checking_tolerance( pll_settings->calculated_pix_clk_100hz = actual_calculated_clock_100hz; pll_settings->vco_freq = - div_u64(actual_calculated_clock_100hz * post_divider, 10); + div_u64((u64)actual_calculated_clock_100hz * post_divider, 10); return true; } return false; From 41401ac67791810dd880345962339aa1bedd3c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kokem=C3=BCller?= Date: Thu, 11 Feb 2021 19:28:43 +0100 Subject: [PATCH 57/60] drm/amd/display: Add FPU wrappers to dcn21_validate_bandwidth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dcn21_validate_bandwidth() calls functions that use floating point math. On my machine this sometimes results in simd exceptions when there are other FPU users such as KVM virtual machines running. The screen freezes completely in this case. Wrapping the function with DC_FP_START()/DC_FP_END() seems to solve the problem. This mirrors the approach used for dcn20_validate_bandwidth. Tested on a AMD Ryzen 7 PRO 4750U (Renoir). Bug: https://bugzilla.kernel.org/show_bug.cgi?id=206987 Signed-off-by: Jan Kokemüller Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- .../drm/amd/display/dc/dcn21/dcn21_resource.c | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) 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 a2cbafab663c..2c2dbfcd8957 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -3247,7 +3247,7 @@ static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc, bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate) { - bool voltage_supported = false; + bool voltage_supported; DC_FP_START(); voltage_supported = dcn20_validate_bandwidth_fp(dc, context, fast_validate); DC_FP_END(); diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 674376428916..072f8c880924 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1329,8 +1329,8 @@ static bool dcn21_fast_validate_bw( return out; } -bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, - bool fast_validate) +static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc, + struct dc_state *context, bool fast_validate) { bool out = false; @@ -1383,6 +1383,22 @@ bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, return out; } + +/* + * Some of the functions further below use the FPU, so we need to wrap this + * with DC_FP_START()/DC_FP_END(). Use the same approach as for + * dcn20_validate_bandwidth in dcn20_resource.c. + */ +bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, + bool fast_validate) +{ + bool voltage_supported; + DC_FP_START(); + voltage_supported = dcn21_validate_bandwidth_fp(dc, context, fast_validate); + DC_FP_END(); + return voltage_supported; +} + static void dcn21_destroy_resource_pool(struct resource_pool **pool) { struct dcn21_resource_pool *dcn21_pool = TO_DCN21_RES_POOL(*pool); From 1fb8b1fc4dd1035a264c81d15d41f05884cc8058 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Thu, 4 Feb 2021 00:11:17 -0500 Subject: [PATCH 58/60] drm/amdkfd: Fix recursive lock warnings memalloc_nofs_save/restore are no longer sufficient to prevent recursive lock warnings when holding locks that can be taken in MMU notifiers. Use memalloc_noreclaim_save/restore instead. Fixes: f920e413ff9c ("mm: track mmu notifiers in fs_reclaim_acquire/release") CC: Daniel Vetter Reviewed-by: Philip Yang Signed-off-by: Felix Kuehling Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 5.10.x --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 16262e5d93f5..7351dd195274 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -243,11 +243,11 @@ get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) static inline void dqm_lock(struct device_queue_manager *dqm) { mutex_lock(&dqm->lock_hidden); - dqm->saved_flags = memalloc_nofs_save(); + dqm->saved_flags = memalloc_noreclaim_save(); } static inline void dqm_unlock(struct device_queue_manager *dqm) { - memalloc_nofs_restore(dqm->saved_flags); + memalloc_noreclaim_restore(dqm->saved_flags); mutex_unlock(&dqm->lock_hidden); } From 7e6435c14a426ccb7bedea179fe0e8666c4ea1b8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 16 Feb 2021 09:02:36 -0500 Subject: [PATCH 59/60] drm/radeon: OLAND boards don't have VCE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable it on those boards. No functional change, this just removes the message about VCE failing to initialize. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=197327 Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_asic.c | 3 +++ drivers/gpu/drm/radeon/radeon_vce.c | 1 - drivers/gpu/drm/radeon/vce_v1_0.c | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 8becbe09af2f..bfacf8fe5cc1 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2478,6 +2478,9 @@ int radeon_asic_init(struct radeon_device *rdev) if (rdev->family == CHIP_HAINAN) { rdev->has_uvd = false; rdev->has_vce = false; + } else if (rdev->family == CHIP_OLAND) { + rdev->has_uvd = true; + rdev->has_vce = false; } else { rdev->has_uvd = true; rdev->has_vce = true; diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index a450497368b2..511a942e851d 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c @@ -68,7 +68,6 @@ int radeon_vce_init(struct radeon_device *rdev) case CHIP_TAHITI: case CHIP_PITCAIRN: case CHIP_VERDE: - case CHIP_OLAND: case CHIP_ARUBA: fw_name = FIRMWARE_TAHITI; break; diff --git a/drivers/gpu/drm/radeon/vce_v1_0.c b/drivers/gpu/drm/radeon/vce_v1_0.c index 70c5da2141d7..bdfbcf14b864 100644 --- a/drivers/gpu/drm/radeon/vce_v1_0.c +++ b/drivers/gpu/drm/radeon/vce_v1_0.c @@ -169,7 +169,6 @@ int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) chip_id = 0x01000015; break; case CHIP_PITCAIRN: - case CHIP_OLAND: chip_id = 0x01000016; break; case CHIP_ARUBA: From 6e80fb8ab04f6c4f377e2fd422bdd1855beb7371 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 16 Feb 2021 10:57:00 -0500 Subject: [PATCH 60/60] drm/amdgpu: Set reference clock to 100Mhz on Renoir (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the rlc reference clock used for GPU timestamps. Value is 100Mhz. Confirmed with hardware team. v2: reword commit message. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1480 Acked-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/soc15.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index e865495d3ead..1221aa6b40a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -233,6 +233,8 @@ static u32 soc15_get_xclk(struct amdgpu_device *adev) { u32 reference_clock = adev->clock.spll.reference_freq; + if (adev->asic_type == CHIP_RENOIR) + return 10000; if (adev->asic_type == CHIP_RAVEN) return reference_clock / 4;