From 25f45e633892a45df2edbfd4a5dbbfc70e32487b Mon Sep 17 00:00:00 2001 From: Jack Xiao Date: Thu, 4 Jun 2015 12:18:27 +0800 Subject: [PATCH 01/23] drm/amdgpu: add zero timeout check in amdgpu_fence_wait_seq_timeout Signed-off-by: Jack Xiao Reviewed-by: Jammy Zhou --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 9ce6023a4261..48ca637c5029 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -522,6 +522,10 @@ long amdgpu_fence_wait_seq_timeout(struct amdgpu_device *adev, u64 *target_seq, bool signaled; int i, r; + if (timeout == 0) { + return amdgpu_fence_any_seq_signaled(adev, target_seq); + } + while (!amdgpu_fence_any_seq_signaled(adev, target_seq)) { /* Save current sequence values, used to check for GPU lockups */ From 9298e52f8b51d1e4acd68f502832f3a97f8cf892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 3 Jun 2015 21:31:20 +0200 Subject: [PATCH 02/23] drm/amdgpu: fix user ptr race condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Reviewed-by: monk liu --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index ad5b9c676fd8..e8409fea4bf1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -37,6 +37,7 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj) if (robj) { if (robj->gem_base.import_attach) drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); + amdgpu_mn_unregister(robj); amdgpu_bo_unref(&robj); } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 7d801e016e31..8da64245b31b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -95,7 +95,6 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) bo = container_of(tbo, struct amdgpu_bo, tbo); amdgpu_update_memory_usage(bo->adev, &bo->tbo.mem, NULL); - amdgpu_mn_unregister(bo); mutex_lock(&bo->adev->gem.mutex); list_del_init(&bo->list); From 890ee23fc60193d7c2bca17e099569f1510b3053 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Mon, 1 Jun 2015 14:35:03 +0800 Subject: [PATCH 03/23] drm/amdgpu: disable user fence interrupt (v2) amdgpu submits both kernel and user fences, but just need one interrupt, disable user fence interrupt and don't effect user fence. v2: fix merge error Signed-off-by: Chunming Zhou Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 7 +++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 4 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | 2 +- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 3 ++- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 13 +++++++++---- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 14 ++++++++++---- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 4 ++-- 13 files changed, 46 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c33c1af36fa2..37aeed7b454d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -317,7 +317,7 @@ struct amdgpu_ring_funcs { void (*emit_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib); void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr, - uint64_t seq, bool write64bit); + uint64_t seq, unsigned flags); bool (*emit_semaphore)(struct amdgpu_ring *ring, struct amdgpu_semaphore *semaphore, bool emit_wait); @@ -392,6 +392,9 @@ struct amdgpu_fence_driver { #define AMDGPU_FENCE_OWNER_VM ((void*)1ul) #define AMDGPU_FENCE_OWNER_MOVE ((void*)2ul) +#define AMDGPU_FENCE_FLAG_64BIT (1 << 0) +#define AMDGPU_FENCE_FLAG_INT (1 << 1) + struct amdgpu_fence { struct fence base; @@ -2142,7 +2145,7 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) #define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r)) #define amdgpu_ring_emit_ib(r, ib) (r)->funcs->emit_ib((r), (ib)) #define amdgpu_ring_emit_vm_flush(r, vmid, addr) (r)->funcs->emit_vm_flush((r), (vmid), (addr)) -#define amdgpu_ring_emit_fence(r, addr, seq, write64bit) (r)->funcs->emit_fence((r), (addr), (seq), (write64bit)) +#define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags)) #define amdgpu_ring_emit_semaphore(r, semaphore, emit_wait) (r)->funcs->emit_semaphore((r), (semaphore), (emit_wait)) #define amdgpu_ring_emit_gds_switch(r, v, db, ds, wb, ws, ab, as) (r)->funcs->emit_gds_switch((r), (v), (db), (ds), (wb), (ws), (ab), (as)) #define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 48ca637c5029..5c9918d01bf9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -128,7 +128,9 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner, fence_init(&(*fence)->base, &amdgpu_fence_ops, &adev->fence_queue.lock, adev->fence_context + ring->idx, (*fence)->seq); - amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, (*fence)->seq, false); + amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, + (*fence)->seq, + AMDGPU_FENCE_FLAG_INT); trace_amdgpu_fence_emit(ring->adev->ddev, ring->idx, (*fence)->seq); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 560c5fd347be..52dff75aac6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -216,7 +216,8 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, if (ib->user) { uint64_t addr = amdgpu_bo_gpu_offset(ib->user->bo); addr += ib->user->offset; - amdgpu_ring_emit_fence(ring, addr, ib->fence->seq, true); + amdgpu_ring_emit_fence(ring, addr, ib->fence->seq, + AMDGPU_FENCE_FLAG_64BIT); } if (ib->vm) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 62018b37273e..1127a504f118 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -637,9 +637,9 @@ void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) * */ void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bits) + unsigned flags) { - WARN_ON(write64bits); + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); amdgpu_ring_write(ring, VCE_CMD_FENCE); amdgpu_ring_write(ring, addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h index 4294854912e7..b6a9d0956c60 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h @@ -40,7 +40,7 @@ bool amdgpu_vce_ring_emit_semaphore(struct amdgpu_ring *ring, bool emit_wait); void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bit); + unsigned flags); int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring); int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index ef5e9f9b5ab2..fb931638a7e6 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -259,8 +259,9 @@ static void cik_sdma_ring_emit_hdp_flush(struct amdgpu_ring *ring) * an interrupt if needed (CIK). */ static void cik_sdma_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bit) + unsigned flags) { + bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; /* write the fence */ amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_FENCE, 0, 0)); amdgpu_ring_write(ring, lower_32_bits(addr)); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 5fefe402e085..afa703c0efeb 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -2414,8 +2414,10 @@ static void gfx_v7_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) * GPU caches. */ static void gfx_v7_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, - u64 seq, bool write64bit) + u64 seq, unsigned flags) { + bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; + bool int_sel = flags & AMDGPU_FENCE_FLAG_INT; /* Workaround for cache flush problems. First send a dummy EOP * event down the pipe with seq one below. */ @@ -2438,7 +2440,7 @@ static void gfx_v7_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, EVENT_INDEX(5))); amdgpu_ring_write(ring, addr & 0xfffffffc); amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) | - DATA_SEL(write64bit ? 2 : 1) | INT_SEL(2)); + DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0)); amdgpu_ring_write(ring, lower_32_bits(seq)); amdgpu_ring_write(ring, upper_32_bits(seq)); } @@ -2454,15 +2456,18 @@ static void gfx_v7_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, */ static void gfx_v7_0_ring_emit_fence_compute(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bits) + unsigned flags) { + bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; + bool int_sel = flags & AMDGPU_FENCE_FLAG_INT; + /* RELEASE_MEM - flush caches, send int */ amdgpu_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 5)); amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN | EOP_TC_ACTION_EN | EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5))); - amdgpu_ring_write(ring, DATA_SEL(write64bits ? 2 : 1) | INT_SEL(2)); + amdgpu_ring_write(ring, DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0)); amdgpu_ring_write(ring, addr & 0xfffffffc); amdgpu_ring_write(ring, upper_32_bits(addr)); amdgpu_ring_write(ring, lower_32_bits(seq)); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 04b91523008c..6ae2d6be126a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -3713,8 +3713,11 @@ static void gfx_v8_0_ring_emit_ib(struct amdgpu_ring *ring, } static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, - u64 seq, bool write64bit) + u64 seq, unsigned flags) { + bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; + bool int_sel = flags & AMDGPU_FENCE_FLAG_INT; + /* EVENT_WRITE_EOP - flush caches, send int */ amdgpu_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN | @@ -3723,7 +3726,7 @@ static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, EVENT_INDEX(5))); amdgpu_ring_write(ring, addr & 0xfffffffc); amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) | - DATA_SEL(write64bit ? 2 : 1) | INT_SEL(2)); + DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0)); amdgpu_ring_write(ring, lower_32_bits(seq)); amdgpu_ring_write(ring, upper_32_bits(seq)); } @@ -3880,15 +3883,18 @@ static void gfx_v8_0_ring_set_wptr_compute(struct amdgpu_ring *ring) static void gfx_v8_0_ring_emit_fence_compute(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bits) + unsigned flags) { + bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; + bool int_sel = flags & AMDGPU_FENCE_FLAG_INT; + /* RELEASE_MEM - flush caches, send int */ amdgpu_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 5)); amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN | EOP_TC_ACTION_EN | EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5))); - amdgpu_ring_write(ring, DATA_SEL(write64bits ? 2 : 1) | INT_SEL(2)); + amdgpu_ring_write(ring, DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0)); amdgpu_ring_write(ring, addr & 0xfffffffc); amdgpu_ring_write(ring, upper_32_bits(addr)); amdgpu_ring_write(ring, lower_32_bits(seq)); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index d09aa7eeb40e..d7895885fe0c 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -292,8 +292,9 @@ static void sdma_v2_4_ring_emit_hdp_flush(struct amdgpu_ring *ring) * an interrupt if needed (VI). */ static void sdma_v2_4_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bits) + unsigned flags) { + bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; /* write the fence */ amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE)); amdgpu_ring_write(ring, lower_32_bits(addr)); @@ -301,7 +302,7 @@ static void sdma_v2_4_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se amdgpu_ring_write(ring, lower_32_bits(seq)); /* optionally write high bits as well */ - if (write64bits) { + if (write64bit) { addr += 4; amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE)); amdgpu_ring_write(ring, lower_32_bits(addr)); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 555c0e1e4c97..e3c1fde75363 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -347,8 +347,9 @@ static void sdma_v3_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) * an interrupt if needed (VI). */ static void sdma_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bits) + unsigned flags) { + bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; /* write the fence */ amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE)); amdgpu_ring_write(ring, lower_32_bits(addr)); @@ -356,7 +357,7 @@ static void sdma_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se amdgpu_ring_write(ring, lower_32_bits(seq)); /* optionally write high bits as well */ - if (write64bits) { + if (write64bit) { addr += 4; amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE)); amdgpu_ring_write(ring, lower_32_bits(addr)); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 292932a73c81..4efd671d7a9b 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -417,9 +417,9 @@ static void uvd_v4_2_stop(struct amdgpu_device *adev) * Write a fence and a trap command to the ring. */ static void uvd_v4_2_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bit) + unsigned flags) { - WARN_ON(write64bit); + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, seq); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index 004c56496fc4..b756bd99c0fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -461,9 +461,9 @@ static void uvd_v5_0_stop(struct amdgpu_device *adev) * Write a fence and a trap command to the ring. */ static void uvd_v5_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bit) + unsigned flags) { - WARN_ON(write64bit); + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, seq); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 8c790fb31e2f..49aa931b2cb4 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -457,9 +457,9 @@ static void uvd_v6_0_stop(struct amdgpu_device *adev) * Write a fence and a trap command to the ring. */ static void uvd_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, - bool write64bit) + unsigned flags) { - WARN_ON(write64bit); + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, seq); From cab6d57c09ece2ceb03602dd44ea2f4ce9333ec9 Mon Sep 17 00:00:00 2001 From: Jammy Zhou Date: Sat, 6 Jun 2015 04:49:22 +0800 Subject: [PATCH 04/23] drm/amdgpu: remove unused AMDGPU_IB_FLAG_GDS Signed-off-by: Jammy Zhou Reviewed-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 780a5815fb12..3b911b604fdf 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -371,11 +371,8 @@ union drm_amdgpu_cs { /* This IB should be submitted to CE */ #define AMDGPU_IB_FLAG_CE (1<<0) -/* GDS is used by this IB */ -#define AMDGPU_IB_FLAG_GDS (1<<1) - /* CE Preamble */ -#define AMDGPU_IB_FLAG_PREAMBLE (1<<2) +#define AMDGPU_IB_FLAG_PREAMBLE (1<<1) struct drm_amdgpu_cs_chunk_ib { uint32_t _pad; @@ -580,7 +577,7 @@ struct drm_amdgpu_info_device { uint32_t gart_page_size; /** constant engine ram size*/ uint32_t ce_ram_size; - /** video memory type infro*/ + /** video memory type info*/ uint32_t vram_type; /** video memory bit width*/ uint32_t vram_bit_width; From 7e9fca0baa3b3400ccb2b2a8a17822f7b04ea282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 5 Jun 2015 10:06:04 +0200 Subject: [PATCH 05/23] drm/amdgpu: fix amdgpu_vm_bo_map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to reset the bo_va address, otherwise new mappings wouldn't be updated in the page table. Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index fd28e890693e..33696ee55349 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1002,6 +1002,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, list_add(&mapping->list, &bo_va->mappings); interval_tree_insert(&mapping->it, &vm->va); + bo_va->addr = 0; + /* Make sure the page tables are allocated */ saddr >>= amdgpu_vm_block_size; eaddr >>= amdgpu_vm_block_size; From 6c7fc503a47f9b87dfd7c76e34f808ab6870a82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 5 Jun 2015 20:56:17 +0200 Subject: [PATCH 06/23] drm/amdgpu: fix saddr handling in amdgpu_vm_bo_unmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 33696ee55349..407882b233c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1084,6 +1084,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping; struct amdgpu_vm *vm = bo_va->vm; + saddr /= AMDGPU_GPU_PAGE_SIZE; + list_for_each_entry(mapping, &bo_va->mappings, list) { if (mapping->it.start == saddr) break; From 34b5f6a6d6d0e482c7ce498f60bce261e533821e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 8 Jun 2015 15:03:00 +0200 Subject: [PATCH 07/23] drm/amdgpu: cleanup VA IOCTL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the unnecessary returned status and make the IOCTL write only. Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 64 ++++++++----------------- include/uapi/drm/amdgpu_drm.h | 18 +------ 2 files changed, 23 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index e8409fea4bf1..0ec222295fee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -505,7 +505,7 @@ error_free: int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { - union drm_amdgpu_gem_va *args = data; + struct drm_amdgpu_gem_va *args = data; struct drm_gem_object *gobj; struct amdgpu_device *adev = dev->dev_private; struct amdgpu_fpriv *fpriv = filp->driver_priv; @@ -514,95 +514,73 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, uint32_t invalid_flags, va_flags = 0; int r = 0; - if (!adev->vm_manager.enabled) { - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; + if (!adev->vm_manager.enabled) return -ENOTTY; - } - if (args->in.va_address < AMDGPU_VA_RESERVED_SIZE) { + if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { dev_err(&dev->pdev->dev, "va_address 0x%lX is in reserved area 0x%X\n", - (unsigned long)args->in.va_address, + (unsigned long)args->va_address, AMDGPU_VA_RESERVED_SIZE); - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; return -EINVAL; } invalid_flags = ~(AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE); - if ((args->in.flags & invalid_flags)) { + if ((args->flags & invalid_flags)) { dev_err(&dev->pdev->dev, "invalid flags 0x%08X vs 0x%08X\n", - args->in.flags, invalid_flags); - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; + args->flags, invalid_flags); return -EINVAL; } - switch (args->in.operation) { + switch (args->operation) { case AMDGPU_VA_OP_MAP: case AMDGPU_VA_OP_UNMAP: break; default: dev_err(&dev->pdev->dev, "unsupported operation %d\n", - args->in.operation); - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; + args->operation); return -EINVAL; } - gobj = drm_gem_object_lookup(dev, filp, args->in.handle); - if (gobj == NULL) { - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; + gobj = drm_gem_object_lookup(dev, filp, args->handle); + if (gobj == NULL) return -ENOENT; - } + rbo = gem_to_amdgpu_bo(gobj); r = amdgpu_bo_reserve(rbo, false); if (r) { - if (r != -ERESTARTSYS) { - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; - } drm_gem_object_unreference_unlocked(gobj); return r; } + bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo); if (!bo_va) { - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; - drm_gem_object_unreference_unlocked(gobj); + amdgpu_bo_unreserve(rbo); return -ENOENT; } - switch (args->in.operation) { + switch (args->operation) { case AMDGPU_VA_OP_MAP: - if (args->in.flags & AMDGPU_VM_PAGE_READABLE) + if (args->flags & AMDGPU_VM_PAGE_READABLE) va_flags |= AMDGPU_PTE_READABLE; - if (args->in.flags & AMDGPU_VM_PAGE_WRITEABLE) + if (args->flags & AMDGPU_VM_PAGE_WRITEABLE) va_flags |= AMDGPU_PTE_WRITEABLE; - if (args->in.flags & AMDGPU_VM_PAGE_EXECUTABLE) + if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE) va_flags |= AMDGPU_PTE_EXECUTABLE; - r = amdgpu_vm_bo_map(adev, bo_va, args->in.va_address, - args->in.offset_in_bo, args->in.map_size, + r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, + args->offset_in_bo, args->map_size, va_flags); break; case AMDGPU_VA_OP_UNMAP: - r = amdgpu_vm_bo_unmap(adev, bo_va, args->in.va_address); + r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); break; default: break; } - if (!r) { + if (!r) amdgpu_gem_va_update_vm(adev, bo_va); - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_OK; - } else { - memset(args, 0, sizeof(*args)); - args->out.result = AMDGPU_VA_RESULT_ERROR; - } drm_gem_object_unreference_unlocked(gobj); return r; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 3b911b604fdf..4c465e10a5a6 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -55,7 +55,7 @@ #define DRM_IOCTL_AMDGPU_INFO DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_INFO, struct drm_amdgpu_info) #define DRM_IOCTL_AMDGPU_GEM_METADATA DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_METADATA, struct drm_amdgpu_gem_metadata) #define DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_WAIT_IDLE, union drm_amdgpu_gem_wait_idle) -#define DRM_IOCTL_AMDGPU_GEM_VA DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_VA, union drm_amdgpu_gem_va) +#define DRM_IOCTL_AMDGPU_GEM_VA DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_VA, struct drm_amdgpu_gem_va) #define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs) #define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op) #define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr) @@ -290,10 +290,6 @@ struct drm_amdgpu_gem_op { #define AMDGPU_VA_OP_MAP 1 #define AMDGPU_VA_OP_UNMAP 2 -#define AMDGPU_VA_RESULT_OK 0 -#define AMDGPU_VA_RESULT_ERROR 1 -#define AMDGPU_VA_RESULT_VA_INVALID_ALIGNMENT 2 - /* Mapping flags */ /* readable mapping */ #define AMDGPU_VM_PAGE_READABLE (1 << 1) @@ -302,7 +298,7 @@ struct drm_amdgpu_gem_op { /* executable mapping, new for VI */ #define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3) -struct drm_amdgpu_gem_va_in { +struct drm_amdgpu_gem_va { /* GEM object handle */ uint32_t handle; uint32_t _pad; @@ -319,16 +315,6 @@ struct drm_amdgpu_gem_va_in { uint64_t map_size; }; -struct drm_amdgpu_gem_va_out { - uint32_t result; - uint32_t _pad; -}; - -union drm_amdgpu_gem_va { - struct drm_amdgpu_gem_va_in in; - struct drm_amdgpu_gem_va_out out; -}; - #define AMDGPU_HW_IP_GFX 0 #define AMDGPU_HW_IP_COMPUTE 1 #define AMDGPU_HW_IP_DMA 2 From 3e39ab90833b20eb7fbc4e472726000274739538 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 5 Jun 2015 15:04:33 -0400 Subject: [PATCH 08/23] drm/amdgpu: also print the pci revision when printing the pci ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver makes use of this information so print if to aid in debugging. Reviewed-by: Christian König Reviewed-by: Samuel Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 36be03ce76c2..fec487d1c870 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1388,9 +1388,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; - DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", - amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, - pdev->subsystem_vendor, pdev->subsystem_device); + DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", + amdgpu_asic_name[adev->asic_type], pdev->vendor, pdev->device, + pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); /* mutex initialization are all done here so we * can recall function without having locking issues */ From bd5c97bc1ae77e8f2ec93a2dbe6d4080ae04a4c5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 5 Jun 2015 14:34:19 -0400 Subject: [PATCH 09/23] drm/amdgpu: set the gfx config properly for all CZ variants (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Need to adjust the number of CUs and RBs. v2: get proper values Reviewed-by: Christian König Reviewed-by: Samuel Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 38 +++++++++++++++++++++++++-- 1 file changed, 36 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 6ae2d6be126a..698ea6ce1185 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -1933,9 +1933,43 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev) case CHIP_CARRIZO: adev->gfx.config.max_shader_engines = 1; adev->gfx.config.max_tile_pipes = 2; - adev->gfx.config.max_cu_per_sh = 8; adev->gfx.config.max_sh_per_se = 1; - adev->gfx.config.max_backends_per_se = 2; + + switch (adev->pdev->revision) { + case 0xc4: + case 0x84: + case 0xc8: + case 0xcc: + /* B10 */ + adev->gfx.config.max_cu_per_sh = 8; + adev->gfx.config.max_backends_per_se = 2; + break; + case 0xc5: + case 0x81: + case 0x85: + case 0xc9: + case 0xcd: + /* B8 */ + adev->gfx.config.max_cu_per_sh = 6; + adev->gfx.config.max_backends_per_se = 2; + break; + case 0xc6: + case 0xca: + case 0xce: + /* B6 */ + adev->gfx.config.max_cu_per_sh = 6; + adev->gfx.config.max_backends_per_se = 2; + break; + case 0xc7: + case 0x87: + case 0xcb: + default: + /* B4 */ + adev->gfx.config.max_cu_per_sh = 4; + adev->gfx.config.max_backends_per_se = 1; + break; + } + adev->gfx.config.max_texture_channel_caches = 2; adev->gfx.config.max_gprs = 256; adev->gfx.config.max_gs_threads = 32; From 147dbfbc54e460682eba3494370ea33e9fd5e9b0 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Thu, 11 Jun 2015 02:28:56 +0800 Subject: [PATCH 10/23] drm/amdgpu: remove the VI hardware semaphore in ring sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: David Zhang Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 698ea6ce1185..70cc6bd48926 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -3783,11 +3783,10 @@ static bool gfx_v8_0_ring_emit_semaphore(struct amdgpu_ring *ring, unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; if (ring->adev->asic_type == CHIP_TOPAZ || - ring->adev->asic_type == CHIP_TONGA) { - amdgpu_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); - amdgpu_ring_write(ring, lower_32_bits(addr)); - amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); - } else { + ring->adev->asic_type == CHIP_TONGA) + /* we got a hw semaphore bug in VI TONGA, return false to switch back to sw fence wait */ + return false; + else { amdgpu_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 2)); amdgpu_ring_write(ring, lower_32_bits(addr)); amdgpu_ring_write(ring, upper_32_bits(addr)); From 692a59e696afe1a4e777d0e4359325336ab0ad89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 9 Jun 2015 15:21:35 +0200 Subject: [PATCH 11/23] drm/amdgpu: remove AMDGPU_CTX_OP_STATE_RUNNING MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not used. Signed-off-by: Christian König Reviewed-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 4c465e10a5a6..a82c0601a294 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -139,8 +139,6 @@ union drm_amdgpu_bo_list { #define AMDGPU_CTX_OP_FREE_CTX 2 #define AMDGPU_CTX_OP_QUERY_STATE 3 -#define AMDGPU_CTX_OP_STATE_RUNNING 1 - /* GPU reset status */ #define AMDGPU_CTX_NO_RESET 0 #define AMDGPU_CTX_GUILTY_RESET 1 /* this the context caused it */ From 675da0ddd6fefa5500488a5a3d500aaaefa95e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 9 Jun 2015 15:54:37 +0200 Subject: [PATCH 12/23] drm/amdgpu: cleanup UAPI comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional change. Signed-off-by: Christian König Reviewed-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 121 ++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 42 deletions(-) diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index a82c0601a294..d3f4832db289 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -141,12 +141,17 @@ union drm_amdgpu_bo_list { /* GPU reset status */ #define AMDGPU_CTX_NO_RESET 0 -#define AMDGPU_CTX_GUILTY_RESET 1 /* this the context caused it */ -#define AMDGPU_CTX_INNOCENT_RESET 2 /* some other context caused it */ -#define AMDGPU_CTX_UNKNOWN_RESET 3 /* unknown cause */ +/* this the context caused it */ +#define AMDGPU_CTX_GUILTY_RESET 1 +/* some other context caused it */ +#define AMDGPU_CTX_INNOCENT_RESET 2 +/* unknown cause */ +#define AMDGPU_CTX_UNKNOWN_RESET 3 struct drm_amdgpu_ctx_in { + /** AMDGPU_CTX_OP_* */ uint32_t op; + /** For future use, no flags defined so far */ uint32_t flags; uint32_t ctx_id; uint32_t _pad; @@ -159,6 +164,7 @@ union drm_amdgpu_ctx_out { } alloc; struct { + /** For future use, no flags defined so far */ uint64_t flags; /** Number of resets caused by this context so far. */ uint32_t hangs; @@ -185,7 +191,9 @@ union drm_amdgpu_ctx { struct drm_amdgpu_gem_userptr { uint64_t addr; uint64_t size; + /* AMDGPU_GEM_USERPTR_* */ uint32_t flags; + /* Resulting GEM handle */ uint32_t handle; }; @@ -217,23 +225,29 @@ struct drm_amdgpu_gem_userptr { /** The same structure is shared for input/output */ struct drm_amdgpu_gem_metadata { - uint32_t handle; /* GEM Object handle */ - uint32_t op; /** Do we want get or set metadata */ + /** GEM Object handle */ + uint32_t handle; + /** Do we want get or set metadata */ + uint32_t op; struct { + /** For future use, no flags defined so far */ uint64_t flags; - uint64_t tiling_info; /* family specific tiling info */ + /** family specific tiling info */ + uint64_t tiling_info; uint32_t data_size_bytes; uint32_t data[64]; } data; }; struct drm_amdgpu_gem_mmap_in { - uint32_t handle; /** the GEM object handle */ + /** the GEM object handle */ + uint32_t handle; uint32_t _pad; }; struct drm_amdgpu_gem_mmap_out { - uint64_t addr_ptr; /** mmap offset from the vma offset manager */ + /** mmap offset from the vma offset manager */ + uint64_t addr_ptr; }; union drm_amdgpu_gem_mmap { @@ -242,14 +256,19 @@ union drm_amdgpu_gem_mmap { }; struct drm_amdgpu_gem_wait_idle_in { - uint32_t handle; /* GEM object handle */ + /** GEM object handle */ + uint32_t handle; + /** For future use, no flags defined so far */ uint32_t flags; - uint64_t timeout; /* Timeout to wait. If 0 then returned immediately with the status */ + /** Absolute timeout to wait */ + uint64_t timeout; }; struct drm_amdgpu_gem_wait_idle_out { - uint32_t status; /* BO status: 0 - BO is idle, 1 - BO is busy */ - uint32_t domain; /* Returned current memory domain */ + /** BO status: 0 - BO is idle, 1 - BO is busy */ + uint32_t status; + /** Returned current memory domain */ + uint32_t domain; }; union drm_amdgpu_gem_wait_idle { @@ -258,7 +277,9 @@ union drm_amdgpu_gem_wait_idle { }; struct drm_amdgpu_wait_cs_in { + /** Command submission handle */ uint64_t handle; + /** Absolute timeout to wait */ uint64_t timeout; uint32_t ip_type; uint32_t ip_instance; @@ -267,6 +288,7 @@ struct drm_amdgpu_wait_cs_in { }; struct drm_amdgpu_wait_cs_out { + /** CS status: 0 - CS completed, 1 - CS still busy */ uint64_t status; }; @@ -275,16 +297,19 @@ union drm_amdgpu_wait_cs { struct drm_amdgpu_wait_cs_out out; }; -/* Sets or returns a value associated with a buffer. */ -struct drm_amdgpu_gem_op { - uint32_t handle; /* buffer */ - uint32_t op; /* AMDGPU_GEM_OP_* */ - uint64_t value; /* input or return value */ -}; - #define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0 #define AMDGPU_GEM_OP_SET_PLACEMENT 1 +/* Sets or returns a value associated with a buffer. */ +struct drm_amdgpu_gem_op { + /** GEM object handle */ + uint32_t handle; + /** AMDGPU_GEM_OP_* */ + uint32_t op; + /** Input or return value */ + uint64_t value; +}; + #define AMDGPU_VA_OP_MAP 1 #define AMDGPU_VA_OP_UNMAP 2 @@ -297,19 +322,18 @@ struct drm_amdgpu_gem_op { #define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3) struct drm_amdgpu_gem_va { - /* GEM object handle */ + /** GEM object handle */ uint32_t handle; uint32_t _pad; - /* map or unmap*/ + /** AMDGPU_VA_OP_* */ uint32_t operation; - /* specify mapping flags */ + /** AMDGPU_VM_PAGE_* */ uint32_t flags; - /* va address to assign . Must be correctly aligned.*/ + /** va address to assign . Must be correctly aligned.*/ uint64_t va_address; - /* Specify offset inside of BO to assign. Must be correctly aligned.*/ + /** Specify offset inside of BO to assign. Must be correctly aligned.*/ uint64_t offset_in_bo; - /* Specify mapping size. If 0 and offset is 0 then map the whole BO.*/ - /* Must be correctly aligned. */ + /** Specify mapping size. Must be correctly aligned. */ uint64_t map_size; }; @@ -324,6 +348,7 @@ struct drm_amdgpu_gem_va { #define AMDGPU_CHUNK_ID_IB 0x01 #define AMDGPU_CHUNK_ID_FENCE 0x02 + struct drm_amdgpu_cs_chunk { uint32_t chunk_id; uint32_t length_dw; @@ -337,7 +362,7 @@ struct drm_amdgpu_cs_in { uint32_t bo_list_handle; uint32_t num_chunks; uint32_t _pad; - /* this points to uint64_t * which point to cs chunks */ + /** this points to uint64_t * which point to cs chunks */ uint64_t chunks; }; @@ -346,8 +371,8 @@ struct drm_amdgpu_cs_out { }; union drm_amdgpu_cs { - struct drm_amdgpu_cs_in in; - struct drm_amdgpu_cs_out out; + struct drm_amdgpu_cs_in in; + struct drm_amdgpu_cs_out out; }; /* Specify flags to be used for IB */ @@ -360,12 +385,18 @@ union drm_amdgpu_cs { struct drm_amdgpu_cs_chunk_ib { uint32_t _pad; - uint32_t flags; /* IB Flags */ - uint64_t va_start; /* Virtual address to begin IB execution */ - uint32_t ib_bytes; /* Size of submission */ - uint32_t ip_type; /* HW IP to submit to */ - uint32_t ip_instance; /* HW IP index of the same type to submit to */ - uint32_t ring; /* Ring index to submit to */ + /** AMDGPU_IB_FLAG_* */ + uint32_t flags; + /** Virtual address to begin IB execution */ + uint64_t va_start; + /** Size of submission */ + uint32_t ib_bytes; + /** HW IP to submit to */ + uint32_t ip_type; + /** HW IP index of the same type to submit to */ + uint32_t ip_instance; + /** Ring index to submit to */ + uint32_t ring; }; struct drm_amdgpu_cs_chunk_fence { @@ -460,23 +491,28 @@ struct drm_amdgpu_info { /** AMDGPU_HW_IP_* */ uint32_t type; /** - * Index of the IP if there are more IPs of the same type. - * Ignored by AMDGPU_INFO_HW_IP_COUNT. + * Index of the IP if there are more IPs of the same + * type. Ignored by AMDGPU_INFO_HW_IP_COUNT. */ uint32_t ip_instance; } query_hw_ip; struct { uint32_t dword_offset; - uint32_t count; /* number of registers to read */ + /** number of registers to read */ + uint32_t count; uint32_t instance; + /** For future use, no flags defined so far */ uint32_t flags; } read_mmr_reg; struct { /** AMDGPU_INFO_FW_* */ uint32_t fw_type; - /** Index of the IP if there are more IPs of the same type. */ + /** + * Index of the IP if there are more IPs of + * the same type. + */ uint32_t ip_instance; /** * Index of the engine. Whether this is used depends @@ -537,9 +573,10 @@ struct drm_amdgpu_info_device { uint32_t family; uint32_t num_shader_engines; uint32_t num_shader_arrays_per_engine; - uint32_t gpu_counter_freq; /* in KHz */ - uint64_t max_engine_clock; /* in KHz */ - uint64_t max_memory_clock; /* in KHz */ + /* in KHz */ + uint32_t gpu_counter_freq; + uint64_t max_engine_clock; + uint64_t max_memory_clock; /* cu information */ uint32_t cu_active_number; uint32_t cu_ao_mask; From 454fc95e84a20024eb5d6c0fbc5ab648bae2a56f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Jun 2015 09:58:23 -0400 Subject: [PATCH 13/23] drm/amdgpu: fix the build on big endian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some leftover copy and pastes from radeon that never got updated. Reviewed-by: Christian König Reported-by: Stephen Rothwell Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 3 ++- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index fb931638a7e6..ab83cc1ca4cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -411,7 +411,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) rb_bufsz = order_base_2(ring->ring_size / 4); rb_cntl = rb_bufsz << 1; #ifdef __BIG_ENDIAN - rb_cntl |= SDMA_RB_SWAP_ENABLE | SDMA_RPTR_WRITEBACK_SWAP_ENABLE; + rb_cntl |= SDMA0_GFX_RB_CNTL__RB_SWAP_ENABLE_MASK | + SDMA0_GFX_RB_CNTL__RPTR_WRITEBACK_SWAP_ENABLE_MASK; #endif WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index afa703c0efeb..cb7907447b81 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -2881,7 +2881,7 @@ static int gfx_v7_0_cp_gfx_resume(struct amdgpu_device *adev) rb_bufsz = order_base_2(ring->ring_size / 8); tmp = (order_base_2(AMDGPU_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; #ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; + tmp |= 2 << CP_RB0_CNTL__BUF_SWAP__SHIFT; #endif WREG32(mmCP_RB0_CNTL, tmp); @@ -3400,7 +3400,8 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev) mqd->queue_state.cp_hqd_pq_control |= (order_base_2(AMDGPU_GPU_PAGE_SIZE/8) << 8); #ifdef __BIG_ENDIAN - mqd->queue_state.cp_hqd_pq_control |= BUF_SWAP_32BIT; + mqd->queue_state.cp_hqd_pq_control |= + 2 << CP_HQD_PQ_CONTROL__ENDIAN_SWAP__SHIFT; #endif mqd->queue_state.cp_hqd_pq_control &= ~(CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK | From 5732a94f18cd69331036ab776bdf5e475702e2b4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Jun 2015 13:51:25 -0400 Subject: [PATCH 14/23] drm/admgpu: move XDMA golden registers to dce code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Already moved other display registers. Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 9 +++++++++ drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 9 +++++++++ drivers/gpu/drm/amd/amdgpu/vi.c | 4 ---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 926c8e0789b0..192dfe55b9ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -120,10 +120,19 @@ static const u32 golden_settings_tonga_a11[] = mmHDMI_CONTROL, 0x31000111, 0x00000011, }; +static const u32 tonga_mgcg_cgcg_init[] = +{ + mmXDMA_CLOCK_GATING_CNTL, 0xffffffff, 0x00000100, + mmXDMA_MEM_POWER_CNTL, 0x00000101, 0x00000000, +}; + static void dce_v10_0_init_golden_registers(struct amdgpu_device *adev) { switch (adev->asic_type) { case CHIP_TONGA: + amdgpu_program_register_sequence(adev, + tonga_mgcg_cgcg_init, + (const u32)ARRAY_SIZE(tonga_mgcg_cgcg_init)); amdgpu_program_register_sequence(adev, golden_settings_tonga_a11, (const u32)ARRAY_SIZE(golden_settings_tonga_a11)); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index bc60fd1844f3..a530c5dd1193 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -120,10 +120,19 @@ static const u32 cz_golden_settings_a11[] = mmFBC_MISC, 0x1f311fff, 0x14300000, }; +static const u32 cz_mgcg_cgcg_init[] = +{ + mmXDMA_CLOCK_GATING_CNTL, 0xffffffff, 0x00000100, + mmXDMA_MEM_POWER_CNTL, 0x00000101, 0x00000000, +}; + static void dce_v11_0_init_golden_registers(struct amdgpu_device *adev) { switch (adev->asic_type) { case CHIP_CARRIZO: + amdgpu_program_register_sequence(adev, + cz_mgcg_cgcg_init, + (const u32)ARRAY_SIZE(cz_mgcg_cgcg_init)); amdgpu_program_register_sequence(adev, cz_golden_settings_a11, (const u32)ARRAY_SIZE(cz_golden_settings_a11)); diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index be7c17610696..b71f41412f91 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -173,8 +173,6 @@ static const u32 tonga_mgcg_cgcg_init[] = mmPCIE_DATA, 0x000f0000, 0x00000000, mmSMC_IND_INDEX_4, 0xffffffff, 0xC060000C, mmSMC_IND_DATA_4, 0xc0000fff, 0x00000100, - mmXDMA_CLOCK_GATING_CNTL, 0xffffffff, 0x00000100, - mmXDMA_MEM_POWER_CNTL, 0x00000101, 0x00000000, mmCGTT_DRM_CLK_CTRL0, 0xff000fff, 0x00000100, mmHDP_XDP_CGTT_BLK_CTRL, 0xc0000fff, 0x00000104, }; @@ -193,8 +191,6 @@ static const u32 cz_mgcg_cgcg_init[] = mmCGTT_DRM_CLK_CTRL0, 0xffffffff, 0x00600100, mmPCIE_INDEX, 0xffffffff, 0x0140001c, mmPCIE_DATA, 0x000f0000, 0x00000000, - mmXDMA_CLOCK_GATING_CNTL, 0xffffffff, 0x00000100, - mmXDMA_MEM_POWER_CNTL, 0x00000101, 0x00000000, mmCGTT_DRM_CLK_CTRL0, 0xff000fff, 0x00000100, mmHDP_XDP_CGTT_BLK_CTRL, 0xc0000fff, 0x00000104, }; From c61bf649270b28526704c2101d1ebd39f51d3f0c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Jun 2015 14:06:18 -0400 Subject: [PATCH 15/23] drm/amdgpu: whitespace cleanup in gmc8 golden regs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 6206fcd39df9..8135963a66be 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -71,7 +71,7 @@ static const u32 golden_settings_iceland_a11[] = static const u32 iceland_mgcg_cgcg_init[] = { - mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104 + mmMC_MEM_POWER_LS, 0xffffffff, 0x00000104 }; static const u32 cz_mgcg_cgcg_init[] = From 6a00a09e49965d7414bacfe24adfc3f59c7d2647 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Jun 2015 14:33:03 -0400 Subject: [PATCH 16/23] drm/amdgpu: update to latest gfx8 golden register settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 70cc6bd48926..14242bd33363 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -116,11 +116,14 @@ static const u32 golden_settings_tonga_a11[] = mmPA_SC_ENHANCE, 0xffffffff, 0x20000001, mmPA_SC_FIFO_DEPTH_CNTL, 0x000003ff, 0x000000fc, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000, + mmSQ_RANDOM_WAVE_PRI, 0x001fffff, 0x000006fd, mmTA_CNTL_AUX, 0x000f000f, 0x000b0000, mmTCC_CTRL, 0x00100000, 0xf31fff7f, + mmTCC_EXE_DISABLE, 0x00000002, 0x00000002, mmTCP_ADDR_CONFIG, 0x000003ff, 0x000002fb, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x0000543b, mmTCP_CHAN_STEER_LO, 0xffffffff, 0xa9210876, + mmVGT_RESET_DEBUG, 0x00000004, 0x00000004, }; static const u32 tonga_golden_common_all[] = @@ -224,8 +227,10 @@ static const u32 golden_settings_iceland_a11[] = mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000, mmPA_SC_RASTER_CONFIG, 0x3f3fffff, 0x00000002, mmPA_SC_RASTER_CONFIG_1, 0x0000003f, 0x00000000, + mmSQ_RANDOM_WAVE_PRI, 0x001fffff, 0x000006fd, mmTA_CNTL_AUX, 0x000f000f, 0x000b0000, mmTCC_CTRL, 0x00100000, 0xf31fff7f, + mmTCC_EXE_DISABLE, 0x00000002, 0x00000002, mmTCP_ADDR_CONFIG, 0x000003ff, 0x000000f1, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x00000000, mmTCP_CHAN_STEER_LO, 0xffffffff, 0x00000010, @@ -318,7 +323,9 @@ static const u32 cz_golden_settings_a11[] = mmGB_GPU_ID, 0x0000000f, 0x00000000, mmPA_SC_ENHANCE, 0xffffffff, 0x00000001, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000, + mmSQ_RANDOM_WAVE_PRI, 0x001fffff, 0x000006fd, mmTA_CNTL_AUX, 0x000f000f, 0x00010000, + mmTCC_EXE_DISABLE, 0x00000002, 0x00000002, mmTCP_ADDR_CONFIG, 0x0000000f, 0x000000f3, mmTCP_CHAN_STEER_LO, 0xffffffff, 0x00001302 }; From 05188312e2ea8991c75bc4ae947d4dc1e7a3bb17 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Jun 2015 17:32:53 -0400 Subject: [PATCH 17/23] drm/amdgpu/cz: don't call smu_init on resume smu_init allocates buffers and initializes them. It does not touch the hw. There is no need to do it again on resume. It should really be part of sw_init (and smu_fini should be part of sw_fini), but we need the firmware sizes from the other IPs for firmware loading so we have to wait until sw init is done for all other IPs. Reviewed-by: Sonny Jiang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index f275b5d2d060..131b4733b112 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c @@ -1230,7 +1230,10 @@ static int cz_dpm_hw_init(void *handle) mutex_lock(&adev->pm.mutex); - /* init smc in dpm hw init */ + /* smu init only needs to be called at startup, not resume. + * It should be in sw_init, but requires the fw info gathered + * in sw_init from other IP modules. + */ ret = cz_smu_init(adev); if (ret) { DRM_ERROR("amdgpu: smc initialization failed\n"); @@ -1297,6 +1300,10 @@ static int cz_dpm_hw_fini(void *handle) mutex_lock(&adev->pm.mutex); + /* smu fini only needs to be called at teardown, not suspend. + * It should be in sw_fini, but we put it here for symmetry + * with smu init. + */ cz_smu_fini(adev); if (adev->pm.dpm_enabled) { @@ -1340,12 +1347,6 @@ static int cz_dpm_resume(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; mutex_lock(&adev->pm.mutex); - ret = cz_smu_init(adev); - if (ret) { - DRM_ERROR("amdgpu: smc resume failed\n"); - mutex_unlock(&adev->pm.mutex); - return ret; - } /* do the actual fw loading */ ret = cz_smu_start(adev); From aaf4ee3c0233893ac9586ede9cdcaa4a77ccb475 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Jun 2015 17:42:10 -0400 Subject: [PATCH 18/23] drm/amdgpu/tonga: don't call smu_init on resume smu_init allocates buffers and initializes them. It does not touch the hw. There is no need to do it again on resume. It should really be part of sw_init (and smu_fini should be part of sw_fini), but we need the firmware sizes from the other IPs for firmware loading so we have to wait until sw init is done for all other IPs. Reviewed-by: Sonny Jiang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/tonga_dpm.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c index 2d5b1bd52afa..204903897b4f 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c @@ -81,6 +81,10 @@ static int tonga_dpm_hw_init(void *handle) mutex_lock(&adev->pm.mutex); + /* smu init only needs to be called at startup, not resume. + * It should be in sw_init, but requires the fw info gathered + * in sw_init from other IP modules. + */ ret = tonga_smu_init(adev); if (ret) { DRM_ERROR("SMU initialization failed\n"); @@ -107,6 +111,10 @@ static int tonga_dpm_hw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; mutex_lock(&adev->pm.mutex); + /* smu fini only needs to be called at teardown, not suspend. + * It should be in sw_fini, but we put it here for symmetry + * with smu init. + */ tonga_smu_fini(adev); mutex_unlock(&adev->pm.mutex); return 0; @@ -114,20 +122,25 @@ static int tonga_dpm_hw_fini(void *handle) static int tonga_dpm_suspend(void *handle) { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - - tonga_dpm_hw_fini(adev); - return 0; } static int tonga_dpm_resume(void *handle) { + int ret; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - tonga_dpm_hw_init(adev); + mutex_lock(&adev->pm.mutex); - return 0; + ret = tonga_smu_start(adev); + if (ret) { + DRM_ERROR("SMU start failed\n"); + goto fail; + } + +fail: + mutex_unlock(&adev->pm.mutex); + return ret; } static int tonga_dpm_set_clockgating_state(void *handle, From b97aab014c6ba6133df1e26bd20c1ad7f50a5bff Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 9 Jun 2015 17:46:30 -0400 Subject: [PATCH 19/23] drm/amdgpu/iceland: don't call smu_init on resume smu_init allocates buffers and initializes them. It does not touch the hw. There is no need to do it again on resume. It should really be part of sw_init (and smu_fini should be part of sw_fini), but we need the firmware sizes from the other IPs for firmware loading so we have to wait until sw init is done for all other IPs. Reviewed-by: Sonny Jiang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/iceland_dpm.c | 25 ++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c index 4b773f29167a..208d55f41c7f 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c @@ -82,6 +82,10 @@ static int iceland_dpm_hw_init(void *handle) mutex_lock(&adev->pm.mutex); + /* smu init only needs to be called at startup, not resume. + * It should be in sw_init, but requires the fw info gathered + * in sw_init from other IP modules. + */ ret = iceland_smu_init(adev); if (ret) { DRM_ERROR("SMU initialization failed\n"); @@ -108,6 +112,10 @@ static int iceland_dpm_hw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; mutex_lock(&adev->pm.mutex); + /* smu fini only needs to be called at teardown, not suspend. + * It should be in sw_fini, but we put it here for symmetry + * with smu init. + */ iceland_smu_fini(adev); mutex_unlock(&adev->pm.mutex); return 0; @@ -115,20 +123,25 @@ static int iceland_dpm_hw_fini(void *handle) static int iceland_dpm_suspend(void *handle) { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - - iceland_dpm_hw_fini(adev); - return 0; } static int iceland_dpm_resume(void *handle) { + int ret; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - iceland_dpm_hw_init(adev); + mutex_lock(&adev->pm.mutex); - return 0; + ret = iceland_smu_start(adev); + if (ret) { + DRM_ERROR("SMU start failed\n"); + goto fail; + } + +fail: + mutex_unlock(&adev->pm.mutex); + return ret; } static int iceland_dpm_set_clockgating_state(void *handle, From b7a0776949a8f9db835ab652b6fa96b6e7d6972d Mon Sep 17 00:00:00 2001 From: Sonny Jiang Date: Thu, 28 May 2015 15:47:53 -0400 Subject: [PATCH 20/23] drm/amdgpu: enable vce powergating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable VCE dpm and powergating. VCE dpm dynamically scales the VCE clocks on demand. Signed-off-by: Sonny Jiang Reviewed-by: Alex Deucher Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 26 +++-- drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 132 ++++++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/vi.c | 2 +- 4 files changed, 148 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 37aeed7b454d..22866d1c3d69 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1509,6 +1509,7 @@ struct amdgpu_dpm_funcs { int (*force_performance_level)(struct amdgpu_device *adev, enum amdgpu_dpm_forced_level level); bool (*vblank_too_short)(struct amdgpu_device *adev); void (*powergate_uvd)(struct amdgpu_device *adev, bool gate); + void (*powergate_vce)(struct amdgpu_device *adev, bool gate); void (*enable_bapm)(struct amdgpu_device *adev, bool enable); void (*set_fan_control_mode)(struct amdgpu_device *adev, u32 mode); u32 (*get_fan_control_mode)(struct amdgpu_device *adev); @@ -2182,6 +2183,7 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) #define amdgpu_dpm_force_performance_level(adev, l) (adev)->pm.funcs->force_performance_level((adev), (l)) #define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev)) #define amdgpu_dpm_powergate_uvd(adev, g) (adev)->pm.funcs->powergate_uvd((adev), (g)) +#define amdgpu_dpm_powergate_vce(adev, g) (adev)->pm.funcs->powergate_vce((adev), (g)) #define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e)) #define amdgpu_dpm_set_fan_control_mode(adev, m) (adev)->pm.funcs->set_fan_control_mode((adev), (m)) #define amdgpu_dpm_get_fan_control_mode(adev) (adev)->pm.funcs->get_fan_control_mode((adev)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 605a9e42f943..ed13baa7c976 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -656,19 +656,27 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) { - if (enable) { + if (adev->pm.funcs->powergate_vce) { mutex_lock(&adev->pm.mutex); - adev->pm.dpm.vce_active = true; - /* XXX select vce level based on ring/task */ - adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL; + /* enable/disable VCE */ + amdgpu_dpm_powergate_vce(adev, !enable); + mutex_unlock(&adev->pm.mutex); } else { - mutex_lock(&adev->pm.mutex); - adev->pm.dpm.vce_active = false; - mutex_unlock(&adev->pm.mutex); - } + if (enable) { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.vce_active = true; + /* XXX select vce level based on ring/task */ + adev->pm.dpm.vce_level = AMDGPU_VCE_LEVEL_AC_ALL; + mutex_unlock(&adev->pm.mutex); + } else { + mutex_lock(&adev->pm.mutex); + adev->pm.dpm.vce_active = false; + mutex_unlock(&adev->pm.mutex); + } - amdgpu_pm_compute_clocks(adev); + amdgpu_pm_compute_clocks(adev); + } } void amdgpu_pm_print_power_states(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 131b4733b112..10a387424ff8 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c @@ -43,6 +43,7 @@ #include "gfx_v8_0.h" static void cz_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate); +static void cz_dpm_powergate_vce(struct amdgpu_device *adev, bool gate); static struct cz_ps *cz_get_ps(struct amdgpu_ps *rps) { @@ -558,6 +559,7 @@ static int cz_dpm_late_init(void *handle) /* powerdown unused blocks for now */ cz_dpm_powergate_uvd(adev, true); + cz_dpm_powergate_vce(adev, true); return 0; } @@ -826,16 +828,16 @@ static void cz_init_vce_limit(struct amdgpu_device *adev) return; } - pi->vce_dpm.soft_min_clk = 0; - pi->vce_dpm.hard_min_clk = 0; + pi->vce_dpm.soft_min_clk = table->entries[0].ecclk; + pi->vce_dpm.hard_min_clk = table->entries[0].ecclk; cz_send_msg_to_smc(adev, PPSMC_MSG_GetMaxEclkLevel); level = cz_get_argument(adev); if (level < table->count) - clock = table->entries[level].evclk; + clock = table->entries[level].ecclk; else { /* future BIOS would fix this error */ DRM_ERROR("Invalid VCE Voltage Dependency table entry.\n"); - clock = table->entries[table->count - 1].evclk; + clock = table->entries[table->count - 1].ecclk; } pi->vce_dpm.soft_max_clk = clock; @@ -1004,6 +1006,36 @@ static uint32_t cz_get_sclk_level(struct amdgpu_device *adev, return i; } +static uint32_t cz_get_eclk_level(struct amdgpu_device *adev, + uint32_t clock, uint16_t msg) +{ + int i = 0; + struct amdgpu_vce_clock_voltage_dependency_table *table = + &adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; + + if (table->count == 0) + return 0; + + switch (msg) { + case PPSMC_MSG_SetEclkSoftMin: + case PPSMC_MSG_SetEclkHardMin: + for (i = 0; i < table->count-1; i++) + if (clock <= table->entries[i].ecclk) + break; + break; + case PPSMC_MSG_SetEclkSoftMax: + case PPSMC_MSG_SetEclkHardMax: + for (i = table->count - 1; i > 0; i--) + if (clock >= table->entries[i].ecclk) + break; + break; + default: + break; + } + + return i; +} + static int cz_program_bootup_state(struct amdgpu_device *adev) { struct cz_power_info *pi = cz_get_pi(adev); @@ -1285,6 +1317,7 @@ static int cz_dpm_disable(struct amdgpu_device *adev) /* powerup blocks */ cz_dpm_powergate_uvd(adev, false); + cz_dpm_powergate_vce(adev, false); cz_clear_voting_clients(adev); cz_stop_dpm(adev); @@ -1775,6 +1808,96 @@ static void cz_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate) } } +static int cz_enable_vce_dpm(struct amdgpu_device *adev, bool enable) +{ + struct cz_power_info *pi = cz_get_pi(adev); + int ret = 0; + + if (enable && pi->caps_vce_dpm) { + pi->dpm_flags |= DPMFlags_VCE_Enabled; + DRM_DEBUG("VCE DPM Enabled.\n"); + + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_EnableAllSmuFeatures, VCE_DPM_MASK); + + } else { + pi->dpm_flags &= ~DPMFlags_VCE_Enabled; + DRM_DEBUG("VCE DPM Stopped\n"); + + ret = cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_DisableAllSmuFeatures, VCE_DPM_MASK); + } + + return ret; +} + +static int cz_update_vce_dpm(struct amdgpu_device *adev) +{ + struct cz_power_info *pi = cz_get_pi(adev); + struct amdgpu_vce_clock_voltage_dependency_table *table = + &adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; + + /* Stable Pstate is enabled and we need to set the VCE DPM to highest level */ + if (pi->caps_stable_power_state) { + pi->vce_dpm.hard_min_clk = table->entries[table->count-1].ecclk; + + } else { /* non-stable p-state cases. without vce.Arbiter.EcclkHardMin */ + pi->vce_dpm.hard_min_clk = table->entries[0].ecclk; + } + + cz_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SetEclkHardMin, + cz_get_eclk_level(adev, + pi->vce_dpm.hard_min_clk, + PPSMC_MSG_SetEclkHardMin)); + return 0; +} + +static void cz_dpm_powergate_vce(struct amdgpu_device *adev, bool gate) +{ + struct cz_power_info *pi = cz_get_pi(adev); + + if (pi->caps_vce_pg) { + if (pi->vce_power_gated != gate) { + if (gate) { + /* disable clockgating so we can properly shut down the block */ + amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_CG_STATE_UNGATE); + /* shutdown the VCE block */ + amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_GATE); + + cz_enable_vce_dpm(adev, false); + /* TODO: to figure out why vce can't be poweroff. */ + /* cz_send_msg_to_smc(adev, PPSMC_MSG_VCEPowerOFF); */ + pi->vce_power_gated = true; + } else { + cz_send_msg_to_smc(adev, PPSMC_MSG_VCEPowerON); + pi->vce_power_gated = false; + + /* re-init the VCE block */ + amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_UNGATE); + /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */ + amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_CG_STATE_GATE); + + cz_update_vce_dpm(adev); + cz_enable_vce_dpm(adev, true); + } + } else { + if (! pi->vce_power_gated) { + cz_update_vce_dpm(adev); + } + } + } else { /*pi->caps_vce_pg*/ + cz_update_vce_dpm(adev); + cz_enable_vce_dpm(adev, true); + } + + return; +} + const struct amd_ip_funcs cz_dpm_ip_funcs = { .early_init = cz_dpm_early_init, .late_init = cz_dpm_late_init, @@ -1806,6 +1929,7 @@ static const struct amdgpu_dpm_funcs cz_dpm_funcs = { .force_performance_level = cz_dpm_force_dpm_level, .vblank_too_short = NULL, .powergate_uvd = cz_dpm_powergate_uvd, + .powergate_vce = cz_dpm_powergate_vce, }; static void cz_dpm_set_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index b71f41412f91..90fc93c2c1d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -1263,7 +1263,7 @@ static int vi_common_early_init(void *handle) case CHIP_CARRIZO: adev->has_uvd = true; adev->cg_flags = 0; - adev->pg_flags = AMDGPU_PG_SUPPORT_UVD; + adev->pg_flags = AMDGPU_PG_SUPPORT_UVD | AMDGPU_PG_SUPPORT_VCE; adev->external_rev_id = adev->rev_id + 0x1; if (amdgpu_smc_load_fw && smc_enabled) adev->firmware.smu_load = true; From 4802ce11778664a69b308c5aa9b95350b76793be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 10 Jun 2015 17:20:11 +0200 Subject: [PATCH 21/23] drm/amdgpu: fix UVD/VCE VM emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index f6b224a69b3a..f09b2cba40ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -564,21 +564,33 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, return r; if (ring->funcs->parse_cs) { + struct amdgpu_bo_va_mapping *m; struct amdgpu_bo *aobj = NULL; - void *kptr; + uint64_t offset; + uint8_t *kptr; - amdgpu_cs_find_mapping(parser, chunk_ib->va_start, &aobj); + m = amdgpu_cs_find_mapping(parser, chunk_ib->va_start, + &aobj); if (!aobj) { DRM_ERROR("IB va_start is invalid\n"); return -EINVAL; } + if ((chunk_ib->va_start + chunk_ib->ib_bytes) > + (m->it.last + 1) * AMDGPU_GPU_PAGE_SIZE) { + DRM_ERROR("IB va_start+ib_bytes is invalid\n"); + return -EINVAL; + } + /* the IB should be reserved at this point */ - r = amdgpu_bo_kmap(aobj, &kptr); + r = amdgpu_bo_kmap(aobj, (void **)&kptr); if (r) { return r; } + offset = ((uint64_t)m->it.start) * AMDGPU_GPU_PAGE_SIZE; + kptr += chunk_ib->va_start - offset; + r = amdgpu_ib_get(ring, NULL, chunk_ib->ib_bytes, ib); if (r) { DRM_ERROR("Failed to get ib !\n"); From 633ed3df9a65614f14e756424aaff0d317b1b637 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 10 Jun 2015 11:52:00 -0400 Subject: [PATCH 22/23] drm/amdgpu: don't enable/disable display twice on suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were doing it in the common code and in the IP specific code. Remove the IP specific code. The common code handles the ordering properly. Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 18 ------------------ drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 18 ------------------ drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 18 ------------------ 3 files changed, 54 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 192dfe55b9ab..5cde635978f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -3017,16 +3017,8 @@ static int dce_v10_0_hw_fini(void *handle) static int dce_v10_0_suspend(void *handle) { - struct drm_connector *connector; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - drm_kms_helper_poll_disable(adev->ddev); - - /* turn off display hw */ - list_for_each_entry(connector, &adev->ddev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - } - amdgpu_atombios_scratch_regs_save(adev); dce_v10_0_hpd_fini(adev); @@ -3036,7 +3028,6 @@ static int dce_v10_0_suspend(void *handle) static int dce_v10_0_resume(void *handle) { - struct drm_connector *connector; struct amdgpu_device *adev = (struct amdgpu_device *)handle; dce_v10_0_init_golden_registers(adev); @@ -3057,15 +3048,6 @@ static int dce_v10_0_resume(void *handle) /* initialize hpd */ dce_v10_0_hpd_init(adev); - /* blat the mode back in */ - drm_helper_resume_force_mode(adev->ddev); - /* turn on display hw */ - list_for_each_entry(connector, &adev->ddev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - - drm_kms_helper_poll_enable(adev->ddev); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index a530c5dd1193..95efd98b202d 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -3015,16 +3015,8 @@ static int dce_v11_0_hw_fini(void *handle) static int dce_v11_0_suspend(void *handle) { - struct drm_connector *connector; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - drm_kms_helper_poll_disable(adev->ddev); - - /* turn off display hw */ - list_for_each_entry(connector, &adev->ddev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - } - amdgpu_atombios_scratch_regs_save(adev); dce_v11_0_hpd_fini(adev); @@ -3034,7 +3026,6 @@ static int dce_v11_0_suspend(void *handle) static int dce_v11_0_resume(void *handle) { - struct drm_connector *connector; struct amdgpu_device *adev = (struct amdgpu_device *)handle; dce_v11_0_init_golden_registers(adev); @@ -3056,15 +3047,6 @@ static int dce_v11_0_resume(void *handle) /* initialize hpd */ dce_v11_0_hpd_init(adev); - /* blat the mode back in */ - drm_helper_resume_force_mode(adev->ddev); - /* turn on display hw */ - list_for_each_entry(connector, &adev->ddev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - - drm_kms_helper_poll_enable(adev->ddev); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 9e8b9f1fad18..72c27ac915f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -2948,16 +2948,8 @@ static int dce_v8_0_hw_fini(void *handle) static int dce_v8_0_suspend(void *handle) { - struct drm_connector *connector; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - drm_kms_helper_poll_disable(adev->ddev); - - /* turn off display hw */ - list_for_each_entry(connector, &adev->ddev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - } - amdgpu_atombios_scratch_regs_save(adev); dce_v8_0_hpd_fini(adev); @@ -2967,7 +2959,6 @@ static int dce_v8_0_suspend(void *handle) static int dce_v8_0_resume(void *handle) { - struct drm_connector *connector; struct amdgpu_device *adev = (struct amdgpu_device *)handle; amdgpu_atombios_scratch_regs_restore(adev); @@ -2986,15 +2977,6 @@ static int dce_v8_0_resume(void *handle) /* initialize hpd */ dce_v8_0_hpd_init(adev); - /* blat the mode back in */ - drm_helper_resume_force_mode(adev->ddev); - /* turn on display hw */ - list_for_each_entry(connector, &adev->ddev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - - drm_kms_helper_poll_enable(adev->ddev); - return 0; } From 6d8db6ce239587c3d300d79fce3f5bb376232475 Mon Sep 17 00:00:00 2001 From: Sonny Jiang Date: Wed, 10 Jun 2015 13:46:36 -0400 Subject: [PATCH 23/23] drm/amdgpu: fix a amdgpu_dpm=0 bug Signed-off-by: Sonny Jiang Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 10a387424ff8..e4936a452bc6 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c @@ -557,9 +557,11 @@ static int cz_dpm_late_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - /* powerdown unused blocks for now */ - cz_dpm_powergate_uvd(adev, true); - cz_dpm_powergate_vce(adev, true); + if (amdgpu_dpm) { + /* powerdown unused blocks for now */ + cz_dpm_powergate_uvd(adev, true); + cz_dpm_powergate_vce(adev, true); + } return 0; }