diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 8a440b9fa0fdc691076b141eda6ebd6d2296f5cd..44f62fda40228b9fcce899ab5a3497cdada714c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -73,6 +73,7 @@ #include "amdgpu_virt.h" #include "amdgpu_gart.h" #include "amdgpu_debugfs.h" +#include "amdgpu_job.h" /* * Modules parameters. @@ -105,11 +106,8 @@ extern int amdgpu_vm_fault_stop; extern int amdgpu_vm_debug; extern int amdgpu_vm_update_mode; extern int amdgpu_dc; -extern int amdgpu_dc_log; extern int amdgpu_sched_jobs; extern int amdgpu_sched_hw_submission; -extern int amdgpu_no_evict; -extern int amdgpu_direct_gma_size; extern uint amdgpu_pcie_gen_cap; extern uint amdgpu_pcie_lane_cap; extern uint amdgpu_cg_mask; @@ -600,17 +598,6 @@ struct amdgpu_ib { extern const struct drm_sched_backend_ops amdgpu_sched_ops; -int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, - struct amdgpu_job **job, struct amdgpu_vm *vm); -int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, - struct amdgpu_job **job); - -void amdgpu_job_free_resources(struct amdgpu_job *job); -void amdgpu_job_free(struct amdgpu_job *job); -int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, - struct drm_sched_entity *entity, void *owner, - struct dma_fence **f); - /* * Queue manager */ @@ -732,6 +719,14 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, struct list_head *validated); void amdgpu_bo_list_put(struct amdgpu_bo_list *list); void amdgpu_bo_list_free(struct amdgpu_bo_list *list); +int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, + struct drm_amdgpu_bo_list_entry **info_param); + +int amdgpu_bo_list_create(struct amdgpu_device *adev, + struct drm_file *filp, + struct drm_amdgpu_bo_list_entry *info, + unsigned num_entries, + struct amdgpu_bo_list **list); /* * GFX stuff @@ -1029,6 +1024,7 @@ struct amdgpu_cs_parser { /* scheduler job object */ struct amdgpu_job *job; + struct amdgpu_ring *ring; /* buffer objects */ struct ww_acquire_ctx ticket; @@ -1050,40 +1046,6 @@ struct amdgpu_cs_parser { struct drm_syncobj **post_dep_syncobjs; }; -#define AMDGPU_PREAMBLE_IB_PRESENT (1 << 0) /* bit set means command submit involves a preamble IB */ -#define AMDGPU_PREAMBLE_IB_PRESENT_FIRST (1 << 1) /* bit set means preamble IB is first presented in belonging context */ -#define AMDGPU_HAVE_CTX_SWITCH (1 << 2) /* bit set means context switch occured */ - -struct amdgpu_job { - struct drm_sched_job base; - struct amdgpu_device *adev; - struct amdgpu_vm *vm; - struct amdgpu_ring *ring; - struct amdgpu_sync sync; - struct amdgpu_sync sched_sync; - struct amdgpu_ib *ibs; - struct dma_fence *fence; /* the hw fence */ - uint32_t preamble_status; - uint32_t num_ibs; - void *owner; - uint64_t fence_ctx; /* the fence_context this job uses */ - bool vm_needs_flush; - uint64_t vm_pd_addr; - unsigned vmid; - unsigned pasid; - uint32_t gds_base, gds_size; - uint32_t gws_base, gws_size; - uint32_t oa_base, oa_size; - uint32_t vram_lost_counter; - - /* user fence handling */ - uint64_t uf_addr; - uint64_t uf_sequence; - -}; -#define to_amdgpu_job(sched_job) \ - container_of((sched_job), struct amdgpu_job, base) - static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, uint32_t ib_idx, int idx) { @@ -1398,6 +1360,7 @@ enum amd_hw_ip_block_type { PWR_HWIP, NBIF_HWIP, THM_HWIP, + CLK_HWIP, MAX_HWIP }; @@ -1588,9 +1551,9 @@ struct amdgpu_device { DECLARE_HASHTABLE(mn_hash, 7); /* tracking pinned memory */ - u64 vram_pin_size; - u64 invisible_pin_size; - u64 gart_pin_size; + atomic64_t vram_pin_size; + atomic64_t visible_pin_size; + atomic64_t gart_pin_size; /* amdkfd interface */ struct kfd_dev *kfd; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 305143fcc1ceed0d1231efa742864de460b608d0..e3ed08dca7b7d2e6ff8ef7c486dd2e5917834d9b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -251,7 +251,6 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, struct amdgpu_bo *bo = NULL; struct amdgpu_bo_param bp; int r; - uint64_t gpu_addr_tmp = 0; void *cpu_ptr_tmp = NULL; memset(&bp, 0, sizeof(bp)); @@ -275,13 +274,18 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, goto allocate_mem_reserve_bo_failed; } - r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, - &gpu_addr_tmp); + r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); if (r) { dev_err(adev->dev, "(%d) failed to pin bo for amdkfd\n", r); goto allocate_mem_pin_bo_failed; } + r = amdgpu_ttm_alloc_gart(&bo->tbo); + if (r) { + dev_err(adev->dev, "%p bind failed\n", bo); + goto allocate_mem_kmap_bo_failed; + } + r = amdgpu_bo_kmap(bo, &cpu_ptr_tmp); if (r) { dev_err(adev->dev, @@ -290,7 +294,7 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, } *mem_obj = bo; - *gpu_addr = gpu_addr_tmp; + *gpu_addr = amdgpu_bo_gpu_offset(bo); *cpu_ptr = cpu_ptr_tmp; amdgpu_bo_unreserve(bo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index ff8fd75f7ca51fcd74587683c84a2a60a1439f64..079af8ac2636d6d9a921236f15d044b80401b1b4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1587,7 +1587,7 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd, goto bo_reserve_failed; } - ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL); + ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); if (ret) { pr_err("Failed to pin bo. ret %d\n", ret); goto pin_failed; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c index 19cfff31f2e161f6cc6e884a9c110cfb33586a9f..3079ea8523c55db1110e55a98b81dcbca667e576 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c @@ -95,11 +95,17 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, r = amdgpu_bo_reserve(sobj, false); if (unlikely(r != 0)) goto out_cleanup; - r = amdgpu_bo_pin(sobj, sdomain, &saddr); + r = amdgpu_bo_pin(sobj, sdomain); + if (r) { + amdgpu_bo_unreserve(sobj); + goto out_cleanup; + } + r = amdgpu_ttm_alloc_gart(&sobj->tbo); amdgpu_bo_unreserve(sobj); if (r) { goto out_cleanup; } + saddr = amdgpu_bo_gpu_offset(sobj); bp.domain = ddomain; r = amdgpu_bo_create(adev, &bp, &dobj); if (r) { @@ -108,11 +114,17 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, r = amdgpu_bo_reserve(dobj, false); if (unlikely(r != 0)) goto out_cleanup; - r = amdgpu_bo_pin(dobj, ddomain, &daddr); + r = amdgpu_bo_pin(dobj, ddomain); + if (r) { + amdgpu_bo_unreserve(sobj); + goto out_cleanup; + } + r = amdgpu_ttm_alloc_gart(&dobj->tbo); amdgpu_bo_unreserve(dobj); if (r) { goto out_cleanup; } + daddr = amdgpu_bo_gpu_offset(dobj); if (adev->mman.buffer_funcs) { time = amdgpu_benchmark_do_move(adev, size, saddr, daddr, n); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 92be7f6de197372beb1a12a0ad1816bd62f738a1..7679c068c89a82b8225e463c252112e3ed318242 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -55,15 +55,15 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref) kfree_rcu(list, rhead); } -static int amdgpu_bo_list_create(struct amdgpu_device *adev, +int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info, unsigned num_entries, - int *id) + struct amdgpu_bo_list **list_out) { - int r; - struct amdgpu_fpriv *fpriv = filp->driver_priv; struct amdgpu_bo_list *list; + int r; + list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL); if (!list) @@ -78,16 +78,7 @@ static int amdgpu_bo_list_create(struct amdgpu_device *adev, return r; } - /* idr alloc should be called only after initialization of bo list. */ - mutex_lock(&fpriv->bo_list_lock); - r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL); - mutex_unlock(&fpriv->bo_list_lock); - if (r < 0) { - amdgpu_bo_list_free(list); - return r; - } - *id = r; - + *list_out = list; return 0; } @@ -263,55 +254,79 @@ void amdgpu_bo_list_free(struct amdgpu_bo_list *list) kfree(list); } -int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) +int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, + struct drm_amdgpu_bo_list_entry **info_param) { + const void __user *uptr = u64_to_user_ptr(in->bo_info_ptr); const uint32_t info_size = sizeof(struct drm_amdgpu_bo_list_entry); - - struct amdgpu_device *adev = dev->dev_private; - struct amdgpu_fpriv *fpriv = filp->driver_priv; - union drm_amdgpu_bo_list *args = data; - uint32_t handle = args->in.list_handle; - const void __user *uptr = u64_to_user_ptr(args->in.bo_info_ptr); - struct drm_amdgpu_bo_list_entry *info; - struct amdgpu_bo_list *list; - int r; - info = kvmalloc_array(args->in.bo_number, - sizeof(struct drm_amdgpu_bo_list_entry), GFP_KERNEL); + info = kvmalloc_array(in->bo_number, info_size, GFP_KERNEL); if (!info) return -ENOMEM; /* copy the handle array from userspace to a kernel buffer */ r = -EFAULT; - if (likely(info_size == args->in.bo_info_size)) { - unsigned long bytes = args->in.bo_number * - args->in.bo_info_size; + if (likely(info_size == in->bo_info_size)) { + unsigned long bytes = in->bo_number * + in->bo_info_size; if (copy_from_user(info, uptr, bytes)) goto error_free; } else { - unsigned long bytes = min(args->in.bo_info_size, info_size); + unsigned long bytes = min(in->bo_info_size, info_size); unsigned i; - memset(info, 0, args->in.bo_number * info_size); - for (i = 0; i < args->in.bo_number; ++i) { + memset(info, 0, in->bo_number * info_size); + for (i = 0; i < in->bo_number; ++i) { if (copy_from_user(&info[i], uptr, bytes)) goto error_free; - uptr += args->in.bo_info_size; + uptr += in->bo_info_size; } } + *info_param = info; + return 0; + +error_free: + kvfree(info); + return r; +} + +int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + struct amdgpu_device *adev = dev->dev_private; + struct amdgpu_fpriv *fpriv = filp->driver_priv; + union drm_amdgpu_bo_list *args = data; + uint32_t handle = args->in.list_handle; + struct drm_amdgpu_bo_list_entry *info = NULL; + struct amdgpu_bo_list *list; + int r; + + r = amdgpu_bo_create_list_entry_array(&args->in, &info); + if (r) + goto error_free; + switch (args->in.operation) { case AMDGPU_BO_LIST_OP_CREATE: r = amdgpu_bo_list_create(adev, filp, info, args->in.bo_number, - &handle); + &list); if (r) goto error_free; + + mutex_lock(&fpriv->bo_list_lock); + r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL); + mutex_unlock(&fpriv->bo_list_lock); + if (r < 0) { + amdgpu_bo_list_free(list); + return r; + } + + handle = r; break; case AMDGPU_BO_LIST_OP_DESTROY: @@ -345,6 +360,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, return 0; error_free: - kvfree(info); + if (info) + kvfree(info); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 7a625f3989a00166c5d12a3db1ce41e0887934ee..7c5cc33d0cda06d8cc93127a7374c1132ae3152c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -66,11 +66,35 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, return 0; } -static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) +static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p, + struct drm_amdgpu_bo_list_in *data) +{ + int r; + struct drm_amdgpu_bo_list_entry *info = NULL; + + r = amdgpu_bo_create_list_entry_array(data, &info); + if (r) + return r; + + r = amdgpu_bo_list_create(p->adev, p->filp, info, data->bo_number, + &p->bo_list); + if (r) + goto error_free; + + kvfree(info); + return 0; + +error_free: + if (info) + kvfree(info); + + return r; +} + +static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) { struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_vm *vm = &fpriv->vm; - union drm_amdgpu_cs *cs = data; uint64_t *chunk_array_user; uint64_t *chunk_array; unsigned size, num_ibs = 0; @@ -164,6 +188,19 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) break; + case AMDGPU_CHUNK_ID_BO_HANDLES: + size = sizeof(struct drm_amdgpu_bo_list_in); + if (p->chunks[i].length_dw * sizeof(uint32_t) < size) { + ret = -EINVAL; + goto free_partial_kdata; + } + + ret = amdgpu_cs_bo_handles_chunk(p, p->chunks[i].kdata); + if (ret) + goto free_partial_kdata; + + break; + case AMDGPU_CHUNK_ID_DEPENDENCIES: case AMDGPU_CHUNK_ID_SYNCOBJ_IN: case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: @@ -187,6 +224,10 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) if (p->uf_entry.robj) p->job->uf_addr = uf_offset; kfree(chunk_array); + + /* Use this opportunity to fill in task info for the vm */ + amdgpu_vm_set_task_info(vm); + return 0; free_all_kdata: @@ -258,7 +299,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, return; } - total_vram = adev->gmc.real_vram_size - adev->vram_pin_size; + total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size); used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; @@ -530,7 +571,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, INIT_LIST_HEAD(&p->validated); - p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); + /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */ + if (!p->bo_list) + p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); + else + mutex_lock(&p->bo_list->lock); + if (p->bo_list) { amdgpu_bo_list_get_list(p->bo_list, &p->validated); if (p->bo_list->first_userptr != p->bo_list->num_entries) @@ -866,11 +912,11 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, { struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_vm *vm = &fpriv->vm; - struct amdgpu_ring *ring = p->job->ring; + struct amdgpu_ring *ring = p->ring; int r; /* Only for UVD/VCE VM emulation */ - if (p->job->ring->funcs->parse_cs) { + if (p->ring->funcs->parse_cs) { unsigned i, j; for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) { @@ -928,6 +974,10 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, r = amdgpu_bo_vm_update_pte(p); if (r) return r; + + r = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv); + if (r) + return r; } return amdgpu_cs_sync_rings(p); @@ -980,10 +1030,10 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, } } - if (parser->job->ring && parser->job->ring != ring) + if (parser->ring && parser->ring != ring) return -EINVAL; - parser->job->ring = ring; + parser->ring = ring; r = amdgpu_ib_get(adev, vm, ring->funcs->parse_cs ? chunk_ib->ib_bytes : 0, @@ -1002,11 +1052,11 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, /* UVD & VCE fw doesn't support user fences */ if (parser->job->uf_addr && ( - parser->job->ring->funcs->type == AMDGPU_RING_TYPE_UVD || - parser->job->ring->funcs->type == AMDGPU_RING_TYPE_VCE)) + parser->ring->funcs->type == AMDGPU_RING_TYPE_UVD || + parser->ring->funcs->type == AMDGPU_RING_TYPE_VCE)) return -EINVAL; - return amdgpu_ctx_wait_prev_fence(parser->ctx, parser->job->ring->idx); + return amdgpu_ctx_wait_prev_fence(parser->ctx, parser->ring->idx); } static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, @@ -1157,8 +1207,9 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) { - struct amdgpu_ring *ring = p->job->ring; + struct amdgpu_ring *ring = p->ring; struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity; + enum drm_sched_priority priority; struct amdgpu_job *job; unsigned i; uint64_t seq; @@ -1189,7 +1240,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, } job->owner = p->filp; - job->fence_ctx = entity->fence_context; p->fence = dma_fence_get(&job->base.s_fence->finished); r = amdgpu_ctx_add_fence(p->ctx, ring, p->fence, &seq); @@ -1207,11 +1257,14 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, job->uf_sequence = seq; amdgpu_job_free_resources(job); - amdgpu_ring_priority_get(job->ring, job->base.s_priority); trace_amdgpu_cs_ioctl(job); + priority = job->base.s_priority; drm_sched_entity_push_job(&job->base, entity); + ring = to_amdgpu_ring(entity->sched); + amdgpu_ring_priority_get(ring, priority); + ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence); amdgpu_mn_unlock(p->mn); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 0120b24fae1b99f0b3906a781554b0cf75242f8a..83e3b320a793831c50bbf3ac277252c7751979e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -90,8 +90,8 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, if (ring == &adev->gfx.kiq.ring) continue; - r = drm_sched_entity_init(&ring->sched, &ctx->rings[i].entity, - rq, &ctx->guilty); + r = drm_sched_entity_init(&ctx->rings[i].entity, + &rq, 1, &ctx->guilty); if (r) goto failed; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9883fa9bb41be90dd21ee745d097f52b80175f56..386a7b34d2f466af0f8337ae3198e16372494bcd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2200,7 +2200,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_VEGA20: -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case CHIP_RAVEN: #endif return amdgpu_dc != 0; @@ -2758,11 +2758,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); r = amdgpu_bo_reserve(aobj, true); if (r == 0) { - r = amdgpu_bo_pin(aobj, - AMDGPU_GEM_DOMAIN_VRAM, - &amdgpu_crtc->cursor_addr); + r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); if (r != 0) DRM_ERROR("Failed to pin cursor BO (%d)\n", r); + amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); amdgpu_bo_unreserve(aobj); } } @@ -3254,7 +3253,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, kthread_park(ring->sched.thread); - if (job && job->ring->idx != i) + if (job && job->base.sched == &ring->sched) continue; drm_sched_hw_job_reset(&ring->sched, &job->base); @@ -3278,7 +3277,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, * or all rings (in the case @job is NULL) * after above amdgpu_reset accomplished */ - if ((!job || job->ring->idx == i) && !r) + if ((!job || job->base.sched == &ring->sched) && !r) drm_sched_job_recovery(&ring->sched); kthread_unpark(ring->sched.thread); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 76ee8e04ff1172b81c18d478b2738f6149661f5d..6748cd7fc129b0e7b83966da865f674c676c04e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -157,7 +157,6 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, struct amdgpu_bo *new_abo; unsigned long flags; u64 tiling_flags; - u64 base; int i, r; work = kzalloc(sizeof *work, GFP_KERNEL); @@ -189,12 +188,18 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, goto cleanup; } - r = amdgpu_bo_pin(new_abo, amdgpu_display_supported_domains(adev), &base); + r = amdgpu_bo_pin(new_abo, amdgpu_display_supported_domains(adev)); if (unlikely(r != 0)) { DRM_ERROR("failed to pin new abo buffer before flip\n"); goto unreserve; } + r = amdgpu_ttm_alloc_gart(&new_abo->tbo); + if (unlikely(r != 0)) { + DRM_ERROR("%p bind failed\n", new_abo); + goto unpin; + } + r = reservation_object_get_fences_rcu(new_abo->tbo.resv, &work->excl, &work->shared_count, &work->shared); @@ -206,7 +211,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, amdgpu_bo_get_tiling_flags(new_abo, &tiling_flags); amdgpu_bo_unreserve(new_abo); - work->base = base; + work->base = amdgpu_bo_gpu_offset(new_abo); work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) + amdgpu_get_vblank_counter_kms(dev, work->crtc_id); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 06aede194bf850fbcce0e58c3dba26c5048f5348..8843a06360fa7bd7e9620c76012b83b21e51f8c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -69,9 +69,10 @@ * - 3.24.0 - Add high priority compute support for gfx9 * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk). * - 3.26.0 - GFX9: Process AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE. + * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation. */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 26 +#define KMS_DRIVER_MINOR 27 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; @@ -103,11 +104,8 @@ int amdgpu_vram_page_split = 512; int amdgpu_vm_update_mode = -1; int amdgpu_exp_hw_support = 0; int amdgpu_dc = -1; -int amdgpu_dc_log = 0; int amdgpu_sched_jobs = 32; int amdgpu_sched_hw_submission = 2; -int amdgpu_no_evict = 0; -int amdgpu_direct_gma_size = 0; uint amdgpu_pcie_gen_cap = 0; uint amdgpu_pcie_lane_cap = 0; uint amdgpu_cg_mask = 0xffffffff; @@ -340,9 +338,6 @@ module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); MODULE_PARM_DESC(dc, "Display Core driver (1 = enable, 0 = disable, -1 = auto (default))"); module_param_named(dc, amdgpu_dc, int, 0444); -MODULE_PARM_DESC(dc_log, "Display Core Log Level (0 = minimal (default), 1 = chatty"); -module_param_named(dc_log, amdgpu_dc_log, int, 0444); - /** * DOC: sched_jobs (int) * Override the max number of jobs supported in the sw queue. The default is 32. @@ -365,12 +360,6 @@ module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))"); module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444); -MODULE_PARM_DESC(no_evict, "Support pinning request from user space (1 = enable, 0 = disable (default))"); -module_param_named(no_evict, amdgpu_no_evict, int, 0444); - -MODULE_PARM_DESC(direct_gma_size, "Direct GMA size in megabytes (max 96MB)"); -module_param_named(direct_gma_size, amdgpu_direct_gma_size, int, 0444); - /** * DOC: pcie_gen_cap (uint) * Override PCIE gen speed capabilities. See the CAIL flags in drivers/gpu/drm/amd/include/amd_pcie.h. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 811c62927c3829bdb681a01879d2d17797149c4f..d44b76455e896a539d9c859914059746fe70d25b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -168,11 +168,19 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, } - ret = amdgpu_bo_pin(abo, domain, NULL); + ret = amdgpu_bo_pin(abo, domain); if (ret) { amdgpu_bo_unreserve(abo); goto out_unref; } + + ret = amdgpu_ttm_alloc_gart(&abo->tbo); + if (ret) { + amdgpu_bo_unreserve(abo); + dev_err(adev->dev, "%p bind failed\n", abo); + goto out_unref; + } + ret = amdgpu_bo_kmap(abo, NULL); amdgpu_bo_unreserve(abo); if (ret) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 36113cb60ca2f466631c78b84d23b5d93c5bc319..a54d5655a191abac380e58c7d175cd08f055fa5b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -143,14 +143,12 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) */ int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) { - uint64_t gpu_addr; int r; r = amdgpu_bo_reserve(adev->gart.robj, false); if (unlikely(r != 0)) return r; - r = amdgpu_bo_pin(adev->gart.robj, - AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr); + r = amdgpu_bo_pin(adev->gart.robj, AMDGPU_GEM_DOMAIN_VRAM); if (r) { amdgpu_bo_unreserve(adev->gart.robj); return r; @@ -159,7 +157,7 @@ int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) if (r) amdgpu_bo_unpin(adev->gart.robj); amdgpu_bo_unreserve(adev->gart.robj); - adev->gart.table_addr = gpu_addr; + adev->gart.table_addr = amdgpu_bo_gpu_offset(adev->gart.robj); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index ce7739832d292c26697db38a9c0f84c2d965ac7a..5518e623fed21046791c42e026383526f8cf8adb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -139,7 +139,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, /* ring tests don't use a job */ if (job) { vm = job->vm; - fence_ctx = job->fence_ctx; + fence_ctx = job->base.s_fence->scheduled.context; } else { vm = NULL; fence_ctx = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 2bd56760c7441fdc720d3a469fef424ae39741ea..5a2c26a85984560a75d5ac01f2768b0a0984884e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -30,14 +30,14 @@ static void amdgpu_job_timedout(struct drm_sched_job *s_job) { - struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); + struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); + struct amdgpu_job *job = to_amdgpu_job(s_job); - DRM_ERROR("ring %s timeout, last signaled seq=%u, last emitted seq=%u\n", - job->base.sched->name, - atomic_read(&job->ring->fence_drv.last_seq), - job->ring->fence_drv.sync_seq); + DRM_ERROR("ring %s timeout, signaled seq=%u, emitted seq=%u\n", + job->base.sched->name, atomic_read(&ring->fence_drv.last_seq), + ring->fence_drv.sync_seq); - amdgpu_device_gpu_recover(job->adev, job, false); + amdgpu_device_gpu_recover(ring->adev, job, false); } int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, @@ -54,7 +54,11 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, if (!*job) return -ENOMEM; - (*job)->adev = adev; + /* + * Initialize the scheduler to at least some ring so that we always + * have a pointer to adev. + */ + (*job)->base.sched = &adev->rings[0]->sched; (*job)->vm = vm; (*job)->ibs = (void *)&(*job)[1]; (*job)->num_ibs = num_ibs; @@ -86,6 +90,7 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, void amdgpu_job_free_resources(struct amdgpu_job *job) { + struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); struct dma_fence *f; unsigned i; @@ -93,14 +98,15 @@ void amdgpu_job_free_resources(struct amdgpu_job *job) f = job->base.s_fence ? &job->base.s_fence->finished : job->fence; for (i = 0; i < job->num_ibs; ++i) - amdgpu_ib_free(job->adev, &job->ibs[i], f); + amdgpu_ib_free(ring->adev, &job->ibs[i], f); } static void amdgpu_job_free_cb(struct drm_sched_job *s_job) { - struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); + struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); + struct amdgpu_job *job = to_amdgpu_job(s_job); - amdgpu_ring_priority_put(job->ring, s_job->s_priority); + amdgpu_ring_priority_put(ring, s_job->s_priority); dma_fence_put(job->fence); amdgpu_sync_free(&job->sync); amdgpu_sync_free(&job->sched_sync); @@ -117,50 +123,68 @@ void amdgpu_job_free(struct amdgpu_job *job) kfree(job); } -int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, - struct drm_sched_entity *entity, void *owner, - struct dma_fence **f) +int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity, + void *owner, struct dma_fence **f) { + enum drm_sched_priority priority; + struct amdgpu_ring *ring; int r; - job->ring = ring; if (!f) return -EINVAL; - r = drm_sched_job_init(&job->base, &ring->sched, entity, owner); + r = drm_sched_job_init(&job->base, entity->sched, entity, owner); if (r) return r; job->owner = owner; - job->fence_ctx = entity->fence_context; *f = dma_fence_get(&job->base.s_fence->finished); amdgpu_job_free_resources(job); - amdgpu_ring_priority_get(job->ring, job->base.s_priority); + priority = job->base.s_priority; drm_sched_entity_push_job(&job->base, entity); + ring = to_amdgpu_ring(entity->sched); + amdgpu_ring_priority_get(ring, priority); + + return 0; +} + +int amdgpu_job_submit_direct(struct amdgpu_job *job, struct amdgpu_ring *ring, + struct dma_fence **fence) +{ + int r; + + job->base.sched = &ring->sched; + r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, NULL, fence); + job->fence = dma_fence_get(*fence); + if (r) + return r; + + amdgpu_job_free(job); return 0; } static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job, struct drm_sched_entity *s_entity) { + struct amdgpu_ring *ring = to_amdgpu_ring(s_entity->sched); struct amdgpu_job *job = to_amdgpu_job(sched_job); struct amdgpu_vm *vm = job->vm; + struct dma_fence *fence; bool explicit = false; int r; - struct dma_fence *fence = amdgpu_sync_get_fence(&job->sync, &explicit); + fence = amdgpu_sync_get_fence(&job->sync, &explicit); if (fence && explicit) { if (drm_sched_dependency_optimized(fence, s_entity)) { - r = amdgpu_sync_fence(job->adev, &job->sched_sync, fence, false); + r = amdgpu_sync_fence(ring->adev, &job->sched_sync, + fence, false); if (r) - DRM_ERROR("Error adding fence to sync (%d)\n", r); + DRM_ERROR("Error adding fence (%d)\n", r); } } while (fence == NULL && vm && !job->vmid) { - struct amdgpu_ring *ring = job->ring; - r = amdgpu_vmid_grab(vm, ring, &job->sync, &job->base.s_fence->finished, job); @@ -175,30 +199,25 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job, static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job) { + struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched); struct dma_fence *fence = NULL, *finished; - struct amdgpu_device *adev; struct amdgpu_job *job; int r; - if (!sched_job) { - DRM_ERROR("job is null\n"); - return NULL; - } job = to_amdgpu_job(sched_job); finished = &job->base.s_fence->finished; - adev = job->adev; BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL)); trace_amdgpu_sched_run_job(job); - if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter)) + if (job->vram_lost_counter != atomic_read(&ring->adev->vram_lost_counter)) dma_fence_set_error(finished, -ECANCELED);/* skip IB as well if VRAM lost */ if (finished->error < 0) { DRM_INFO("Skip scheduling IBs!\n"); } else { - r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, + r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job, &fence); if (r) DRM_ERROR("Error scheduling IBs (%d)\n", r); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h new file mode 100644 index 0000000000000000000000000000000000000000..57cfe78a262b11e70eb037afda5755769932fabd --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h @@ -0,0 +1,74 @@ +/* + * Copyright 2018 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 __AMDGPU_JOB_H__ +#define __AMDGPU_JOB_H__ + +/* bit set means command submit involves a preamble IB */ +#define AMDGPU_PREAMBLE_IB_PRESENT (1 << 0) +/* bit set means preamble IB is first presented in belonging context */ +#define AMDGPU_PREAMBLE_IB_PRESENT_FIRST (1 << 1) +/* bit set means context switch occured */ +#define AMDGPU_HAVE_CTX_SWITCH (1 << 2) + +#define to_amdgpu_job(sched_job) \ + container_of((sched_job), struct amdgpu_job, base) + +struct amdgpu_fence; + +struct amdgpu_job { + struct drm_sched_job base; + struct amdgpu_vm *vm; + struct amdgpu_sync sync; + struct amdgpu_sync sched_sync; + struct amdgpu_ib *ibs; + struct dma_fence *fence; /* the hw fence */ + uint32_t preamble_status; + uint32_t num_ibs; + void *owner; + bool vm_needs_flush; + uint64_t vm_pd_addr; + unsigned vmid; + unsigned pasid; + uint32_t gds_base, gds_size; + uint32_t gws_base, gws_size; + uint32_t oa_base, oa_size; + uint32_t vram_lost_counter; + + /* user fence handling */ + uint64_t uf_addr; + uint64_t uf_sequence; + +}; + +int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, + struct amdgpu_job **job, struct amdgpu_vm *vm); +int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, + struct amdgpu_job **job); + +void amdgpu_job_free_resources(struct amdgpu_job *job); +void amdgpu_job_free(struct amdgpu_job *job); +int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity, + void *owner, struct dma_fence **f); +int amdgpu_job_submit_direct(struct amdgpu_job *job, struct amdgpu_ring *ring, + struct dma_fence **fence); +#endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 2060f208e60b77c461df1a9a529b5f48cfaa7937..207f238649b47f1b46a3c001594425b0a5c2cfaa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -501,13 +501,13 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file case AMDGPU_INFO_VRAM_GTT: { struct drm_amdgpu_info_vram_gtt vram_gtt; - vram_gtt.vram_size = adev->gmc.real_vram_size; - vram_gtt.vram_size -= adev->vram_pin_size; - vram_gtt.vram_cpu_accessible_size = adev->gmc.visible_vram_size; - vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size); + vram_gtt.vram_size = adev->gmc.real_vram_size - + atomic64_read(&adev->vram_pin_size); + vram_gtt.vram_cpu_accessible_size = adev->gmc.visible_vram_size - + atomic64_read(&adev->visible_pin_size); vram_gtt.gtt_size = adev->mman.bdev.man[TTM_PL_TT].size; vram_gtt.gtt_size *= PAGE_SIZE; - vram_gtt.gtt_size -= adev->gart_pin_size; + vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size); return copy_to_user(out, &vram_gtt, min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0; } @@ -516,17 +516,16 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file memset(&mem, 0, sizeof(mem)); mem.vram.total_heap_size = adev->gmc.real_vram_size; - mem.vram.usable_heap_size = - adev->gmc.real_vram_size - adev->vram_pin_size; + mem.vram.usable_heap_size = adev->gmc.real_vram_size - + atomic64_read(&adev->vram_pin_size); mem.vram.heap_usage = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4; mem.cpu_accessible_vram.total_heap_size = adev->gmc.visible_vram_size; - mem.cpu_accessible_vram.usable_heap_size = - adev->gmc.visible_vram_size - - (adev->vram_pin_size - adev->invisible_pin_size); + mem.cpu_accessible_vram.usable_heap_size = adev->gmc.visible_vram_size - + atomic64_read(&adev->visible_pin_size); mem.cpu_accessible_vram.heap_usage = amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); mem.cpu_accessible_vram.max_allocation = @@ -534,8 +533,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file mem.gtt.total_heap_size = adev->mman.bdev.man[TTM_PL_TT].size; mem.gtt.total_heap_size *= PAGE_SIZE; - mem.gtt.usable_heap_size = mem.gtt.total_heap_size - - adev->gart_pin_size; + mem.gtt.usable_heap_size = mem.gtt.total_heap_size - + atomic64_read(&adev->gart_pin_size); mem.gtt.heap_usage = amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]); mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 512f598364369e9d961030be1ffb37e23a7f4192..b12526ce1a9d3e7133b74c66e806f7c82c8d26b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -63,11 +63,35 @@ static bool amdgpu_need_backup(struct amdgpu_device *adev) return true; } +/** + * amdgpu_bo_subtract_pin_size - Remove BO from pin_size accounting + * + * @bo: &amdgpu_bo buffer object + * + * This function is called when a BO stops being pinned, and updates the + * &amdgpu_device pin_size values accordingly. + */ +static void amdgpu_bo_subtract_pin_size(struct amdgpu_bo *bo) +{ + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); + + if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { + atomic64_sub(amdgpu_bo_size(bo), &adev->vram_pin_size); + atomic64_sub(amdgpu_vram_mgr_bo_visible_size(bo), + &adev->visible_pin_size); + } else if (bo->tbo.mem.mem_type == TTM_PL_TT) { + atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size); + } +} + static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) { struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); + if (WARN_ON_ONCE(bo->pin_count > 0)) + amdgpu_bo_subtract_pin_size(bo); + if (bo->kfd_bo) amdgpu_amdkfd_unreserve_system_memory_limit(bo); @@ -252,22 +276,33 @@ int amdgpu_bo_create_reserved(struct amdgpu_device *adev, goto error_free; } - r = amdgpu_bo_pin(*bo_ptr, domain, gpu_addr); + r = amdgpu_bo_pin(*bo_ptr, domain); if (r) { dev_err(adev->dev, "(%d) kernel bo pin failed\n", r); goto error_unreserve; } + r = amdgpu_ttm_alloc_gart(&(*bo_ptr)->tbo); + if (r) { + dev_err(adev->dev, "%p bind failed\n", *bo_ptr); + goto error_unpin; + } + + if (gpu_addr) + *gpu_addr = amdgpu_bo_gpu_offset(*bo_ptr); + if (cpu_addr) { r = amdgpu_bo_kmap(*bo_ptr, cpu_addr); if (r) { dev_err(adev->dev, "(%d) kernel bo map failed\n", r); - goto error_unreserve; + goto error_unpin; } } return 0; +error_unpin: + amdgpu_bo_unpin(*bo_ptr); error_unreserve: amdgpu_bo_unreserve(*bo_ptr); @@ -817,7 +852,6 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo) * @domain: domain to be pinned to * @min_offset: the start of requested address range * @max_offset: the end of requested address range - * @gpu_addr: GPU offset of the &amdgpu_bo buffer object * * Pins the buffer object according to requested domain and address range. If * the memory is unbound gart memory, binds the pages into gart table. Adjusts @@ -835,8 +869,7 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo) * 0 for success or a negative error code on failure. */ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, - u64 min_offset, u64 max_offset, - u64 *gpu_addr) + u64 min_offset, u64 max_offset) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); struct ttm_operation_ctx ctx = { false, false }; @@ -868,8 +901,6 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, return -EINVAL; bo->pin_count++; - if (gpu_addr) - *gpu_addr = amdgpu_bo_gpu_offset(bo); if (max_offset != 0) { u64 domain_start = bo->tbo.bdev->man[mem_type].gpu_offset; @@ -905,22 +936,15 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, goto error; } - r = amdgpu_ttm_alloc_gart(&bo->tbo); - if (unlikely(r)) { - dev_err(adev->dev, "%p bind failed\n", bo); - goto error; - } - bo->pin_count = 1; - if (gpu_addr != NULL) - *gpu_addr = amdgpu_bo_gpu_offset(bo); domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); if (domain == AMDGPU_GEM_DOMAIN_VRAM) { - adev->vram_pin_size += amdgpu_bo_size(bo); - adev->invisible_pin_size += amdgpu_vram_mgr_bo_invisible_size(bo); + atomic64_add(amdgpu_bo_size(bo), &adev->vram_pin_size); + atomic64_add(amdgpu_vram_mgr_bo_visible_size(bo), + &adev->visible_pin_size); } else if (domain == AMDGPU_GEM_DOMAIN_GTT) { - adev->gart_pin_size += amdgpu_bo_size(bo); + atomic64_add(amdgpu_bo_size(bo), &adev->gart_pin_size); } error: @@ -931,7 +955,6 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, * amdgpu_bo_pin - pin an &amdgpu_bo buffer object * @bo: &amdgpu_bo buffer object to be pinned * @domain: domain to be pinned to - * @gpu_addr: GPU offset of the &amdgpu_bo buffer object * * A simple wrapper to amdgpu_bo_pin_restricted(). * Provides a simpler API for buffers that do not have any strict restrictions @@ -940,9 +963,9 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, * Returns: * 0 for success or a negative error code on failure. */ -int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr) +int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain) { - return amdgpu_bo_pin_restricted(bo, domain, 0, 0, gpu_addr); + return amdgpu_bo_pin_restricted(bo, domain, 0, 0); } /** @@ -969,12 +992,7 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo) if (bo->pin_count) return 0; - if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { - adev->vram_pin_size -= amdgpu_bo_size(bo); - adev->invisible_pin_size -= amdgpu_vram_mgr_bo_invisible_size(bo); - } else if (bo->tbo.mem.mem_type == TTM_PL_TT) { - adev->gart_pin_size -= amdgpu_bo_size(bo); - } + amdgpu_bo_subtract_pin_size(bo); for (i = 0; i < bo->placement.num_placement; i++) { bo->placements[i].lpfn = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 731748033878b35a32f70a6fe4eda9d0d44835cb..9c3e29a04eb18868c8f87f9094ac216ddcff3d24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -252,10 +252,9 @@ void *amdgpu_bo_kptr(struct amdgpu_bo *bo); void amdgpu_bo_kunmap(struct amdgpu_bo *bo); struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo); void amdgpu_bo_unref(struct amdgpu_bo **bo); -int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr); +int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain); int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, - u64 min_offset, u64 max_offset, - u64 *gpu_addr); + u64 min_offset, u64 max_offset); int amdgpu_bo_unpin(struct amdgpu_bo *bo); int amdgpu_bo_evict_vram(struct amdgpu_device *adev); int amdgpu_bo_init(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index f1404adc3a9016c681d968ed4a3e340ee3c0d139..15a1192c1ec5472b9d4b51127cc7ad569eced99a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -606,40 +606,59 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, return snprintf(buf, PAGE_SIZE, "\n"); } -static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) +/* + * Worst case: 32 bits individually specified, in octal at 12 characters + * per line (+1 for \n). + */ +#define AMDGPU_MASK_BUF_MAX (32 * 13) + +static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask) { - struct drm_device *ddev = dev_get_drvdata(dev); - struct amdgpu_device *adev = ddev->dev_private; int ret; long level; - uint32_t mask = 0; char *sub_str = NULL; char *tmp; - char buf_cpy[count]; + char buf_cpy[AMDGPU_MASK_BUF_MAX + 1]; const char delimiter[3] = {' ', '\n', '\0'}; + size_t bytes; - memcpy(buf_cpy, buf, count+1); + *mask = 0; + + bytes = min(count, sizeof(buf_cpy) - 1); + memcpy(buf_cpy, buf, bytes); + buf_cpy[bytes] = '\0'; tmp = buf_cpy; while (tmp[0]) { - sub_str = strsep(&tmp, delimiter); + sub_str = strsep(&tmp, delimiter); if (strlen(sub_str)) { ret = kstrtol(sub_str, 0, &level); - - if (ret) { - count = -EINVAL; - goto fail; - } - mask |= 1 << level; + if (ret) + return -EINVAL; + *mask |= 1 << level; } else break; } + + return 0; +} + +static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + int ret; + uint32_t mask = 0; + + ret = amdgpu_read_mask(buf, count, &mask); + if (ret) + return ret; + if (adev->powerplay.pp_funcs->force_clock_level) amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); -fail: return count; } @@ -664,32 +683,15 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; int ret; - long level; uint32_t mask = 0; - char *sub_str = NULL; - char *tmp; - char buf_cpy[count]; - const char delimiter[3] = {' ', '\n', '\0'}; - memcpy(buf_cpy, buf, count+1); - tmp = buf_cpy; - while (tmp[0]) { - sub_str = strsep(&tmp, delimiter); - if (strlen(sub_str)) { - ret = kstrtol(sub_str, 0, &level); + ret = amdgpu_read_mask(buf, count, &mask); + if (ret) + return ret; - if (ret) { - count = -EINVAL; - goto fail; - } - mask |= 1 << level; - } else - break; - } if (adev->powerplay.pp_funcs->force_clock_level) amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); -fail: return count; } @@ -714,33 +716,15 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; int ret; - long level; uint32_t mask = 0; - char *sub_str = NULL; - char *tmp; - char buf_cpy[count]; - const char delimiter[3] = {' ', '\n', '\0'}; - - memcpy(buf_cpy, buf, count+1); - tmp = buf_cpy; - while (tmp[0]) { - sub_str = strsep(&tmp, delimiter); - if (strlen(sub_str)) { - ret = kstrtol(sub_str, 0, &level); + ret = amdgpu_read_mask(buf, count, &mask); + if (ret) + return ret; - if (ret) { - count = -EINVAL; - goto fail; - } - mask |= 1 << level; - } else - break; - } if (adev->powerplay.pp_funcs->force_clock_level) amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); -fail: return count; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index df7226ad64b527b70f202676690de9cdb1c71517..3ed02f47200350991a8fdc524ad6cfcbc0031ba0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -232,7 +232,7 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf, } /* pin buffer into GTT */ - r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL); + r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); if (r) goto error_unreserve; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 19e45a3953e07d3ac69bd84cbb86bfa1f7cd0b21..93794a85f83d80e868870133e387467c2b8de4a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -211,7 +211,8 @@ void amdgpu_ring_priority_get(struct amdgpu_ring *ring, if (!ring->funcs->set_priority) return; - atomic_inc(&ring->num_jobs[priority]); + if (atomic_inc_return(&ring->num_jobs[priority]) <= 0) + return; mutex_lock(&ring->priority_mutex); if (priority <= ring->priority) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index a293f4e6760db15a0a93f5a2331d8ccd2e772ceb..5018c0b6bf1a4e0786cf494c9ce6cb4fafc71794 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -44,6 +44,8 @@ #define AMDGPU_FENCE_FLAG_INT (1 << 1) #define AMDGPU_FENCE_FLAG_TC_WB_ONLY (1 << 2) +#define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched) + enum amdgpu_ring_type { AMDGPU_RING_TYPE_GFX, AMDGPU_RING_TYPE_COMPUTE, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c index 57b14dccd8e0251dcf7209f00113e9797f5e8ce3..8904e62dca7ae277143f4a3cbdffaa28ef120bf9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c @@ -76,11 +76,12 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev) r = amdgpu_bo_reserve(vram_obj, false); if (unlikely(r != 0)) goto out_unref; - r = amdgpu_bo_pin(vram_obj, AMDGPU_GEM_DOMAIN_VRAM, &vram_addr); + r = amdgpu_bo_pin(vram_obj, AMDGPU_GEM_DOMAIN_VRAM); if (r) { DRM_ERROR("Failed to pin VRAM object\n"); goto out_unres; } + vram_addr = amdgpu_bo_gpu_offset(vram_obj); for (i = 0; i < n; i++) { void *gtt_map, *vram_map; void **gart_start, **gart_end; @@ -97,11 +98,17 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev) r = amdgpu_bo_reserve(gtt_obj[i], false); if (unlikely(r != 0)) goto out_lclean_unref; - r = amdgpu_bo_pin(gtt_obj[i], AMDGPU_GEM_DOMAIN_GTT, &gart_addr); + r = amdgpu_bo_pin(gtt_obj[i], AMDGPU_GEM_DOMAIN_GTT); if (r) { DRM_ERROR("Failed to pin GTT object %d\n", i); goto out_lclean_unres; } + r = amdgpu_ttm_alloc_gart(>t_obj[i]->tbo); + if (r) { + DRM_ERROR("%p bind failed\n", gtt_obj[i]); + goto out_lclean_unpin; + } + gart_addr = amdgpu_bo_gpu_offset(gtt_obj[i]); r = amdgpu_bo_kmap(gtt_obj[i], >t_map); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index e96e26d3f3b085f38986f5cd6112e0e7325bd56c..76920035eb22da59d1204795db3479ebb312b42d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -150,10 +150,10 @@ TRACE_EVENT(amdgpu_cs, TP_fast_assign( __entry->bo_list = p->bo_list; - __entry->ring = p->job->ring->idx; + __entry->ring = p->ring->idx; __entry->dw = p->job->ibs[i].length_dw; __entry->fences = amdgpu_fence_count_emitted( - p->job->ring); + p->ring); ), TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u", __entry->bo_list, __entry->ring, __entry->dw, @@ -178,7 +178,7 @@ TRACE_EVENT(amdgpu_cs_ioctl, __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) __entry->context = job->base.s_fence->finished.context; __entry->seqno = job->base.s_fence->finished.seqno; - __entry->ring_name = job->ring->name; + __entry->ring_name = to_amdgpu_ring(job->base.sched)->name; __entry->num_ibs = job->num_ibs; ), TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", @@ -203,7 +203,7 @@ TRACE_EVENT(amdgpu_sched_run_job, __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) __entry->context = job->base.s_fence->finished.context; __entry->seqno = job->base.s_fence->finished.seqno; - __entry->ring_name = job->ring->name; + __entry->ring_name = to_amdgpu_ring(job->base.sched)->name; __entry->num_ibs = job->num_ibs; ), TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 0246cb87d9e4e4b045c5076b64dac1b6c3ac99aa..13977ea6a09788924170f09ce9ebe1fe7785622a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -104,8 +104,6 @@ static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref) static int amdgpu_ttm_global_init(struct amdgpu_device *adev) { struct drm_global_reference *global_ref; - struct amdgpu_ring *ring; - struct drm_sched_rq *rq; int r; /* ensure reference is false in case init fails */ @@ -138,21 +136,10 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev) mutex_init(&adev->mman.gtt_window_lock); - ring = adev->mman.buffer_funcs_ring; - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL]; - r = drm_sched_entity_init(&ring->sched, &adev->mman.entity, - rq, NULL); - if (r) { - DRM_ERROR("Failed setting up TTM BO move run queue.\n"); - goto error_entity; - } - adev->mman.mem_global_referenced = true; return 0; -error_entity: - drm_global_item_unref(&adev->mman.bo_global_ref.ref); error_bo: drm_global_item_unref(&adev->mman.mem_global_ref); error_mem: @@ -162,8 +149,6 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev) static void amdgpu_ttm_global_fini(struct amdgpu_device *adev) { if (adev->mman.mem_global_referenced) { - drm_sched_entity_destroy(adev->mman.entity.sched, - &adev->mman.entity); mutex_destroy(&adev->mman.gtt_window_lock); drm_global_item_unref(&adev->mman.bo_global_ref.ref); drm_global_item_unref(&adev->mman.mem_global_ref); @@ -1695,7 +1680,7 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev) AMDGPU_GEM_DOMAIN_VRAM, adev->fw_vram_usage.start_offset, (adev->fw_vram_usage.start_offset + - adev->fw_vram_usage.size), NULL); + adev->fw_vram_usage.size)); if (r) goto error_pin; r = amdgpu_bo_kmap(adev->fw_vram_usage.reserved_bo, @@ -1921,10 +1906,29 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) { struct ttm_mem_type_manager *man = &adev->mman.bdev.man[TTM_PL_VRAM]; uint64_t size; + int r; - if (!adev->mman.initialized || adev->in_gpu_reset) + if (!adev->mman.initialized || adev->in_gpu_reset || + adev->mman.buffer_funcs_enabled == enable) return; + if (enable) { + struct amdgpu_ring *ring; + struct drm_sched_rq *rq; + + ring = adev->mman.buffer_funcs_ring; + rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL]; + r = drm_sched_entity_init(&adev->mman.entity, &rq, 1, NULL); + if (r) { + DRM_ERROR("Failed setting up TTM BO move entity (%d)\n", + r); + return; + } + } else { + drm_sched_entity_destroy(adev->mman.entity.sched, + &adev->mman.entity); + } + /* this just adjusts TTM size idea, which sets lpfn to the correct value */ if (enable) size = adev->gmc.real_vram_size; @@ -2002,7 +2006,7 @@ static int amdgpu_map_buffer(struct ttm_buffer_object *bo, if (r) goto error_free; - r = amdgpu_job_submit(job, ring, &adev->mman.entity, + r = amdgpu_job_submit(job, &adev->mman.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &fence); if (r) goto error_free; @@ -2071,24 +2075,19 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset, amdgpu_ring_pad_ib(ring, &job->ibs[0]); WARN_ON(job->ibs[0].length_dw > num_dw); - if (direct_submit) { - r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, - NULL, fence); - job->fence = dma_fence_get(*fence); - if (r) - DRM_ERROR("Error scheduling IBs (%d)\n", r); - amdgpu_job_free(job); - } else { - r = amdgpu_job_submit(job, ring, &adev->mman.entity, + if (direct_submit) + r = amdgpu_job_submit_direct(job, ring, fence); + else + r = amdgpu_job_submit(job, &adev->mman.entity, AMDGPU_FENCE_OWNER_UNDEFINED, fence); - if (r) - goto error_free; - } + if (r) + goto error_free; return r; error_free: amdgpu_job_free(job); + DRM_ERROR("Error scheduling IBs (%d)\n", r); return r; } @@ -2171,7 +2170,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, amdgpu_ring_pad_ib(ring, &job->ibs[0]); WARN_ON(job->ibs[0].length_dw > num_dw); - r = amdgpu_job_submit(job, ring, &adev->mman.entity, + r = amdgpu_job_submit(job, &adev->mman.entity, AMDGPU_FENCE_OWNER_UNDEFINED, fence); if (r) goto error_free; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index e5da4654b630dd7030704496ee5260e7676324ec..8b3cc6687769eef8b24fb4d11b40cd518d7f442e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -73,7 +73,7 @@ bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem); uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man); int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man); -u64 amdgpu_vram_mgr_bo_invisible_size(struct amdgpu_bo *bo); +u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo); uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man); uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 3e70eb61a9609fdd22a1d45f2e5acf7d21f428ef..80b5c453f8c11c2d987166dd01a37872909c3cc7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -263,21 +263,20 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); return r; } + } - ring = &adev->uvd.inst[j].ring; - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; - r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity, - rq, NULL); - if (r != 0) { - DRM_ERROR("Failed setting up UVD(%d) run queue.\n", j); - return r; - } - - for (i = 0; i < adev->uvd.max_handles; ++i) { - atomic_set(&adev->uvd.inst[j].handles[i], 0); - adev->uvd.inst[j].filp[i] = NULL; - } + ring = &adev->uvd.inst[0].ring; + rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; + r = drm_sched_entity_init(&adev->uvd.entity, &rq, 1, NULL); + if (r) { + DRM_ERROR("Failed setting up UVD kernel entity.\n"); + return r; } + for (i = 0; i < adev->uvd.max_handles; ++i) { + atomic_set(&adev->uvd.handles[i], 0); + adev->uvd.filp[i] = NULL; + } + /* from uvd v5.0 HW addressing capacity increased to 64 bits */ if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) adev->uvd.address_64_bit = true; @@ -306,11 +305,12 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) { int i, j; + drm_sched_entity_destroy(&adev->uvd.inst->ring.sched, + &adev->uvd.entity); + for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { kfree(adev->uvd.inst[j].saved_bo); - drm_sched_entity_destroy(&adev->uvd.inst[j].ring.sched, &adev->uvd.inst[j].entity); - amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo, &adev->uvd.inst[j].gpu_addr, (void **)&adev->uvd.inst[j].cpu_addr); @@ -333,20 +333,20 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) cancel_delayed_work_sync(&adev->uvd.idle_work); + /* only valid for physical mode */ + if (adev->asic_type < CHIP_POLARIS10) { + for (i = 0; i < adev->uvd.max_handles; ++i) + if (atomic_read(&adev->uvd.handles[i])) + break; + + if (i == adev->uvd.max_handles) + return 0; + } + for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { if (adev->uvd.inst[j].vcpu_bo == NULL) continue; - /* only valid for physical mode */ - if (adev->asic_type < CHIP_POLARIS10) { - for (i = 0; i < adev->uvd.max_handles; ++i) - if (atomic_read(&adev->uvd.inst[j].handles[i])) - break; - - if (i == adev->uvd.max_handles) - continue; - } - size = amdgpu_bo_size(adev->uvd.inst[j].vcpu_bo); ptr = adev->uvd.inst[j].cpu_addr; @@ -398,30 +398,27 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp) { - struct amdgpu_ring *ring; - int i, j, r; - - for (j = 0; j < adev->uvd.num_uvd_inst; j++) { - ring = &adev->uvd.inst[j].ring; + struct amdgpu_ring *ring = &adev->uvd.inst[0].ring; + int i, r; - for (i = 0; i < adev->uvd.max_handles; ++i) { - uint32_t handle = atomic_read(&adev->uvd.inst[j].handles[i]); - if (handle != 0 && adev->uvd.inst[j].filp[i] == filp) { - struct dma_fence *fence; - - r = amdgpu_uvd_get_destroy_msg(ring, handle, - false, &fence); - if (r) { - DRM_ERROR("Error destroying UVD(%d) %d!\n", j, r); - continue; - } + for (i = 0; i < adev->uvd.max_handles; ++i) { + uint32_t handle = atomic_read(&adev->uvd.handles[i]); - dma_fence_wait(fence, false); - dma_fence_put(fence); + if (handle != 0 && adev->uvd.filp[i] == filp) { + struct dma_fence *fence; - adev->uvd.inst[j].filp[i] = NULL; - atomic_set(&adev->uvd.inst[j].handles[i], 0); + r = amdgpu_uvd_get_destroy_msg(ring, handle, false, + &fence); + if (r) { + DRM_ERROR("Error destroying UVD %d!\n", r); + continue; } + + dma_fence_wait(fence, false); + dma_fence_put(fence); + + adev->uvd.filp[i] = NULL; + atomic_set(&adev->uvd.handles[i], 0); } } } @@ -696,16 +693,15 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, void *ptr; long r; int i; - uint32_t ip_instance = ctx->parser->job->ring->me; if (offset & 0x3F) { - DRM_ERROR("UVD(%d) messages must be 64 byte aligned!\n", ip_instance); + DRM_ERROR("UVD messages must be 64 byte aligned!\n"); return -EINVAL; } r = amdgpu_bo_kmap(bo, &ptr); if (r) { - DRM_ERROR("Failed mapping the UVD(%d) message (%ld)!\n", ip_instance, r); + DRM_ERROR("Failed mapping the UVD) message (%ld)!\n", r); return r; } @@ -715,7 +711,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, handle = msg[2]; if (handle == 0) { - DRM_ERROR("Invalid UVD(%d) handle!\n", ip_instance); + DRM_ERROR("Invalid UVD handle!\n"); return -EINVAL; } @@ -726,18 +722,19 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, /* try to alloc a new handle */ for (i = 0; i < adev->uvd.max_handles; ++i) { - if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) { - DRM_ERROR("(%d)Handle 0x%x already in use!\n", ip_instance, handle); + if (atomic_read(&adev->uvd.handles[i]) == handle) { + DRM_ERROR(")Handle 0x%x already in use!\n", + handle); return -EINVAL; } - if (!atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], 0, handle)) { - adev->uvd.inst[ip_instance].filp[i] = ctx->parser->filp; + if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) { + adev->uvd.filp[i] = ctx->parser->filp; return 0; } } - DRM_ERROR("No more free UVD(%d) handles!\n", ip_instance); + DRM_ERROR("No more free UVD handles!\n"); return -ENOSPC; case 1: @@ -749,27 +746,27 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, /* validate the handle */ for (i = 0; i < adev->uvd.max_handles; ++i) { - if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) { - if (adev->uvd.inst[ip_instance].filp[i] != ctx->parser->filp) { - DRM_ERROR("UVD(%d) handle collision detected!\n", ip_instance); + if (atomic_read(&adev->uvd.handles[i]) == handle) { + if (adev->uvd.filp[i] != ctx->parser->filp) { + DRM_ERROR("UVD handle collision detected!\n"); return -EINVAL; } return 0; } } - DRM_ERROR("Invalid UVD(%d) handle 0x%x!\n", ip_instance, handle); + DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); return -ENOENT; case 2: /* it's a destroy msg, free the handle */ for (i = 0; i < adev->uvd.max_handles; ++i) - atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], handle, 0); + atomic_cmpxchg(&adev->uvd.handles[i], handle, 0); amdgpu_bo_kunmap(bo); return 0; default: - DRM_ERROR("Illegal UVD(%d) message type (%d)!\n", ip_instance, msg_type); + DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); return -EINVAL; } BUG(); @@ -1062,19 +1059,16 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, if (r < 0) goto err_free; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err_free; - - amdgpu_job_free(job); } else { r = amdgpu_sync_resv(adev, &job->sync, bo->tbo.resv, AMDGPU_FENCE_OWNER_UNDEFINED, false); if (r) goto err_free; - r = amdgpu_job_submit(job, ring, &adev->uvd.inst[ring->me].entity, + r = amdgpu_job_submit(job, &adev->uvd.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &f); if (r) goto err_free; @@ -1276,7 +1270,7 @@ uint32_t amdgpu_uvd_used_handles(struct amdgpu_device *adev) * necessarily linear. So we need to count * all non-zero handles. */ - if (atomic_read(&adev->uvd.inst->handles[i])) + if (atomic_read(&adev->uvd.handles[i])) used_handles++; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h index 8b23a1b00c76c95cf2b12c8aff1440415b059560..66872286ab123c8ad1f5afeb3662da43676b3389 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h @@ -42,13 +42,9 @@ struct amdgpu_uvd_inst { void *cpu_addr; uint64_t gpu_addr; void *saved_bo; - atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; - struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; struct amdgpu_ring ring; struct amdgpu_ring ring_enc[AMDGPU_MAX_UVD_ENC_RINGS]; struct amdgpu_irq_src irq; - struct drm_sched_entity entity; - struct drm_sched_entity entity_enc; uint32_t srbm_soft_reset; }; @@ -57,10 +53,13 @@ struct amdgpu_uvd { unsigned fw_version; unsigned max_handles; unsigned num_enc_rings; - uint8_t num_uvd_inst; + uint8_t num_uvd_inst; bool address_64_bit; bool use_ctx_buf; - struct amdgpu_uvd_inst inst[AMDGPU_MAX_UVD_INSTANCES]; + struct amdgpu_uvd_inst inst[AMDGPU_MAX_UVD_INSTANCES]; + struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; + atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; + struct drm_sched_entity entity; struct delayed_work idle_work; }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 6ae1ad7e83b3cab538c1bb5fb1975723cc453ce3..86182c966ed6f85b78cdbc5ad8986de87130affd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -190,8 +190,7 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) ring = &adev->vce.ring[0]; rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; - r = drm_sched_entity_init(&ring->sched, &adev->vce.entity, - rq, NULL); + r = drm_sched_entity_init(&adev->vce.entity, &rq, 1, NULL); if (r != 0) { DRM_ERROR("Failed setting up VCE run queue.\n"); return r; @@ -470,12 +469,10 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err; - amdgpu_job_free(job); if (fence) *fence = dma_fence_get(f); dma_fence_put(f); @@ -532,19 +529,13 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - if (direct) { - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); - if (r) - goto err; - - amdgpu_job_free(job); - } else { - r = amdgpu_job_submit(job, ring, &ring->adev->vce.entity, + if (direct) + r = amdgpu_job_submit_direct(job, ring, &f); + else + r = amdgpu_job_submit(job, &ring->adev->vce.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &f); - if (r) - goto err; - } + if (r) + goto err; if (fence) *fence = dma_fence_get(f); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index a66cd521a875499243e5be4001dfae3a67996173..798648a1971080040e2dc5140f1a7349440c6cc2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -211,6 +211,8 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]); } + fences += amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg); + if (fences == 0) { if (adev->pm.dpm_enabled) amdgpu_dpm_enable_uvd(adev, false); @@ -227,7 +229,7 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) struct amdgpu_device *adev = ring->adev; bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); - if (set_clocks && adev->pm.dpm_enabled) { + if (set_clocks) { if (adev->pm.dpm_enabled) amdgpu_dpm_enable_uvd(adev, true); else @@ -306,13 +308,10 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, } ib->length_dw = 16; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err_free; - amdgpu_job_free(job); - amdgpu_bo_fence(bo, f, false); amdgpu_bo_unreserve(bo); amdgpu_bo_unref(&bo); @@ -497,12 +496,10 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err; - amdgpu_job_free(job); if (fence) *fence = dma_fence_get(f); dma_fence_put(f); @@ -551,12 +548,10 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err; - amdgpu_job_free(job); if (fence) *fence = dma_fence_get(f); dma_fence_put(f); @@ -664,12 +659,10 @@ static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle, } ib->length_dw = 16; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err; - amdgpu_job_free(job); if (fence) *fence = dma_fence_get(f); dma_fence_put(f); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 712af5c1a5d692a68e4da876de531960b2e48a4f..098dd1ba751a244a098e5ea4a90e44a0acd85bfb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -156,6 +156,9 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base, return; list_add_tail(&base->bo_list, &bo->va); + if (bo->tbo.type == ttm_bo_type_kernel) + list_move(&base->vm_status, &vm->relocated); + if (bo->tbo.resv != vm->root.base.bo->tbo.resv) return; @@ -422,8 +425,8 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, if (r) goto error_free; - r = amdgpu_job_submit(job, ring, &vm->entity, - AMDGPU_FENCE_OWNER_UNDEFINED, &fence); + r = amdgpu_job_submit(job, &vm->entity, AMDGPU_FENCE_OWNER_UNDEFINED, + &fence); if (r) goto error_free; @@ -540,7 +543,6 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, pt->parent = amdgpu_bo_ref(parent->base.bo); amdgpu_vm_bo_base_init(&entry->base, vm, pt); - list_move(&entry->base.vm_status, &vm->relocated); } if (level < AMDGPU_VM_PTB) { @@ -1118,8 +1120,8 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev, amdgpu_sync_resv(adev, &job->sync, root->tbo.resv, AMDGPU_FENCE_OWNER_VM, false); WARN_ON(params.ib->length_dw > ndw); - r = amdgpu_job_submit(job, ring, &vm->entity, - AMDGPU_FENCE_OWNER_VM, &fence); + r = amdgpu_job_submit(job, &vm->entity, AMDGPU_FENCE_OWNER_VM, + &fence); if (r) goto error; @@ -1483,8 +1485,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, amdgpu_ring_pad_ib(ring, params.ib); WARN_ON(params.ib->length_dw > ndw); - r = amdgpu_job_submit(job, ring, &vm->entity, - AMDGPU_FENCE_OWNER_VM, &f); + r = amdgpu_job_submit(job, &vm->entity, AMDGPU_FENCE_OWNER_VM, &f); if (r) goto error_free; @@ -1645,18 +1646,17 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, uint64_t flags; int r; - if (clear || !bo_va->base.bo) { + if (clear || !bo) { mem = NULL; nodes = NULL; exclusive = NULL; } else { struct ttm_dma_tt *ttm; - mem = &bo_va->base.bo->tbo.mem; + mem = &bo->tbo.mem; nodes = mem->mm_node; if (mem->mem_type == TTM_PL_TT) { - ttm = container_of(bo_va->base.bo->tbo.ttm, - struct ttm_dma_tt, ttm); + ttm = container_of(bo->tbo.ttm, struct ttm_dma_tt, ttm); pages_addr = ttm->dma_address; } exclusive = reservation_object_get_excl(bo->tbo.resv); @@ -2562,8 +2562,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, ring_instance %= adev->vm_manager.vm_pte_num_rings; ring = adev->vm_manager.vm_pte_rings[ring_instance]; rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_KERNEL]; - r = drm_sched_entity_init(&ring->sched, &vm->entity, - rq, NULL); + r = drm_sched_entity_init(&vm->entity, &rq, 1, NULL); if (r) return r; @@ -2942,3 +2941,42 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return 0; } + +/** + * amdgpu_vm_get_task_info - Extracts task info for a PASID. + * + * @dev: drm device pointer + * @pasid: PASID identifier for VM + * @task_info: task_info to fill. + */ +void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid, + struct amdgpu_task_info *task_info) +{ + struct amdgpu_vm *vm; + + spin_lock(&adev->vm_manager.pasid_lock); + + vm = idr_find(&adev->vm_manager.pasid_idr, pasid); + if (vm) + *task_info = vm->task_info; + + spin_unlock(&adev->vm_manager.pasid_lock); +} + +/** + * amdgpu_vm_set_task_info - Sets VMs task info. + * + * @vm: vm for which to set the info + */ +void amdgpu_vm_set_task_info(struct amdgpu_vm *vm) +{ + if (!vm->task_info.pid) { + vm->task_info.pid = current->pid; + get_task_comm(vm->task_info.task_name, current); + + if (current->group_leader->mm == current->mm) { + vm->task_info.tgid = current->group_leader->pid; + get_task_comm(vm->task_info.process_name, current->group_leader); + } + } +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 061b99a18cb81d7b2a9fb197bbc33c4df14d9d02..d416f895233d3b89dd0f535ba61006412b30bbb1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -164,6 +164,14 @@ struct amdgpu_vm_pt { #define AMDGPU_VM_FAULT_PASID(fault) ((u64)(fault) >> 48) #define AMDGPU_VM_FAULT_ADDR(fault) ((u64)(fault) & 0xfffffffff000ULL) + +struct amdgpu_task_info { + char process_name[TASK_COMM_LEN]; + char task_name[TASK_COMM_LEN]; + pid_t pid; + pid_t tgid; +}; + struct amdgpu_vm { /* tree of virtual addresses mapped */ struct rb_root_cached va; @@ -215,6 +223,9 @@ struct amdgpu_vm { /* Valid while the PD is reserved or fenced */ uint64_t pd_phys_addr; + + /* Some basic info about the task */ + struct amdgpu_task_info task_info; }; struct amdgpu_vm_manager { @@ -317,4 +328,9 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, struct amdgpu_job *job); void amdgpu_vm_check_compute_bug(struct amdgpu_device *adev); +void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid, + struct amdgpu_task_info *task_info); + +void amdgpu_vm_set_task_info(struct amdgpu_vm *vm); + #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index f7a4bd5885a399e20fc3a5a7b1fecd3c02674d9a..9cfa8a9ada921b8b0844a9bd140a68e1c1eca8c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -97,33 +97,29 @@ static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev, } /** - * amdgpu_vram_mgr_bo_invisible_size - CPU invisible BO size + * amdgpu_vram_mgr_bo_visible_size - CPU visible BO size * * @bo: &amdgpu_bo buffer object (must be in VRAM) * * Returns: - * How much of the given &amdgpu_bo buffer object lies in CPU invisible VRAM. + * How much of the given &amdgpu_bo buffer object lies in CPU visible VRAM. */ -u64 amdgpu_vram_mgr_bo_invisible_size(struct amdgpu_bo *bo) +u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); struct ttm_mem_reg *mem = &bo->tbo.mem; struct drm_mm_node *nodes = mem->mm_node; unsigned pages = mem->num_pages; - u64 usage = 0; + u64 usage; if (amdgpu_gmc_vram_full_visible(&adev->gmc)) - return 0; + return amdgpu_bo_size(bo); if (mem->start >= adev->gmc.visible_vram_size >> PAGE_SHIFT) - return amdgpu_bo_size(bo); + return 0; - while (nodes && pages) { - usage += nodes->size << PAGE_SHIFT; - usage -= amdgpu_vram_mgr_vis_size(adev, nodes); - pages -= nodes->size; - ++nodes; - } + for (usage = 0; nodes && pages; pages -= nodes->size, nodes++) + usage += amdgpu_vram_mgr_vis_size(adev, nodes); return usage; } diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index ada241bfeee96c743c93cbfad8f567eaf1eaf6ac..308f9f238bc11ca34ec407f5edf57d12d2dd57fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -41,6 +41,8 @@ #include "gmc/gmc_8_1_d.h" #include "gmc/gmc_8_1_sh_mask.h" +#include "ivsrcid/ivsrcid_vislands30.h" + static void dce_v10_0_set_display_funcs(struct amdgpu_device *adev); static void dce_v10_0_set_irq_funcs(struct amdgpu_device *adev); @@ -1855,15 +1857,14 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, if (unlikely(r != 0)) return r; - if (atomic) { - fb_location = amdgpu_bo_gpu_offset(abo); - } else { - r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); + if (!atomic) { + r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM); if (unlikely(r != 0)) { amdgpu_bo_unreserve(abo); return -EINVAL; } } + fb_location = amdgpu_bo_gpu_offset(abo); amdgpu_bo_get_tiling_flags(abo, &tiling_flags); amdgpu_bo_unreserve(abo); @@ -2370,13 +2371,14 @@ static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc, return ret; } - ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM, &amdgpu_crtc->cursor_addr); + ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); amdgpu_bo_unreserve(aobj); if (ret) { DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret); drm_gem_object_put_unlocked(obj); return ret; } + amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); dce_v10_0_lock_cursor(crtc, true); @@ -2737,14 +2739,14 @@ static int dce_v10_0_sw_init(void *handle) return r; } - for (i = 8; i < 20; i += 2) { + for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP; i < 20; i += 2) { r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i, &adev->pageflip_irq); if (r) return r; } /* HPD hotplug */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 42, &adev->hpd_irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index a5b96eac3033232d46d3e5320f7ae9e9e72f97e8..76dfb76f7900c671527a5ae972840d4d7942fb34 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -41,6 +41,8 @@ #include "gmc/gmc_8_1_d.h" #include "gmc/gmc_8_1_sh_mask.h" +#include "ivsrcid/ivsrcid_vislands30.h" + static void dce_v11_0_set_display_funcs(struct amdgpu_device *adev); static void dce_v11_0_set_irq_funcs(struct amdgpu_device *adev); @@ -1897,15 +1899,14 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, if (unlikely(r != 0)) return r; - if (atomic) { - fb_location = amdgpu_bo_gpu_offset(abo); - } else { - r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); + if (!atomic) { + r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM); if (unlikely(r != 0)) { amdgpu_bo_unreserve(abo); return -EINVAL; } } + fb_location = amdgpu_bo_gpu_offset(abo); amdgpu_bo_get_tiling_flags(abo, &tiling_flags); amdgpu_bo_unreserve(abo); @@ -2449,13 +2450,14 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc, return ret; } - ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM, &amdgpu_crtc->cursor_addr); + ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); amdgpu_bo_unreserve(aobj); if (ret) { DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret); drm_gem_object_put_unlocked(obj); return ret; } + amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); dce_v11_0_lock_cursor(crtc, true); @@ -2858,14 +2860,14 @@ static int dce_v11_0_sw_init(void *handle) return r; } - for (i = 8; i < 20; i += 2) { + for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP; i < 20; i += 2) { r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i, &adev->pageflip_irq); if (r) return r; } /* HPD hotplug */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 42, &adev->hpd_irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A, &adev->hpd_irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index 394cc1e8fe20e22f4131f6697f24fa248f536996..c9adc627305da9411dab4f565b00008b2927b2bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -1811,15 +1811,14 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc, if (unlikely(r != 0)) return r; - if (atomic) { - fb_location = amdgpu_bo_gpu_offset(abo); - } else { - r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); + if (!atomic) { + r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM); if (unlikely(r != 0)) { amdgpu_bo_unreserve(abo); return -EINVAL; } } + fb_location = amdgpu_bo_gpu_offset(abo); amdgpu_bo_get_tiling_flags(abo, &tiling_flags); amdgpu_bo_unreserve(abo); @@ -2263,13 +2262,14 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc, return ret; } - ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM, &amdgpu_crtc->cursor_addr); + ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); amdgpu_bo_unreserve(aobj); if (ret) { DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret); drm_gem_object_put_unlocked(obj); return ret; } + amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); dce_v6_0_lock_cursor(crtc, true); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index c9b9ab8f1b059a8b0385babc3a2b50547c566450..50cd03beac7d673cc448245e616b5463e50b739d 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -1786,15 +1786,14 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, if (unlikely(r != 0)) return r; - if (atomic) { - fb_location = amdgpu_bo_gpu_offset(abo); - } else { - r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); + if (!atomic) { + r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM); if (unlikely(r != 0)) { amdgpu_bo_unreserve(abo); return -EINVAL; } } + fb_location = amdgpu_bo_gpu_offset(abo); amdgpu_bo_get_tiling_flags(abo, &tiling_flags); amdgpu_bo_unreserve(abo); @@ -2274,13 +2273,14 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc, return ret; } - ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM, &amdgpu_crtc->cursor_addr); + ret = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); amdgpu_bo_unreserve(aobj); if (ret) { DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret); drm_gem_object_put_unlocked(obj); return ret; } + amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj); dce_v8_0_lock_cursor(crtc, true); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c index 677e96a563302e2d46171148b4da667445c6cb13..15257634a53aa673e30f04068bf3c1e48b541ac7 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c @@ -36,6 +36,7 @@ #include "dce_v10_0.h" #include "dce_v11_0.h" #include "dce_virtual.h" +#include "ivsrcid/ivsrcid_vislands30.h" #define DCE_VIRTUAL_VBLANK_PERIOD 16666666 @@ -371,7 +372,7 @@ static int dce_virtual_sw_init(void *handle) int r, i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 229, &adev->crtc_irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 551f21bad6d38bd3b1e8338483a126f9fa167a9b..5cd45210113f645062750e4ef54ffd4e7dc14da7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -51,6 +51,8 @@ #include "smu/smu_7_1_3_d.h" +#include "ivsrcid/ivsrcid_vislands30.h" + #define GFX8_NUM_GFX_RINGS 1 #define GFX8_MEC_HPD_SIZE 2048 @@ -2047,35 +2049,35 @@ static int gfx_v8_0_sw_init(void *handle) adev->gfx.mec.num_queue_per_pipe = 8; /* KIQ event */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 178, &adev->gfx.kiq.irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_INT_IB2, &adev->gfx.kiq.irq); if (r) return r; /* EOP Event */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 181, &adev->gfx.eop_irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_END_OF_PIPE, &adev->gfx.eop_irq); if (r) return r; /* Privileged reg */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 184, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_PRIV_REG_FAULT, &adev->gfx.priv_reg_irq); if (r) return r; /* Privileged inst */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 185, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_PRIV_INSTR_FAULT, &adev->gfx.priv_inst_irq); if (r) return r; /* Add CP EDC/ECC irq */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 197, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_ECC_ERROR, &adev->gfx.cp_ecc_error_irq); if (r) return r; /* SQ interrupts. */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 239, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SQ_INTERRUPT_MSG, &adev->gfx.sq_irq); if (r) { DRM_ERROR("amdgpu_irq_add() for SQ failed: %d\n", r); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index ac46eabe3bcde1e4622ed110dc8bb8d0e8d1e9b9..9ab39117cc4e11a9bf47645993d05a0f8aae96ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -38,6 +38,8 @@ #include "clearstate_gfx9.h" #include "v9_structs.h" +#include "ivsrcid/gfx/irqsrcs_gfx_9_0.h" + #define GFX9_NUM_GFX_RINGS 1 #define GFX9_MEC_HPD_SIZE 2048 #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L @@ -102,11 +104,22 @@ static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] = { SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL, 0x0000f000, 0x00012107), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_3, 0x30000000, 0x10000000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPC_UTCL1_CNTL, 0x08000000, 0x08000080), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPF_UTCL1_CNTL, 0x08000000, 0x08000080), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPG_UTCL1_CNTL, 0x08000000, 0x08000080), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0xffff77ff, 0x2a114042), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG_READ, 0xffff77ff, 0x2a114042), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmIA_UTCL1_CNTL, 0x08000000, 0x08000080), SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_1, 0x00008000, 0x00048000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_0, 0x08000000, 0x08000080), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_1, 0x08000000, 0x08000080), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_2, 0x08000000, 0x08000080), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_PREWALKER_UTCL1_CNTL, 0x08000000, 0x08000080), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_UTCL1_CNTL, 0x08000000, 0x08000080), SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2, 0x00030000, 0x00020000), - SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x00001800, 0x00000800) + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x0000000f, 0x01000107), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x00001800, 0x00000800), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x08000000, 0x08000080) }; static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] = @@ -648,7 +661,10 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) adev->firmware.fw_size += ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); - if (adev->gfx.rlc.is_rlc_v2_1) { + if (adev->gfx.rlc.is_rlc_v2_1 && + adev->gfx.rlc.save_restore_list_cntl_size_bytes && + adev->gfx.rlc.save_restore_list_gpm_size_bytes && + adev->gfx.rlc.save_restore_list_srm_size_bytes) { info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL]; info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL; info->fw = adev->gfx.rlc_fw; @@ -943,6 +959,7 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev) dst_ptr = adev->gfx.rlc.cs_ptr; gfx_v9_0_get_csb_buffer(adev, dst_ptr); amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); + amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); } @@ -971,6 +988,39 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev) return 0; } +static int gfx_v9_0_csb_vram_pin(struct amdgpu_device *adev) +{ + int r; + + r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); + if (unlikely(r != 0)) + return r; + + r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, + AMDGPU_GEM_DOMAIN_VRAM); + if (!r) + adev->gfx.rlc.clear_state_gpu_addr = + amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj); + + amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); + + return r; +} + +static void gfx_v9_0_csb_vram_unpin(struct amdgpu_device *adev) +{ + int r; + + if (!adev->gfx.rlc.clear_state_obj) + return; + + r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true); + if (likely(r == 0)) { + amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); + amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); + } +} + static void gfx_v9_0_mec_fini(struct amdgpu_device *adev) { amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL); @@ -1451,23 +1501,23 @@ static int gfx_v9_0_sw_init(void *handle) adev->gfx.mec.num_queue_per_pipe = 8; /* KIQ event */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, 178, &adev->gfx.kiq.irq); + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_IB2_INTERRUPT_PKT, &adev->gfx.kiq.irq); if (r) return r; /* EOP Event */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, 181, &adev->gfx.eop_irq); + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_EOP_INTERRUPT, &adev->gfx.eop_irq); if (r) return r; /* Privileged reg */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, 184, + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_PRIV_REG_FAULT, &adev->gfx.priv_reg_irq); if (r) return r; /* Privileged inst */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, 185, + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_PRIV_INSTR_FAULT, &adev->gfx.priv_inst_irq); if (r) return r; @@ -2148,8 +2198,16 @@ static void gfx_v9_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *ad static void gfx_v9_0_init_pg(struct amdgpu_device *adev) { - if (!adev->gfx.rlc.is_rlc_v2_1) - return; + gfx_v9_0_init_csb(adev); + + /* + * Rlc save restore list is workable since v2_1. + * And it's needed by gfxoff feature. + */ + if (adev->gfx.rlc.is_rlc_v2_1) { + gfx_v9_1_init_rlc_save_restore_list(adev); + gfx_v9_0_enable_save_restore_machine(adev); + } if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | AMD_PG_SUPPORT_GFX_SMG | @@ -2157,10 +2215,6 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev) AMD_PG_SUPPORT_CP | AMD_PG_SUPPORT_GDS | AMD_PG_SUPPORT_RLC_SMU_HS)) { - gfx_v9_0_init_csb(adev); - gfx_v9_1_init_rlc_save_restore_list(adev); - gfx_v9_0_enable_save_restore_machine(adev); - WREG32(mmRLC_JUMP_TABLE_RESTORE, adev->gfx.rlc.cp_table_gpu_addr >> 8); gfx_v9_0_init_gfx_power_gating(adev); @@ -2252,9 +2306,6 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev) /* disable CG */ WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL, 0); - /* disable PG */ - WREG32_SOC15(GC, 0, mmRLC_PG_CNTL, 0); - gfx_v9_0_rlc_reset(adev); gfx_v9_0_init_pg(adev); @@ -3116,6 +3167,10 @@ static int gfx_v9_0_hw_init(void *handle) gfx_v9_0_gpu_init(adev); + r = gfx_v9_0_csb_vram_pin(adev); + if (r) + return r; + r = gfx_v9_0_rlc_resume(adev); if (r) return r; @@ -3224,6 +3279,8 @@ static int gfx_v9_0_hw_fini(void *handle) gfx_v9_0_cp_enable(adev, false); gfx_v9_0_rlc_stop(adev); + gfx_v9_0_csb_vram_unpin(adev); + return 0; } @@ -3510,8 +3567,11 @@ static void gfx_v9_0_update_medium_grain_clock_gating(struct amdgpu_device *adev if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_MGCG)) { /* 1 - RLC_CGTT_MGCG_OVERRIDE */ def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); - data &= ~(RLC_CGTT_MGCG_OVERRIDE__CPF_CGTT_SCLK_OVERRIDE_MASK | - RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | + + if (adev->asic_type != CHIP_VEGA12) + data &= ~RLC_CGTT_MGCG_OVERRIDE__CPF_CGTT_SCLK_OVERRIDE_MASK; + + data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK); @@ -3541,11 +3601,15 @@ static void gfx_v9_0_update_medium_grain_clock_gating(struct amdgpu_device *adev } else { /* 1 - MGCG_OVERRIDE */ def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); - data |= (RLC_CGTT_MGCG_OVERRIDE__CPF_CGTT_SCLK_OVERRIDE_MASK | - RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK | + + if (adev->asic_type != CHIP_VEGA12) + data |= RLC_CGTT_MGCG_OVERRIDE__CPF_CGTT_SCLK_OVERRIDE_MASK; + + data |= (RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK | RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK); + if (def != data) WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data); @@ -3581,9 +3645,11 @@ static void gfx_v9_0_update_3d_clock_gating(struct amdgpu_device *adev, /* update CGCG and CGLS override bits */ if (def != data) WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data); - /* enable 3Dcgcg FSM(0x0020003f) */ + + /* enable 3Dcgcg FSM(0x0000363f) */ def = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D); - data = (0x2000 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | + + data = (0x36 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK; if (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGLS) data |= (0x000F << RLC_CGCG_CGLS_CTRL_3D__CGLS_REP_COMPANSAT_DELAY__SHIFT) | @@ -3630,9 +3696,10 @@ static void gfx_v9_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev if (def != data) WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data); - /* enable cgcg FSM(0x0020003F) */ + /* enable cgcg FSM(0x0000363F) */ def = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL); - data = (0x2000 << RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | + + data = (0x36 << RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK; if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) data |= (0x000F << RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY__SHIFT) | @@ -3715,6 +3782,11 @@ static int gfx_v9_0_set_powergating_state(void *handle, /* update mgcg state */ gfx_v9_0_update_gfx_mg_power_gating(adev, enable); + /* set gfx off through smu */ + if (enable && adev->powerplay.pp_funcs->set_powergating_by_smu) + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true); + break; + case CHIP_VEGA12: /* set gfx off through smu */ if (enable && adev->powerplay.pp_funcs->set_powergating_by_smu) amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 78339309a00c684d47426fb66c2b2f6c73894bc9..10920f0bd85ff1160472517c8738440cea464163 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -43,6 +43,8 @@ #include "amdgpu_atombios.h" +#include "ivsrcid/ivsrcid_vislands30.h" + static void gmc_v7_0_set_gmc_funcs(struct amdgpu_device *adev); static void gmc_v7_0_set_irq_funcs(struct amdgpu_device *adev); static int gmc_v7_0_wait_for_idle(void *handle); @@ -996,11 +998,11 @@ static int gmc_v7_0_sw_init(void *handle) adev->gmc.vram_type = gmc_v7_0_convert_vram_type(tmp); } - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 146, &adev->gmc.vm_fault); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault); if (r) return r; - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 147, &adev->gmc.vm_fault); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 1edbe6b477b56dc309a49eb1d5a2e68d11ffa8be..75f3ffb2891e97fafd35c9aff98e0c4be6e75c1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -44,6 +44,7 @@ #include "amdgpu_atombios.h" +#include "ivsrcid/ivsrcid_vislands30.h" static void gmc_v8_0_set_gmc_funcs(struct amdgpu_device *adev); static void gmc_v8_0_set_irq_funcs(struct amdgpu_device *adev); @@ -1101,11 +1102,11 @@ static int gmc_v8_0_sw_init(void *handle) adev->gmc.vram_type = gmc_v8_0_convert_vram_type(tmp); } - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 146, &adev->gmc.vm_fault); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT, &adev->gmc.vm_fault); if (r) return r; - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 147, &adev->gmc.vm_fault); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT, &adev->gmc.vm_fault); if (r) return r; @@ -1447,8 +1448,13 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev, gmc_v8_0_set_fault_enable_default(adev, false); if (printk_ratelimit()) { - dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n", - entry->src_id, entry->src_data[0]); + struct amdgpu_task_info task_info = { 0 }; + + amdgpu_vm_get_task_info(adev, entry->pasid, &task_info); + + dev_err(adev->dev, "GPU fault detected: %d 0x%08x for process %s pid %d thread %s pid %d\n", + entry->src_id, entry->src_data[0], task_info.process_name, + task_info.tgid, task_info.task_name, task_info.pid); dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", addr); dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 3c0a85d4e4ab9b513ec2681ab199659bba6e1bf3..9df94b45d17de5ce2c5788e7e60cc91a3f84e5cd 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -43,6 +43,8 @@ #include "gfxhub_v1_0.h" #include "mmhub_v1_0.h" +#include "ivsrcid/vmc/irqsrcs_vmc_1_0.h" + /* add these here since we already include dce12 headers and these are for DCN */ #define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION 0x055d #define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX 2 @@ -257,11 +259,16 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, } if (printk_ratelimit()) { + struct amdgpu_task_info task_info = { 0 }; + + amdgpu_vm_get_task_info(adev, entry->pasid, &task_info); + dev_err(adev->dev, - "[%s] VMC page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n", + "[%s] VMC page fault (src_id:%u ring:%u vmid:%u pasid:%u, for process %s pid %d thread %s pid %d\n)\n", entry->vmid_src ? "mmhub" : "gfxhub", entry->src_id, entry->ring_id, entry->vmid, - entry->pasid); + entry->pasid, task_info.process_name, task_info.tgid, + task_info.task_name, task_info.pid); dev_err(adev->dev, " at page 0x%016llx from %d\n", addr, entry->client_id); if (!amdgpu_sriov_vf(adev)) @@ -872,9 +879,9 @@ static int gmc_v9_0_sw_init(void *handle) } /* This interrupt is VMC page fault.*/ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VMC, 0, + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VMC, VMC_1_0__SRCID__VM_FAULT, &adev->gmc.vm_fault); - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UTCL2, 0, + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UTCL2, UTCL2_1_0__SRCID__FAULT, &adev->gmc.vm_fault); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index cee4fae76d2009b7c7d2cca90284f6a4dd14100d..15ae4bc9c072741d6b8fb319b9371b87e08ac6c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -44,6 +44,8 @@ #include "iceland_sdma_pkt_open.h" +#include "ivsrcid/ivsrcid_vislands30.h" + static void sdma_v2_4_set_ring_funcs(struct amdgpu_device *adev); static void sdma_v2_4_set_buffer_funcs(struct amdgpu_device *adev); static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev); @@ -896,7 +898,7 @@ static int sdma_v2_4_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* SDMA trap event */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 224, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_TRAP, &adev->sdma.trap_irq); if (r) return r; @@ -908,7 +910,7 @@ static int sdma_v2_4_sw_init(void *handle) return r; /* SDMA Privileged inst */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 247, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_SRBM_WRITE, &adev->sdma.illegal_inst_irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 99616dd9594f285babd39044ba3b3271b112cd3b..1e07ff274d73433b34e14a9aa4b94caf04bba961 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -44,6 +44,8 @@ #include "tonga_sdma_pkt_open.h" +#include "ivsrcid/ivsrcid_vislands30.h" + static void sdma_v3_0_set_ring_funcs(struct amdgpu_device *adev); static void sdma_v3_0_set_buffer_funcs(struct amdgpu_device *adev); static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev); @@ -1175,7 +1177,7 @@ static int sdma_v3_0_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* SDMA trap event */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 224, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_TRAP, &adev->sdma.trap_irq); if (r) return r; @@ -1187,7 +1189,7 @@ static int sdma_v3_0_sw_init(void *handle) return r; /* SDMA Privileged inst */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 247, + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SDMA_SRBM_WRITE, &adev->sdma.illegal_inst_irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 572ca63cf676b84420eba53dbe3860ffc4c3d5ed..e7ca4623cfb946f41b0e3e1ffb107a3f295daedb 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -38,6 +38,9 @@ #include "soc15.h" #include "vega10_sdma_pkt_open.h" +#include "ivsrcid/sdma0/irqsrcs_sdma0_4_0.h" +#include "ivsrcid/sdma1/irqsrcs_sdma1_4_0.h" + MODULE_FIRMWARE("amdgpu/vega10_sdma.bin"); MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin"); MODULE_FIRMWARE("amdgpu/vega12_sdma.bin"); @@ -1225,13 +1228,13 @@ static int sdma_v4_0_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* SDMA trap event */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA0, 224, + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA0, SDMA0_4_0__SRCID__SDMA_TRAP, &adev->sdma.trap_irq); if (r) return r; /* SDMA trap event */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA1, 224, + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_SDMA1, SDMA1_4_0__SRCID__SDMA_TRAP, &adev->sdma.trap_irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index 341ee6d55ce89e0aeaac6f646f05f7d3be49d68c..aeaa1ca46a99dc1a4801f921ea8942ad30ca1d56 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -35,6 +35,7 @@ #include "vi.h" #include "smu/smu_7_1_2_d.h" #include "smu/smu_7_1_2_sh_mask.h" +#include "ivsrcid/ivsrcid_vislands30.h" static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev); static void uvd_v5_0_set_irq_funcs(struct amdgpu_device *adev); @@ -104,7 +105,7 @@ static int uvd_v5_0_sw_init(void *handle) int r; /* UVD TRAP */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE, &adev->uvd.inst->irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 8ee1c2eaaa14ed96c01b62a74b787d2fcd38b5ae..598dbeaba63686e2e2476528adace86d035b3f70 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -36,6 +36,7 @@ #include "bif/bif_5_1_d.h" #include "gmc/gmc_8_1_d.h" #include "vi.h" +#include "ivsrcid/ivsrcid_vislands30.h" /* Polaris10/11/12 firmware version */ #define FW_1_130_16 ((1 << 24) | (130 << 16) | (16 << 8)) @@ -247,12 +248,10 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err; - amdgpu_job_free(job); if (fence) *fence = dma_fence_get(f); dma_fence_put(f); @@ -311,19 +310,13 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - if (direct) { - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); - if (r) - goto err; - - amdgpu_job_free(job); - } else { - r = amdgpu_job_submit(job, ring, &ring->adev->vce.entity, + if (direct) + r = amdgpu_job_submit_direct(job, ring, &f); + else + r = amdgpu_job_submit(job, &ring->adev->vce.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &f); - if (r) - goto err; - } + if (r) + goto err; if (fence) *fence = dma_fence_get(f); @@ -400,14 +393,14 @@ static int uvd_v6_0_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* UVD TRAP */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE, &adev->uvd.inst->irq); if (r) return r; /* UVD ENC TRAP */ if (uvd_v6_0_enc_support(adev)) { for (i = 0; i < adev->uvd.num_enc_rings; ++i) { - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 119, &adev->uvd.inst->irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + VISLANDS30_IV_SRCID_UVD_ENC_GEN_PURP, &adev->uvd.inst->irq); if (r) return r; } @@ -425,16 +418,6 @@ static int uvd_v6_0_sw_init(void *handle) adev->uvd.num_enc_rings = 0; DRM_INFO("UVD ENC is disabled\n"); - } else { - struct drm_sched_rq *rq; - ring = &adev->uvd.inst->ring_enc[0]; - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; - r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst->entity_enc, - rq, NULL); - if (r) { - DRM_ERROR("Failed setting up UVD ENC run queue.\n"); - return r; - } } r = amdgpu_uvd_resume(adev); @@ -470,8 +453,6 @@ static int uvd_v6_0_sw_fini(void *handle) return r; if (uvd_v6_0_enc_support(adev)) { - drm_sched_entity_destroy(&adev->uvd.inst->ring_enc[0].sched, &adev->uvd.inst->entity_enc); - for (i = 0; i < adev->uvd.num_enc_rings; ++i) amdgpu_ring_fini(&adev->uvd.inst->ring_enc[i]); } diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index ba244d3b74dbbe7ab8fffc8177822fc9c1eb4d1f..db5f3d78ab12aff3d5f9d70af6fc43b658594c8f 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -39,6 +39,7 @@ #include "hdp/hdp_4_0_offset.h" #include "mmhub/mmhub_1_0_offset.h" #include "mmhub/mmhub_1_0_sh_mask.h" +#include "ivsrcid/uvd/irqsrcs_uvd_7_0.h" #define UVD7_MAX_HW_INSTANCES_VEGA20 2 @@ -249,12 +250,10 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); + r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err; - amdgpu_job_free(job); if (fence) *fence = dma_fence_get(f); dma_fence_put(f); @@ -312,19 +311,13 @@ int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - if (direct) { - r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); - job->fence = dma_fence_get(f); - if (r) - goto err; - - amdgpu_job_free(job); - } else { - r = amdgpu_job_submit(job, ring, &ring->adev->vce.entity, + if (direct) + r = amdgpu_job_submit_direct(job, ring, &f); + else + r = amdgpu_job_submit(job, &ring->adev->vce.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &f); - if (r) - goto err; - } + if (r) + goto err; if (fence) *fence = dma_fence_get(f); @@ -396,19 +389,18 @@ static int uvd_v7_0_early_init(void *handle) static int uvd_v7_0_sw_init(void *handle) { struct amdgpu_ring *ring; - struct drm_sched_rq *rq; int i, j, r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; for (j = 0; j < adev->uvd.num_uvd_inst; j++) { /* UVD TRAP */ - r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], 124, &adev->uvd.inst[j].irq); + r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], UVD_7_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->uvd.inst[j].irq); if (r) return r; /* UVD ENC TRAP */ for (i = 0; i < adev->uvd.num_enc_rings; ++i) { - r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], i + 119, &adev->uvd.inst[j].irq); + r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], i + UVD_7_0__SRCID__UVD_ENC_GEN_PURP, &adev->uvd.inst[j].irq); if (r) return r; } @@ -428,17 +420,6 @@ static int uvd_v7_0_sw_init(void *handle) DRM_INFO("PSP loading UVD firmware\n"); } - for (j = 0; j < adev->uvd.num_uvd_inst; j++) { - ring = &adev->uvd.inst[j].ring_enc[0]; - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; - r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity_enc, - rq, NULL); - if (r) { - DRM_ERROR("(%d)Failed setting up UVD ENC run queue.\n", j); - return r; - } - } - r = amdgpu_uvd_resume(adev); if (r) return r; @@ -491,8 +472,6 @@ static int uvd_v7_0_sw_fini(void *handle) return r; for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { - drm_sched_entity_destroy(&adev->uvd.inst[j].ring_enc[0].sched, &adev->uvd.inst[j].entity_enc); - for (i = 0; i < adev->uvd.num_enc_rings; ++i) amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 99604d0262adaade9b1c9abeecae6675be143fb9..cc6ce6cc03f47968345e6afe0d44003308ed2ecf 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -39,6 +39,7 @@ #include "smu/smu_7_1_2_sh_mask.h" #include "gca/gfx_8_0_d.h" #include "gca/gfx_8_0_sh_mask.h" +#include "ivsrcid/ivsrcid_vislands30.h" #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 @@ -422,7 +423,7 @@ static int vce_v3_0_sw_init(void *handle) int r, i; /* VCE */ - r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 167, &adev->vce.irq); + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_VCE_TRAP, &adev->vce.irq); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index 575bf9709389a44ed56c793f4b8086acc85bf245..65f8860169e95b4030b97c4c8de563e21c93dfe5 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c @@ -39,6 +39,8 @@ #include "mmhub/mmhub_1_0_offset.h" #include "mmhub/mmhub_1_0_sh_mask.h" +#include "ivsrcid/vce/irqsrcs_vce_4_0.h" + #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02 #define VCE_V4_0_FW_SIZE (384 * 1024) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index b82c92084b6f413731d73e230f84b97d31c5b3cc..2ce91a748c4028867c64d7f8d5940fc3e6787cd0 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -35,6 +35,8 @@ #include "mmhub/mmhub_9_1_offset.h" #include "mmhub/mmhub_9_1_sh_mask.h" +#include "ivsrcid/vcn/irqsrcs_vcn_1_0.h" + static int vcn_v1_0_stop(struct amdgpu_device *adev); static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); @@ -77,13 +79,13 @@ static int vcn_v1_0_sw_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* VCN DEC TRAP */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 124, &adev->vcn.irq); + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, VCN_1_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.irq); if (r) return r; /* VCN ENC TRAP */ for (i = 0; i < adev->vcn.num_enc_rings; ++i) { - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, i + 119, + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, i + VCN_1_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.irq); if (r) return r; @@ -600,12 +602,12 @@ static int vcn_v1_0_start(struct amdgpu_device *adev) /* disable byte swapping */ lmi_swap_cntl = 0; - vcn_v1_0_mc_resume(adev); - vcn_1_0_disable_static_power_gating(adev); /* disable clock gating */ vcn_v1_0_disable_clock_gating(adev); + vcn_v1_0_mc_resume(adev); + /* disable interupt */ WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, ~UVD_MASTINT_EN__VCPU_EN_MASK); diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c b/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c index 45aafca7f31560fb4e0862c500046e61030cb336..c5c9b2bc190d5cdd679e2fd7252d235816cbb166 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c @@ -51,6 +51,7 @@ int vega10_reg_base_init(struct amdgpu_device *adev) adev->reg_offset[PWR_HWIP][i] = (uint32_t *)(&(PWR_BASE.instance[i])); adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIF_BASE.instance[i])); adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i])); + adev->reg_offset[CLK_HWIP][i] = (uint32_t *)(&(CLK_BASE.instance[i])); } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 4ac1288ab7dff4fee300e3cdd1b359628173da71..42c8ad105b0503f1471f06215aa7e46b074aaa88 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -1363,11 +1363,11 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, if (adev->cg_flags & (AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_MC_MGCG)) { if (adev->cg_flags & AMD_CG_SUPPORT_MC_LS) { - pp_support_state = AMD_CG_SUPPORT_MC_LS; + pp_support_state = PP_STATE_SUPPORT_LS; pp_state = PP_STATE_LS; } if (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG) { - pp_support_state |= AMD_CG_SUPPORT_MC_MGCG; + pp_support_state |= PP_STATE_SUPPORT_CG; pp_state |= PP_STATE_CG; } if (state == AMD_CG_STATE_UNGATE) @@ -1382,11 +1382,11 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, if (adev->cg_flags & (AMD_CG_SUPPORT_SDMA_LS | AMD_CG_SUPPORT_SDMA_MGCG)) { if (adev->cg_flags & AMD_CG_SUPPORT_SDMA_LS) { - pp_support_state = AMD_CG_SUPPORT_SDMA_LS; + pp_support_state = PP_STATE_SUPPORT_LS; pp_state = PP_STATE_LS; } if (adev->cg_flags & AMD_CG_SUPPORT_SDMA_MGCG) { - pp_support_state |= AMD_CG_SUPPORT_SDMA_MGCG; + pp_support_state |= PP_STATE_SUPPORT_CG; pp_state |= PP_STATE_CG; } if (state == AMD_CG_STATE_UNGATE) @@ -1401,11 +1401,11 @@ static int vi_common_set_clockgating_state_by_smu(void *handle, if (adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_HDP_MGCG)) { if (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS) { - pp_support_state = AMD_CG_SUPPORT_HDP_LS; + pp_support_state = PP_STATE_SUPPORT_LS; pp_state = PP_STATE_LS; } if (adev->cg_flags & AMD_CG_SUPPORT_HDP_MGCG) { - pp_support_state |= AMD_CG_SUPPORT_HDP_MGCG; + pp_support_state |= PP_STATE_SUPPORT_CG; pp_state |= PP_STATE_CG; } if (state == AMD_CG_STATE_UNGATE) diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index 4c35625eb2c773270d8252a46151262b6e0a2113..325083b0297e4a3d165a50410c3af180d987f7b2 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -9,14 +9,6 @@ config DRM_AMD_DC support for AMDGPU. This adds required support for Vega and Raven ASICs. -config DRM_AMD_DC_DCN1_0 - bool "DCN 1.0 Raven family" - depends on DRM_AMD_DC && X86 - default y - help - Choose this option if you want to have - RV family for display engine - config DEBUG_KERNEL_DC bool "Enable kgdb break in DC" depends on DRM_AMD_DC diff --git a/drivers/gpu/drm/amd/display/TODO b/drivers/gpu/drm/amd/display/TODO index 357d596484016a8f92cd9afd655cece66857b606..a8a6c106e8c74ff8ebe7c6faff771ceb69f46036 100644 --- a/drivers/gpu/drm/amd/display/TODO +++ b/drivers/gpu/drm/amd/display/TODO @@ -97,10 +97,10 @@ share it with drivers. But that's a very long term goal, and by far not just an issue with DC - other drivers, especially around DP sink handling, are equally guilty. -19. The DC logger is still a rather sore thing, but I know that the DRM_DEBUG -stuff just isn't up to the challenges either. We need to figure out something -that integrates better with DRM and linux debug printing, while not being -useless with filtering output. dynamic debug printing might be an option. +19. DONE - The DC logger is still a rather sore thing, but I know that the +DRM_DEBUG stuff just isn't up to the challenges either. We need to figure out +something that integrates better with DRM and linux debug printing, while not +being useless with filtering output. dynamic debug printing might be an option. 20. Use kernel i2c device to program HDMI retimer. Some boards have an HDMI retimer that we need to program to pass PHY compliance. Currently that's 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 28da18b1da528f32cc6c7db847c52ef149a2a59d..5fc13e71a3b514e1696e6d8e2b1a957d65b7db1b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -60,7 +60,7 @@ #include "modules/inc/mod_freesync.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "ivsrcid/irqsrcs_dcn_1_0.h" #include "dcn/dcn_1_0_offset.h" @@ -1041,7 +1041,7 @@ static void handle_hpd_rx_irq(void *param) if (dc_link->type != dc_connection_mst_branch) mutex_lock(&aconnector->hpd_lock); - if (dc_link_handle_hpd_rx_irq(dc_link, NULL) && + if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) && !is_mst_root_connector) { /* Downstream Port status changed. */ if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) { @@ -1192,7 +1192,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) return 0; } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 /* Register IRQ sources and initialize IRQ callbacks */ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) { @@ -1526,7 +1526,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) goto fail; } break; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case CHIP_RAVEN: if (dcn10_register_irq_handlers(dm->adev)) { DRM_ERROR("DM: Failed to initialize IRQ\n"); @@ -1725,7 +1725,7 @@ static int dm_early_init(void *handle) adev->mode_info.num_dig = 6; adev->mode_info.plane_type = dm_plane_type_default; break; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case CHIP_RAVEN: adev->mode_info.num_crtc = 4; adev->mode_info.num_hpd = 4; @@ -3094,15 +3094,25 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, else domain = AMDGPU_GEM_DOMAIN_VRAM; - r = amdgpu_bo_pin(rbo, domain, &afb->address); - amdgpu_bo_unreserve(rbo); - + r = amdgpu_bo_pin(rbo, domain); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) DRM_ERROR("Failed to pin framebuffer with error %d\n", r); + amdgpu_bo_unreserve(rbo); return r; } + r = amdgpu_ttm_alloc_gart(&rbo->tbo); + if (unlikely(r != 0)) { + amdgpu_bo_unpin(rbo); + amdgpu_bo_unreserve(rbo); + DRM_ERROR("%p bind failed\n", rbo); + return r; + } + amdgpu_bo_unreserve(rbo); + + afb->address = amdgpu_bo_gpu_offset(rbo); + amdgpu_bo_ref(rbo); if (dm_plane_state_new->dc_state && @@ -3499,7 +3509,6 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, aconnector->base.stereo_allowed = false; aconnector->base.dpms = DRM_MODE_DPMS_OFF; aconnector->hpd.hpd = AMDGPU_HPD_NONE; /* not used */ - mutex_init(&aconnector->hpd_lock); /* configure support HPD hot plug connector_>polled default value is 0 @@ -3508,9 +3517,13 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, switch (connector_type) { case DRM_MODE_CONNECTOR_HDMIA: aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; + aconnector->base.ycbcr_420_allowed = + link->link_enc->features.ycbcr420_supported ? true : false; break; case DRM_MODE_CONNECTOR_DisplayPort: aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; + aconnector->base.ycbcr_420_allowed = + link->link_enc->features.ycbcr420_supported ? true : false; break; case DRM_MODE_CONNECTOR_DVID: aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index cf5ea69e46ad300263f271bf4ae4d8e91ea17235..0d9e410ca01e2d9deca8d37021e4cd3d53f16539 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -26,113 +26,667 @@ #include <linux/debugfs.h> #include "dc.h" -#include "dc_link.h" - #include "amdgpu.h" #include "amdgpu_dm.h" #include "amdgpu_dm_debugfs.h" -static ssize_t dp_link_rate_debugfs_read(struct file *f, char __user *buf, +/* function description + * get/ set DP configuration: lane_count, link_rate, spread_spectrum + * + * valid lane count value: 1, 2, 4 + * valid link rate value: + * 06h = 1.62Gbps per lane + * 0Ah = 2.7Gbps per lane + * 0Ch = 3.24Gbps per lane + * 14h = 5.4Gbps per lane + * 1Eh = 8.1Gbps per lane + * + * debugfs is located at /sys/kernel/debug/dri/0/DP-x/link_settings + * + * --- to get dp configuration + * + * cat link_settings + * + * It will list current, verified, reported, preferred dp configuration. + * current -- for current video mode + * verified --- maximum configuration which pass link training + * reported --- DP rx report caps (DPCD register offset 0, 1 2) + * preferred --- user force settings + * + * --- set (or force) dp configuration + * + * echo <lane_count> <link_rate> > link_settings + * + * for example, to force to 2 lane, 2.7GHz, + * echo 4 0xa > link_settings + * + * spread_spectrum could not be changed dynamically. + * + * in case invalid lane count, link rate are force, no hw programming will be + * done. please check link settings after force operation to see if HW get + * programming. + * + * cat link_settings + * + * check current and preferred settings. + * + */ +static ssize_t dp_link_settings_read(struct file *f, char __user *buf, size_t size, loff_t *pos) { - /* TODO: create method to read link rate */ - return 1; -} + struct amdgpu_dm_connector *connector = file_inode(f)->i_private; + struct dc_link *link = connector->dc_link; + char *rd_buf = NULL; + char *rd_buf_ptr = NULL; + const uint32_t rd_buf_size = 100; + uint32_t result = 0; + uint8_t str_len = 0; + int r; -static ssize_t dp_link_rate_debugfs_write(struct file *f, const char __user *buf, - size_t size, loff_t *pos) -{ - /* TODO: create method to write link rate */ - return 1; -} + if (*pos & 3 || size & 3) + return -EINVAL; -static ssize_t dp_lane_count_debugfs_read(struct file *f, char __user *buf, - size_t size, loff_t *pos) -{ - /* TODO: create method to read lane count */ - return 1; -} + rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL); + if (!rd_buf) + return 0; -static ssize_t dp_lane_count_debugfs_write(struct file *f, const char __user *buf, - size_t size, loff_t *pos) -{ - /* TODO: create method to write lane count */ - return 1; -} + rd_buf_ptr = rd_buf; -static ssize_t dp_voltage_swing_debugfs_read(struct file *f, char __user *buf, - size_t size, loff_t *pos) -{ - /* TODO: create method to read voltage swing */ - return 1; -} + str_len = strlen("Current: %d %d %d "); + snprintf(rd_buf_ptr, str_len, "Current: %d %d %d ", + link->cur_link_settings.lane_count, + link->cur_link_settings.link_rate, + link->cur_link_settings.link_spread); + rd_buf_ptr += str_len; -static ssize_t dp_voltage_swing_debugfs_write(struct file *f, const char __user *buf, - size_t size, loff_t *pos) -{ - /* TODO: create method to write voltage swing */ - return 1; + str_len = strlen("Verified: %d %d %d "); + snprintf(rd_buf_ptr, str_len, "Verified: %d %d %d ", + link->verified_link_cap.lane_count, + link->verified_link_cap.link_rate, + link->verified_link_cap.link_spread); + rd_buf_ptr += str_len; + + str_len = strlen("Reported: %d %d %d "); + snprintf(rd_buf_ptr, str_len, "Reported: %d %d %d ", + link->reported_link_cap.lane_count, + link->reported_link_cap.link_rate, + link->reported_link_cap.link_spread); + rd_buf_ptr += str_len; + + str_len = strlen("Preferred: %d %d %d "); + snprintf(rd_buf_ptr, str_len, "Preferred: %d %d %d\n", + link->preferred_link_setting.lane_count, + link->preferred_link_setting.link_rate, + link->preferred_link_setting.link_spread); + + while (size) { + if (*pos >= rd_buf_size) + break; + + r = put_user(*(rd_buf + result), buf); + if (r) + return r; /* r = -EFAULT */ + + buf += 1; + size -= 1; + *pos += 1; + result += 1; + } + + kfree(rd_buf); + return result; } -static ssize_t dp_pre_emphasis_debugfs_read(struct file *f, char __user *buf, +static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) { - /* TODO: create method to read pre-emphasis */ - return 1; + struct amdgpu_dm_connector *connector = file_inode(f)->i_private; + struct dc_link *link = connector->dc_link; + struct dc *dc = (struct dc *)link->dc; + struct dc_link_settings prefer_link_settings; + char *wr_buf = NULL; + char *wr_buf_ptr = NULL; + const uint32_t wr_buf_size = 40; + int r; + int bytes_from_user; + char *sub_str; + /* 0: lane_count; 1: link_rate */ + uint8_t param_index = 0; + long param[2]; + const char delimiter[3] = {' ', '\n', '\0'}; + bool valid_input = false; + + if (size == 0) + return -EINVAL; + + wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL); + if (!wr_buf) + return -EINVAL; + wr_buf_ptr = wr_buf; + + r = copy_from_user(wr_buf_ptr, buf, wr_buf_size); + + /* r is bytes not be copied */ + if (r >= wr_buf_size) { + kfree(wr_buf); + DRM_DEBUG_DRIVER("user data not read\n"); + return -EINVAL; + } + + bytes_from_user = wr_buf_size - r; + + while (isspace(*wr_buf_ptr)) + wr_buf_ptr++; + + while ((*wr_buf_ptr != '\0') && (param_index < 2)) { + + sub_str = strsep(&wr_buf_ptr, delimiter); + + r = kstrtol(sub_str, 16, ¶m[param_index]); + + if (r) + DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r); + + param_index++; + while (isspace(*wr_buf_ptr)) + wr_buf_ptr++; + } + + switch (param[0]) { + case LANE_COUNT_ONE: + case LANE_COUNT_TWO: + case LANE_COUNT_FOUR: + valid_input = true; + break; + default: + break; + } + + switch (param[1]) { + case LINK_RATE_LOW: + case LINK_RATE_HIGH: + case LINK_RATE_RBR2: + case LINK_RATE_HIGH2: + case LINK_RATE_HIGH3: + valid_input = true; + break; + default: + break; + } + + if (!valid_input) { + kfree(wr_buf); + DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n"); + return bytes_from_user; + } + + /* save user force lane_count, link_rate to preferred settings + * spread spectrum will not be changed + */ + prefer_link_settings.link_spread = link->cur_link_settings.link_spread; + prefer_link_settings.lane_count = param[0]; + prefer_link_settings.link_rate = param[1]; + + dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link); + + kfree(wr_buf); + return bytes_from_user; } -static ssize_t dp_pre_emphasis_debugfs_write(struct file *f, const char __user *buf, +/* function: get current DP PHY settings: voltage swing, pre-emphasis, + * post-cursor2 (defined by VESA DP specification) + * + * valid values + * voltage swing: 0,1,2,3 + * pre-emphasis : 0,1,2,3 + * post cursor2 : 0,1,2,3 + * + * + * how to use this debugfs + * + * debugfs is located at /sys/kernel/debug/dri/0/DP-x + * + * there will be directories, like DP-1, DP-2,DP-3, etc. for DP display + * + * To figure out which DP-x is the display for DP to be check, + * cd DP-x + * ls -ll + * There should be debugfs file, like link_settings, phy_settings. + * cat link_settings + * from lane_count, link_rate to figure which DP-x is for display to be worked + * on + * + * To get current DP PHY settings, + * cat phy_settings + * + * To change DP PHY settings, + * echo <voltage_swing> <pre-emphasis> <post_cursor2> > phy_settings + * for examle, to change voltage swing to 2, pre-emphasis to 3, post_cursor2 to + * 0, + * echo 2 3 0 > phy_settings + * + * To check if change be applied, get current phy settings by + * cat phy_settings + * + * In case invalid values are set by user, like + * echo 1 4 0 > phy_settings + * + * HW will NOT be programmed by these settings. + * cat phy_settings will show the previous valid settings. + */ +static ssize_t dp_phy_settings_read(struct file *f, char __user *buf, size_t size, loff_t *pos) { - /* TODO: create method to write pre-emphasis */ - return 1; + struct amdgpu_dm_connector *connector = file_inode(f)->i_private; + struct dc_link *link = connector->dc_link; + char *rd_buf = NULL; + const uint32_t rd_buf_size = 20; + uint32_t result = 0; + int r; + + if (*pos & 3 || size & 3) + return -EINVAL; + + rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL); + if (!rd_buf) + return -EINVAL; + + snprintf(rd_buf, rd_buf_size, " %d %d %d ", + link->cur_lane_setting.VOLTAGE_SWING, + link->cur_lane_setting.PRE_EMPHASIS, + link->cur_lane_setting.POST_CURSOR2); + + while (size) { + if (*pos >= rd_buf_size) + break; + + r = put_user((*(rd_buf + result)), buf); + if (r) + return r; /* r = -EFAULT */ + + buf += 1; + size -= 1; + *pos += 1; + result += 1; + } + + kfree(rd_buf); + return result; } -static ssize_t dp_phy_test_pattern_debugfs_read(struct file *f, char __user *buf, +static ssize_t dp_phy_settings_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) { - /* TODO: create method to read PHY test pattern */ - return 1; + struct amdgpu_dm_connector *connector = file_inode(f)->i_private; + struct dc_link *link = connector->dc_link; + struct dc *dc = (struct dc *)link->dc; + char *wr_buf = NULL; + char *wr_buf_ptr = NULL; + uint32_t wr_buf_size = 40; + int r; + int bytes_from_user; + char *sub_str; + uint8_t param_index = 0; + long param[3]; + const char delimiter[3] = {' ', '\n', '\0'}; + bool use_prefer_link_setting; + struct link_training_settings link_lane_settings; + + if (size == 0) + return 0; + + wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL); + if (!wr_buf) + return 0; + wr_buf_ptr = wr_buf; + + r = copy_from_user(wr_buf_ptr, buf, wr_buf_size); + + /* r is bytes not be copied */ + if (r >= wr_buf_size) { + kfree(wr_buf); + DRM_DEBUG_DRIVER("user data not be read\n"); + return 0; + } + + bytes_from_user = wr_buf_size - r; + + while (isspace(*wr_buf_ptr)) + wr_buf_ptr++; + + while ((*wr_buf_ptr != '\0') && (param_index < 3)) { + + sub_str = strsep(&wr_buf_ptr, delimiter); + + r = kstrtol(sub_str, 16, ¶m[param_index]); + + if (r) + DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r); + + param_index++; + while (isspace(*wr_buf_ptr)) + wr_buf_ptr++; + } + + if ((param[0] > VOLTAGE_SWING_MAX_LEVEL) || + (param[1] > PRE_EMPHASIS_MAX_LEVEL) || + (param[2] > POST_CURSOR2_MAX_LEVEL)) { + kfree(wr_buf); + DRM_DEBUG_DRIVER("Invalid Input No HW will be programmed\n"); + return bytes_from_user; + } + + /* get link settings: lane count, link rate */ + use_prefer_link_setting = + ((link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) && + (link->test_pattern_enabled)); + + memset(&link_lane_settings, 0, sizeof(link_lane_settings)); + + if (use_prefer_link_setting) { + link_lane_settings.link_settings.lane_count = + link->preferred_link_setting.lane_count; + link_lane_settings.link_settings.link_rate = + link->preferred_link_setting.link_rate; + link_lane_settings.link_settings.link_spread = + link->preferred_link_setting.link_spread; + } else { + link_lane_settings.link_settings.lane_count = + link->cur_link_settings.lane_count; + link_lane_settings.link_settings.link_rate = + link->cur_link_settings.link_rate; + link_lane_settings.link_settings.link_spread = + link->cur_link_settings.link_spread; + } + + /* apply phy settings from user */ + for (r = 0; r < link_lane_settings.link_settings.lane_count; r++) { + link_lane_settings.lane_settings[r].VOLTAGE_SWING = + (enum dc_voltage_swing) (param[0]); + link_lane_settings.lane_settings[r].PRE_EMPHASIS = + (enum dc_pre_emphasis) (param[1]); + link_lane_settings.lane_settings[r].POST_CURSOR2 = + (enum dc_post_cursor2) (param[2]); + } + + /* program ASIC registers and DPCD registers */ + dc_link_set_drive_settings(dc, &link_lane_settings, link); + + kfree(wr_buf); + return bytes_from_user; } +/* function description + * + * set PHY layer or Link layer test pattern + * PHY test pattern is used for PHY SI check. + * Link layer test will not affect PHY SI. + * + * Reset Test Pattern: + * 0 = DP_TEST_PATTERN_VIDEO_MODE + * + * PHY test pattern supported: + * 1 = DP_TEST_PATTERN_D102 + * 2 = DP_TEST_PATTERN_SYMBOL_ERROR + * 3 = DP_TEST_PATTERN_PRBS7 + * 4 = DP_TEST_PATTERN_80BIT_CUSTOM + * 5 = DP_TEST_PATTERN_CP2520_1 + * 6 = DP_TEST_PATTERN_CP2520_2 = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE + * 7 = DP_TEST_PATTERN_CP2520_3 + * + * DP PHY Link Training Patterns + * 8 = DP_TEST_PATTERN_TRAINING_PATTERN1 + * 9 = DP_TEST_PATTERN_TRAINING_PATTERN2 + * a = DP_TEST_PATTERN_TRAINING_PATTERN3 + * b = DP_TEST_PATTERN_TRAINING_PATTERN4 + * + * DP Link Layer Test pattern + * c = DP_TEST_PATTERN_COLOR_SQUARES + * d = DP_TEST_PATTERN_COLOR_SQUARES_CEA + * e = DP_TEST_PATTERN_VERTICAL_BARS + * f = DP_TEST_PATTERN_HORIZONTAL_BARS + * 10= DP_TEST_PATTERN_COLOR_RAMP + * + * debugfs phy_test_pattern is located at /syskernel/debug/dri/0/DP-x + * + * --- set test pattern + * echo <test pattern #> > test_pattern + * + * If test pattern # is not supported, NO HW programming will be done. + * for DP_TEST_PATTERN_80BIT_CUSTOM, it needs extra 10 bytes of data + * for the user pattern. input 10 bytes data are separated by space + * + * echo 0x4 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa > test_pattern + * + * --- reset test pattern + * echo 0 > test_pattern + * + * --- HPD detection is disabled when set PHY test pattern + * + * when PHY test pattern (pattern # within [1,7]) is set, HPD pin of HW ASIC + * is disable. User could unplug DP display from DP connected and plug scope to + * check test pattern PHY SI. + * If there is need unplug scope and plug DP display back, do steps below: + * echo 0 > phy_test_pattern + * unplug scope + * plug DP display. + * + * "echo 0 > phy_test_pattern" will re-enable HPD pin again so that video sw + * driver could detect "unplug scope" and "plug DP display" + */ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) { - /* TODO: create method to write PHY test pattern */ - return 1; -} + struct amdgpu_dm_connector *connector = file_inode(f)->i_private; + struct dc_link *link = connector->dc_link; + char *wr_buf = NULL; + char *wr_buf_ptr = NULL; + uint32_t wr_buf_size = 100; + uint32_t wr_buf_count = 0; + int r; + int bytes_from_user; + char *sub_str = NULL; + uint8_t param_index = 0; + uint8_t param_nums = 0; + long param[11] = {0x0}; + const char delimiter[3] = {' ', '\n', '\0'}; + enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED; + bool disable_hpd = false; + bool valid_test_pattern = false; + /* init with defalut 80bit custom pattern */ + uint8_t custom_pattern[10] = { + 0x1f, 0x7c, 0xf0, 0xc1, 0x07, + 0x1f, 0x7c, 0xf0, 0xc1, 0x07 + }; + struct dc_link_settings prefer_link_settings = {LANE_COUNT_UNKNOWN, + LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED}; + struct dc_link_settings cur_link_settings = {LANE_COUNT_UNKNOWN, + LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED}; + struct link_training_settings link_training_settings; + int i; -static const struct file_operations dp_link_rate_fops = { - .owner = THIS_MODULE, - .read = dp_link_rate_debugfs_read, - .write = dp_link_rate_debugfs_write, - .llseek = default_llseek -}; + if (size == 0) + return 0; -static const struct file_operations dp_lane_count_fops = { - .owner = THIS_MODULE, - .read = dp_lane_count_debugfs_read, - .write = dp_lane_count_debugfs_write, - .llseek = default_llseek -}; + wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL); + if (!wr_buf) + return 0; + wr_buf_ptr = wr_buf; + + r = copy_from_user(wr_buf_ptr, buf, wr_buf_size); + + /* r is bytes not be copied */ + if (r >= wr_buf_size) { + kfree(wr_buf); + DRM_DEBUG_DRIVER("user data not be read\n"); + return 0; + } + + bytes_from_user = wr_buf_size - r; + + /* check number of parameters. isspace could not differ space and \n */ + while ((*wr_buf_ptr != 0xa) && (wr_buf_count < wr_buf_size)) { + /* skip space*/ + while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) { + wr_buf_ptr++; + wr_buf_count++; + } + + if (wr_buf_count == wr_buf_size) + break; + + /* skip non-space*/ + while ((!isspace(*wr_buf_ptr)) && (wr_buf_count < wr_buf_size)) { + wr_buf_ptr++; + wr_buf_count++; + } + + param_nums++; + + if (wr_buf_count == wr_buf_size) + break; + } + + /* max 11 parameters */ + if (param_nums > 11) + param_nums = 11; + + wr_buf_ptr = wr_buf; /* reset buf pinter */ + wr_buf_count = 0; /* number of char already checked */ + + while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) { + wr_buf_ptr++; + wr_buf_count++; + } + + while (param_index < param_nums) { + /* after strsep, wr_buf_ptr will be moved to after space */ + sub_str = strsep(&wr_buf_ptr, delimiter); + + r = kstrtol(sub_str, 16, ¶m[param_index]); + + if (r) + DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r); + + param_index++; + } + + test_pattern = param[0]; + + switch (test_pattern) { + case DP_TEST_PATTERN_VIDEO_MODE: + case DP_TEST_PATTERN_COLOR_SQUARES: + case DP_TEST_PATTERN_COLOR_SQUARES_CEA: + case DP_TEST_PATTERN_VERTICAL_BARS: + case DP_TEST_PATTERN_HORIZONTAL_BARS: + case DP_TEST_PATTERN_COLOR_RAMP: + valid_test_pattern = true; + break; + + case DP_TEST_PATTERN_D102: + case DP_TEST_PATTERN_SYMBOL_ERROR: + case DP_TEST_PATTERN_PRBS7: + case DP_TEST_PATTERN_80BIT_CUSTOM: + case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE: + case DP_TEST_PATTERN_TRAINING_PATTERN4: + disable_hpd = true; + valid_test_pattern = true; + break; + + default: + valid_test_pattern = false; + test_pattern = DP_TEST_PATTERN_UNSUPPORTED; + break; + } + + if (!valid_test_pattern) { + kfree(wr_buf); + DRM_DEBUG_DRIVER("Invalid Test Pattern Parameters\n"); + return bytes_from_user; + } + + if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) { + for (i = 0; i < 10; i++) { + if ((uint8_t) param[i + 1] != 0x0) + break; + } + + if (i < 10) { + /* not use default value */ + for (i = 0; i < 10; i++) + custom_pattern[i] = (uint8_t) param[i + 1]; + } + } + + /* Usage: set DP physical test pattern using debugfs with normal DP + * panel. Then plug out DP panel and connect a scope to measure + * For normal video mode and test pattern generated from CRCT, + * they are visibile to user. So do not disable HPD. + * Video Mode is also set to clear the test pattern, so enable HPD + * because it might have been disabled after a test pattern was set. + * AUX depends on HPD * sequence dependent, do not move! + */ + if (!disable_hpd) + dc_link_enable_hpd(link); + + prefer_link_settings.lane_count = link->verified_link_cap.lane_count; + prefer_link_settings.link_rate = link->verified_link_cap.link_rate; + prefer_link_settings.link_spread = link->verified_link_cap.link_spread; + + cur_link_settings.lane_count = link->cur_link_settings.lane_count; + cur_link_settings.link_rate = link->cur_link_settings.link_rate; + cur_link_settings.link_spread = link->cur_link_settings.link_spread; + + link_training_settings.link_settings = cur_link_settings; + + + if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) { + if (prefer_link_settings.lane_count != LANE_COUNT_UNKNOWN && + prefer_link_settings.link_rate != LINK_RATE_UNKNOWN && + (prefer_link_settings.lane_count != cur_link_settings.lane_count || + prefer_link_settings.link_rate != cur_link_settings.link_rate)) + link_training_settings.link_settings = prefer_link_settings; + } + + for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++) + link_training_settings.lane_settings[i] = link->cur_lane_setting; + + dc_link_set_test_pattern( + link, + test_pattern, + &link_training_settings, + custom_pattern, + 10); + + /* Usage: Set DP physical test pattern using AMDDP with normal DP panel + * Then plug out DP panel and connect a scope to measure DP PHY signal. + * Need disable interrupt to avoid SW driver disable DP output. This is + * done after the test pattern is set. + */ + if (valid_test_pattern && disable_hpd) + dc_link_disable_hpd(link); + + kfree(wr_buf); + + return bytes_from_user; +} -static const struct file_operations dp_voltage_swing_fops = { +static const struct file_operations dp_link_settings_debugfs_fops = { .owner = THIS_MODULE, - .read = dp_voltage_swing_debugfs_read, - .write = dp_voltage_swing_debugfs_write, + .read = dp_link_settings_read, + .write = dp_link_settings_write, .llseek = default_llseek }; -static const struct file_operations dp_pre_emphasis_fops = { +static const struct file_operations dp_phy_settings_debugfs_fop = { .owner = THIS_MODULE, - .read = dp_pre_emphasis_debugfs_read, - .write = dp_pre_emphasis_debugfs_write, + .read = dp_phy_settings_read, + .write = dp_phy_settings_write, .llseek = default_llseek }; static const struct file_operations dp_phy_test_pattern_fops = { .owner = THIS_MODULE, - .read = dp_phy_test_pattern_debugfs_read, .write = dp_phy_test_pattern_debugfs_write, .llseek = default_llseek }; @@ -141,11 +695,9 @@ static const struct { char *name; const struct file_operations *fops; } dp_debugfs_entries[] = { - {"link_rate", &dp_link_rate_fops}, - {"lane_count", &dp_lane_count_fops}, - {"voltage_swing", &dp_voltage_swing_fops}, - {"pre_emphasis", &dp_pre_emphasis_fops}, - {"phy_test_pattern", &dp_phy_test_pattern_fops} + {"link_settings", &dp_link_settings_debugfs_fops}, + {"phy_settings", &dp_phy_settings_debugfs_fop}, + {"test_pattern", &dp_phy_test_pattern_fops} }; int connector_debugfs_init(struct amdgpu_dm_connector *connector) 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 b19dc4cfc0301661a3aa1db6b2f822a6fd6887ca..8403b6a9a77bd0008ab30b67153db5392206a5b6 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 @@ -169,6 +169,11 @@ static void get_payload_table( mutex_unlock(&mst_mgr->payload_lock); } +void dm_helpers_dp_update_branch_info( + struct dc_context *ctx, + const struct dc_link *link) +{} + /* * Writes payload allocation table in immediate downstream device. */ @@ -454,6 +459,22 @@ bool dm_helpers_submit_i2c( return result; } +bool dm_helpers_is_dp_sink_present(struct dc_link *link) +{ + bool dp_sink_present; + struct amdgpu_dm_connector *aconnector = link->priv; + + if (!aconnector) { + BUG_ON("Failed to found connector for link!"); + return true; + } + + mutex_lock(&aconnector->dm_dp_aux.aux.hw_mutex); + dp_sink_present = dc_link_is_dp_sink_present(link); + mutex_unlock(&aconnector->dm_dp_aux.aux.hw_mutex); + return dp_sink_present; +} + enum dc_edid_status dm_helpers_read_local_edid( struct dc_context *ctx, struct dc_link *link, @@ -498,8 +519,8 @@ enum dc_edid_status dm_helpers_read_local_edid( edid_status, aconnector->base.name); if (link->aux_mode) { - union test_request test_request = {0}; - union test_response test_response = {0}; + union test_request test_request = { {0} }; + union test_response test_response = { {0} }; dm_helpers_dp_read_dpcd(ctx, link, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 65f210d3497bb4d80f36eaa415350dfe2e5ab3d9..9a300732ba3747a86541d8b62c2562e27e96b9fc 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -80,55 +80,72 @@ static void log_dpcd(uint8_t type, static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { - enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ? - I2C_MOT_TRUE : I2C_MOT_FALSE; - enum ddc_result res; - uint32_t read_bytes = msg->size; + ssize_t result = 0; + enum i2caux_transaction_action action; + enum aux_transaction_type type; if (WARN_ON(msg->size > 16)) return -E2BIG; switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_READ: - res = dal_ddc_service_read_dpcd_data( - TO_DM_AUX(aux)->ddc_service, - false, - I2C_MOT_UNDEF, - msg->address, - msg->buffer, - msg->size, - &read_bytes); + type = AUX_TRANSACTION_TYPE_DP; + action = I2CAUX_TRANSACTION_ACTION_DP_READ; + + result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, + msg->address, + &msg->reply, + msg->buffer, + msg->size, + type, + action); break; case DP_AUX_NATIVE_WRITE: - res = dal_ddc_service_write_dpcd_data( - TO_DM_AUX(aux)->ddc_service, - false, - I2C_MOT_UNDEF, - msg->address, - msg->buffer, - msg->size); + type = AUX_TRANSACTION_TYPE_DP; + action = I2CAUX_TRANSACTION_ACTION_DP_WRITE; + + dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, + msg->address, + &msg->reply, + msg->buffer, + msg->size, + type, + action); + result = msg->size; break; case DP_AUX_I2C_READ: - res = dal_ddc_service_read_dpcd_data( - TO_DM_AUX(aux)->ddc_service, - true, - mot, - msg->address, - msg->buffer, - msg->size, - &read_bytes); + type = AUX_TRANSACTION_TYPE_I2C; + if (msg->request & DP_AUX_I2C_MOT) + action = I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT; + else + action = I2CAUX_TRANSACTION_ACTION_I2C_READ; + + result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, + msg->address, + &msg->reply, + msg->buffer, + msg->size, + type, + action); break; case DP_AUX_I2C_WRITE: - res = dal_ddc_service_write_dpcd_data( - TO_DM_AUX(aux)->ddc_service, - true, - mot, - msg->address, - msg->buffer, - msg->size); + type = AUX_TRANSACTION_TYPE_I2C; + if (msg->request & DP_AUX_I2C_MOT) + action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT; + else + action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE; + + dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, + msg->address, + &msg->reply, + msg->buffer, + msg->size, + type, + action); + result = msg->size; break; default: - return 0; + return -EINVAL; } #ifdef TRACE_DPCD @@ -139,9 +156,10 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, r == DDC_RESULT_SUCESSFULL); #endif - if (res != DDC_RESULT_SUCESSFULL) - return -EIO; - return read_bytes; + if (result < 0) /* DC doesn't know about kernel error codes */ + result = -EIO; + + return result; } static enum drm_connector_status diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c index 50e863024f585d102338462e7205fd71961f64ca..c69ae78d82b24a338f5a4dab7a0c35c13de9b828 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c @@ -192,6 +192,33 @@ static enum amd_pp_clock_type dc_to_pp_clock_type( return amd_pp_clk_type; } +static enum dm_pp_clocks_state pp_to_dc_powerlevel_state( + enum PP_DAL_POWERLEVEL max_clocks_state) +{ + switch (max_clocks_state) { + case PP_DAL_POWERLEVEL_0: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_0; + case PP_DAL_POWERLEVEL_1: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_1; + case PP_DAL_POWERLEVEL_2: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_2; + case PP_DAL_POWERLEVEL_3: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_3; + case PP_DAL_POWERLEVEL_4: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_4; + case PP_DAL_POWERLEVEL_5: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_5; + case PP_DAL_POWERLEVEL_6: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_6; + case PP_DAL_POWERLEVEL_7: + return DM_PP_CLOCKS_DPM_STATE_LEVEL_7; + default: + DRM_ERROR("DM_PPLIB: invalid powerlevel state: %d!\n", + max_clocks_state); + return DM_PP_CLOCKS_STATE_INVALID; + } +} + static void pp_to_dc_clock_levels( const struct amd_pp_clocks *pp_clks, struct dm_pp_clock_levels *dc_clks, @@ -441,7 +468,7 @@ bool dm_pp_get_static_clocks( if (ret) return false; - static_clk_info->max_clocks_state = pp_clk_info.max_clocks_state; + static_clk_info->max_clocks_state = pp_to_dc_powerlevel_state(pp_clk_info.max_clocks_state); static_clk_info->max_mclk_khz = pp_clk_info.max_memory_clock; static_clk_info->max_sclk_khz = pp_clk_info.max_engine_clock; diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index aed538a4d1bace016fb37526d099656227b81348..532a515fda9a11a0f03cb3c700152712ba4a7023 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -25,7 +25,7 @@ DC_LIBS = basics bios calcs dce gpio i2caux irq virtual -ifdef CONFIG_DRM_AMD_DC_DCN1_0 +ifdef CONFIG_X86 DC_LIBS += dcn10 dml endif diff --git a/drivers/gpu/drm/amd/display/dc/basics/Makefile b/drivers/gpu/drm/amd/display/dc/basics/Makefile index b49ea96b5daeef2a2ec7e51262f22ca69877e22a..a50a76471107eb768613239f984cbe9384ed628a 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/Makefile +++ b/drivers/gpu/drm/amd/display/dc/basics/Makefile @@ -25,7 +25,7 @@ # subcomponents. BASICS = conversion.o fixpt31_32.o \ - logger.o log_helpers.o vector.o + log_helpers.o vector.o AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS)) diff --git a/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c b/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c index f6c00a51d51a350e3dffb9353717f154c258b072..26583f346c3957d74da49e75ce4ed677a5958b40 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/basics/log_helpers.c @@ -28,77 +28,12 @@ #include "include/logger_interface.h" #include "dm_helpers.h" -#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) - -struct dc_signal_type_info { - enum signal_type type; - char name[MAX_NAME_LEN]; -}; - -static const struct dc_signal_type_info signal_type_info_tbl[] = { - {SIGNAL_TYPE_NONE, "NC"}, - {SIGNAL_TYPE_DVI_SINGLE_LINK, "DVI"}, - {SIGNAL_TYPE_DVI_DUAL_LINK, "DDVI"}, - {SIGNAL_TYPE_HDMI_TYPE_A, "HDMIA"}, - {SIGNAL_TYPE_LVDS, "LVDS"}, - {SIGNAL_TYPE_RGB, "VGA"}, - {SIGNAL_TYPE_DISPLAY_PORT, "DP"}, - {SIGNAL_TYPE_DISPLAY_PORT_MST, "MST"}, - {SIGNAL_TYPE_EDP, "eDP"}, - {SIGNAL_TYPE_VIRTUAL, "Virtual"} -}; - -void dc_conn_log(struct dc_context *ctx, - const struct dc_link *link, - uint8_t *hex_data, - int hex_data_count, - enum dc_log_type event, - const char *msg, - ...) +void dc_conn_log_hex_linux(const uint8_t *hex_data, int hex_data_count) { int i; - va_list args; - struct log_entry entry = { 0 }; - enum signal_type signal; - - if (link->local_sink) - signal = link->local_sink->sink_signal; - else - signal = link->connector_signal; - - if (link->type == dc_connection_mst_branch) - signal = SIGNAL_TYPE_DISPLAY_PORT_MST; - - dm_logger_open(ctx->logger, &entry, event); - - for (i = 0; i < NUM_ELEMENTS(signal_type_info_tbl); i++) - if (signal == signal_type_info_tbl[i].type) - break; - - if (i == NUM_ELEMENTS(signal_type_info_tbl)) - goto fail; - - dm_logger_append_heading(&entry); - - dm_logger_append(&entry, "[%s][ConnIdx:%d] ", - signal_type_info_tbl[i].name, - link->link_index); - - va_start(args, msg); - dm_logger_append_va(&entry, msg, args); - - if (entry.buf_offset > 0 && - entry.buf[entry.buf_offset - 1] == '\n') - entry.buf_offset--; if (hex_data) for (i = 0; i < hex_data_count; i++) - dm_logger_append(&entry, "%2.2X ", hex_data[i]); - - dm_logger_append(&entry, "^\n"); - -fail: - dm_logger_close(&entry); - - va_end(args); + DC_LOG_DEBUG("%2.2X ", hex_data[i]); } + diff --git a/drivers/gpu/drm/amd/display/dc/basics/logger.c b/drivers/gpu/drm/amd/display/dc/basics/logger.c deleted file mode 100644 index a3c56cd8b3965aaf2a1e12352f99a80f1e5d0f0b..0000000000000000000000000000000000000000 --- a/drivers/gpu/drm/amd/display/dc/basics/logger.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright 2012-15 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ -#include "dm_services.h" -#include "include/logger_interface.h" -#include "logger.h" - - -#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) - -static const struct dc_log_type_info log_type_info_tbl[] = { - {LOG_ERROR, "Error"}, - {LOG_WARNING, "Warning"}, - {LOG_DEBUG, "Debug"}, - {LOG_DC, "DC_Interface"}, - {LOG_DTN, "DTN"}, - {LOG_SURFACE, "Surface"}, - {LOG_HW_HOTPLUG, "HW_Hotplug"}, - {LOG_HW_LINK_TRAINING, "HW_LKTN"}, - {LOG_HW_SET_MODE, "HW_Mode"}, - {LOG_HW_RESUME_S3, "HW_Resume"}, - {LOG_HW_AUDIO, "HW_Audio"}, - {LOG_HW_HPD_IRQ, "HW_HPDIRQ"}, - {LOG_MST, "MST"}, - {LOG_SCALER, "Scaler"}, - {LOG_BIOS, "BIOS"}, - {LOG_BANDWIDTH_CALCS, "BWCalcs"}, - {LOG_BANDWIDTH_VALIDATION, "BWValidation"}, - {LOG_I2C_AUX, "I2C_AUX"}, - {LOG_SYNC, "Sync"}, - {LOG_BACKLIGHT, "Backlight"}, - {LOG_FEATURE_OVERRIDE, "Override"}, - {LOG_DETECTION_EDID_PARSER, "Edid"}, - {LOG_DETECTION_DP_CAPS, "DP_Caps"}, - {LOG_RESOURCE, "Resource"}, - {LOG_DML, "DML"}, - {LOG_EVENT_MODE_SET, "Mode"}, - {LOG_EVENT_DETECTION, "Detect"}, - {LOG_EVENT_LINK_TRAINING, "LKTN"}, - {LOG_EVENT_LINK_LOSS, "LinkLoss"}, - {LOG_EVENT_UNDERFLOW, "Underflow"}, - {LOG_IF_TRACE, "InterfaceTrace"}, - {LOG_PERF_TRACE, "PerfTrace"}, - {LOG_DISPLAYSTATS, "DisplayStats"} -}; - - -/* ----------- Object init and destruction ----------- */ -static bool construct(struct dc_context *ctx, struct dal_logger *logger, - uint32_t log_mask) -{ - /* malloc buffer and init offsets */ - logger->log_buffer_size = DAL_LOGGER_BUFFER_MAX_SIZE; - logger->log_buffer = kcalloc(logger->log_buffer_size, sizeof(char), - GFP_KERNEL); - if (!logger->log_buffer) - return false; - - /* Initialize both offsets to start of buffer (empty) */ - logger->buffer_read_offset = 0; - logger->buffer_write_offset = 0; - - logger->open_count = 0; - - logger->flags.bits.ENABLE_CONSOLE = 1; - logger->flags.bits.ENABLE_BUFFER = 0; - - logger->ctx = ctx; - - logger->mask = log_mask; - - return true; -} - -static void destruct(struct dal_logger *logger) -{ - if (logger->log_buffer) { - kfree(logger->log_buffer); - logger->log_buffer = NULL; - } -} - -struct dal_logger *dal_logger_create(struct dc_context *ctx, uint32_t log_mask) -{ - /* malloc struct */ - struct dal_logger *logger = kzalloc(sizeof(struct dal_logger), - GFP_KERNEL); - - if (!logger) - return NULL; - if (!construct(ctx, logger, log_mask)) { - kfree(logger); - return NULL; - } - - return logger; -} - -uint32_t dal_logger_destroy(struct dal_logger **logger) -{ - if (logger == NULL || *logger == NULL) - return 1; - destruct(*logger); - kfree(*logger); - *logger = NULL; - - return 0; -} - -/* ------------------------------------------------------------------------ */ -void dm_logger_append_heading(struct log_entry *entry) -{ - int j; - - for (j = 0; j < NUM_ELEMENTS(log_type_info_tbl); j++) { - - const struct dc_log_type_info *info = &log_type_info_tbl[j]; - - if (info->type == entry->type) - dm_logger_append(entry, "[%s]\t", info->name); - } -} - - -/* Print everything unread existing in log_buffer to debug console*/ -void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn) -{ - char *string_start = &logger->log_buffer[logger->buffer_read_offset]; - - if (should_warn) - dm_output_to_console( - "---------------- FLUSHING LOG BUFFER ----------------\n"); - while (logger->buffer_read_offset < logger->buffer_write_offset) { - - if (logger->log_buffer[logger->buffer_read_offset] == '\0') { - dm_output_to_console("%s", string_start); - string_start = logger->log_buffer + logger->buffer_read_offset + 1; - } - logger->buffer_read_offset++; - } - if (should_warn) - dm_output_to_console( - "-------------- END FLUSHING LOG BUFFER --------------\n\n"); -} -/* ------------------------------------------------------------------------ */ - -/* Warning: Be careful that 'msg' is null terminated and the total size is - * less than DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE (256) including '\0' - */ -static bool dal_logger_should_log( - struct dal_logger *logger, - enum dc_log_type log_type) -{ - if (logger->mask & (1 << log_type)) - return true; - - return false; -} - -static void log_to_debug_console(struct log_entry *entry) -{ - struct dal_logger *logger = entry->logger; - - if (logger->flags.bits.ENABLE_CONSOLE == 0) - return; - - if (entry->buf_offset) { - switch (entry->type) { - case LOG_ERROR: - dm_error("%s", entry->buf); - break; - default: - dm_output_to_console("%s", entry->buf); - break; - } - } -} - - -static void log_to_internal_buffer(struct log_entry *entry) -{ - - uint32_t size = entry->buf_offset; - struct dal_logger *logger = entry->logger; - - if (logger->flags.bits.ENABLE_BUFFER == 0) - return; - - if (logger->log_buffer == NULL) - return; - - if (size > 0 && size < logger->log_buffer_size) { - - int buffer_space = logger->log_buffer_size - - logger->buffer_write_offset; - - if (logger->buffer_write_offset == logger->buffer_read_offset) { - /* Buffer is empty, start writing at beginning */ - buffer_space = logger->log_buffer_size; - logger->buffer_write_offset = 0; - logger->buffer_read_offset = 0; - } - - if (buffer_space > size) { - /* No wrap around, copy 'size' bytes - * from 'entry->buf' to 'log_buffer' - */ - memmove(logger->log_buffer + - logger->buffer_write_offset, - entry->buf, size); - logger->buffer_write_offset += size; - - } else { - /* Not enough room remaining, we should flush - * existing logs */ - - /* Flush existing unread logs to console */ - dm_logger_flush_buffer(logger, true); - - /* Start writing to beginning of buffer */ - memmove(logger->log_buffer, entry->buf, size); - logger->buffer_write_offset = size; - logger->buffer_read_offset = 0; - } - - } -} - -static void append_entry( - struct log_entry *entry, - char *buffer, - uint32_t buf_size) -{ - if (!entry->buf || - entry->buf_offset + buf_size > entry->max_buf_bytes - ) { - BREAK_TO_DEBUGGER(); - return; - } - - /* Todo: check if off by 1 byte due to \0 anywhere */ - memmove(entry->buf + entry->buf_offset, buffer, buf_size); - entry->buf_offset += buf_size; -} - - -void dm_logger_write( - struct dal_logger *logger, - enum dc_log_type log_type, - const char *msg, - ...) -{ - if (logger && dal_logger_should_log(logger, log_type)) { - uint32_t size; - va_list args; - char buffer[LOG_MAX_LINE_SIZE]; - struct log_entry entry; - - va_start(args, msg); - - entry.logger = logger; - - entry.buf = buffer; - - entry.buf_offset = 0; - entry.max_buf_bytes = DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char); - - entry.type = log_type; - - dm_logger_append_heading(&entry); - - size = dm_log_to_buffer( - buffer, LOG_MAX_LINE_SIZE - 1, msg, args); - - buffer[entry.buf_offset + size] = '\0'; - entry.buf_offset += size + 1; - - /* --Flush log_entry buffer-- */ - /* print to kernel console */ - log_to_debug_console(&entry); - /* log internally for dsat */ - log_to_internal_buffer(&entry); - - va_end(args); - } -} - -/* Same as dm_logger_write, except without open() and close(), which must - * be done separately. - */ -void dm_logger_append( - struct log_entry *entry, - const char *msg, - ...) -{ - va_list args; - - va_start(args, msg); - dm_logger_append_va(entry, msg, args); - va_end(args); -} - -void dm_logger_append_va( - struct log_entry *entry, - const char *msg, - va_list args) -{ - struct dal_logger *logger; - - if (!entry) { - BREAK_TO_DEBUGGER(); - return; - } - - logger = entry->logger; - - if (logger && logger->open_count > 0 && - dal_logger_should_log(logger, entry->type)) { - - uint32_t size; - char buffer[LOG_MAX_LINE_SIZE]; - - size = dm_log_to_buffer( - buffer, LOG_MAX_LINE_SIZE, msg, args); - - if (size < LOG_MAX_LINE_SIZE - 1) { - append_entry(entry, buffer, size); - } else { - append_entry(entry, "LOG_ERROR, line too long\n", 27); - } - } -} - -void dm_logger_open( - struct dal_logger *logger, - struct log_entry *entry, /* out */ - enum dc_log_type log_type) -{ - if (!entry) { - BREAK_TO_DEBUGGER(); - return; - } - - entry->type = log_type; - entry->logger = logger; - - entry->buf = kzalloc(DAL_LOGGER_BUFFER_MAX_SIZE, - GFP_KERNEL); - - entry->buf_offset = 0; - entry->max_buf_bytes = DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char); - - logger->open_count++; - - dm_logger_append_heading(entry); -} - -void dm_logger_close(struct log_entry *entry) -{ - struct dal_logger *logger = entry->logger; - - if (logger && logger->open_count > 0) { - logger->open_count--; - } else { - BREAK_TO_DEBUGGER(); - goto cleanup; - } - - /* --Flush log_entry buffer-- */ - /* print to kernel console */ - log_to_debug_console(entry); - /* log internally for dsat */ - log_to_internal_buffer(entry); - - /* TODO: Write end heading */ - -cleanup: - if (entry->buf) { - kfree(entry->buf); - entry->buf = NULL; - entry->buf_offset = 0; - entry->max_buf_bytes = 0; - } -} - diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index aeb56e402cccfda8863b3fe177bf84873d1857c0..eab007e1793c290ddb17d42688d4a9ba45eab9e4 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -678,7 +678,7 @@ static enum bp_result bios_parser_get_gpio_pin_info( return BP_RESULT_BADBIOSTABLE; if (sizeof(struct atom_common_table_header) + - sizeof(struct atom_gpio_pin_lut_v2_1) + sizeof(struct atom_gpio_pin_assignment) > le16_to_cpu(header->table_header.structuresize)) return BP_RESULT_BADBIOSTABLE; diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c index bbbcef566c551908d42c0c6fda57083c1bdd455e..770ff89ba7e173c273006f122ba77622cde7559f 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c @@ -55,7 +55,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2( case DCE_VERSION_11_22: *h = dal_cmd_tbl_helper_dce112_get_table2(); return true; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: *h = dal_cmd_tbl_helper_dce112_get_table2(); return true; diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index 95f332ee3e7e6e3858294d485c03c23c1c25f613..416500e51b8dd2f20da95ec9b0a7730363d56f50 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -38,7 +38,7 @@ CFLAGS_dcn_calc_math.o := $(calcs_ccflags) -Wno-tautological-compare BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o -ifdef CONFIG_DRM_AMD_DC_DCN1_0 +ifdef CONFIG_X86 BW_CALCS += dcn_calcs.o dcn_calc_math.o dcn_calc_auto.o endif diff --git a/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h b/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h index fc3f98fb09ead42defe0ffa82b3fc92af18f2375..62435bfc274dafe62a1b45fc2be1c7de47024d1b 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h +++ b/drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h @@ -25,10 +25,9 @@ #ifndef _CALCS_CALCS_LOGGER_H_ #define _CALCS_CALCS_LOGGER_H_ -#define DC_LOGGER \ - logger +#define DC_LOGGER ctx->logger -static void print_bw_calcs_dceip(struct dal_logger *logger, const struct bw_calcs_dceip *dceip) +static void print_bw_calcs_dceip(struct dc_context *ctx, const struct bw_calcs_dceip *dceip) { DC_LOG_BANDWIDTH_CALCS("#####################################################################"); @@ -122,7 +121,7 @@ static void print_bw_calcs_dceip(struct dal_logger *logger, const struct bw_calc } -static void print_bw_calcs_vbios(struct dal_logger *logger, const struct bw_calcs_vbios *vbios) +static void print_bw_calcs_vbios(struct dc_context *ctx, const struct bw_calcs_vbios *vbios) { DC_LOG_BANDWIDTH_CALCS("#####################################################################"); @@ -181,7 +180,7 @@ static void print_bw_calcs_vbios(struct dal_logger *logger, const struct bw_calc } -static void print_bw_calcs_data(struct dal_logger *logger, struct bw_calcs_data *data) +static void print_bw_calcs_data(struct dc_context *ctx, struct bw_calcs_data *data) { int i, j, k; diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c index 2c4e8f0cb2dcdb7fedbf133b8121bcfd55085edf..160d11a15eac7dca953fd71fdac4b84c9445ca98 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c @@ -3010,9 +3010,9 @@ bool bw_calcs(struct dc_context *ctx, struct bw_fixed low_yclk = vbios->low_yclk; if (ctx->dc->debug.bandwidth_calcs_trace) { - print_bw_calcs_dceip(ctx->logger, dceip); - print_bw_calcs_vbios(ctx->logger, vbios); - print_bw_calcs_data(ctx->logger, data); + print_bw_calcs_dceip(ctx, dceip); + print_bw_calcs_vbios(ctx, vbios); + print_bw_calcs_data(ctx, data); } calculate_bandwidth(dceip, vbios, data); diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index e44b8d3d68910f8226fdc0228abf7a50cce3dd1d..080f777d705e7eb7f6f38a258204a74358747fc1 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -250,7 +250,24 @@ static void pipe_ctx_to_e2e_pipe_params ( else if (pipe->bottom_pipe != NULL && pipe->bottom_pipe->plane_state == pipe->plane_state) input->src.is_hsplit = true; - input->src.dcc = pipe->plane_state->dcc.enable; + if (pipe->plane_res.dpp->ctx->dc->debug.optimized_watermark) { + /* + * this method requires us to always re-calculate watermark when dcc change + * between flip. + */ + input->src.dcc = pipe->plane_state->dcc.enable ? 1 : 0; + } else { + /* + * allow us to disable dcc on the fly without re-calculating WM + * + * extra overhead for DCC is quite small. for 1080p WM without + * DCC is only 0.417us lower (urgent goes from 6.979us to 6.562us) + */ + unsigned int bpe; + + input->src.dcc = pipe->plane_res.dpp->ctx->dc->res_pool->hubbub->funcs-> + dcc_support_pixel_format(pipe->plane_state->format, &bpe) ? 1 : 0; + } input->src.dcc_rate = 1; input->src.meta_pitch = pipe->plane_state->dcc.grph.meta_pitch; input->src.source_scan = dm_horz; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 2a785bbf2b8f1de5011ede286cfee2d229556c36..733ac224e7fdc6839438a1089ec93b5d1402dcaf 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -384,6 +384,71 @@ void dc_stream_set_static_screen_events(struct dc *dc, dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, events); } +void dc_link_set_drive_settings(struct dc *dc, + struct link_training_settings *lt_settings, + const struct dc_link *link) +{ + + int i; + + for (i = 0; i < dc->link_count; i++) { + if (dc->links[i] == link) + break; + } + + if (i >= dc->link_count) + ASSERT_CRITICAL(false); + + dc_link_dp_set_drive_settings(dc->links[i], lt_settings); +} + +void dc_link_perform_link_training(struct dc *dc, + struct dc_link_settings *link_setting, + bool skip_video_pattern) +{ + int i; + + for (i = 0; i < dc->link_count; i++) + dc_link_dp_perform_link_training( + dc->links[i], + link_setting, + skip_video_pattern); +} + +void dc_link_set_preferred_link_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link) +{ + link->preferred_link_setting = *link_setting; + dp_retrain_link_dp_test(link, link_setting, false); +} + +void dc_link_enable_hpd(const struct dc_link *link) +{ + dc_link_dp_enable_hpd(link); +} + +void dc_link_disable_hpd(const struct dc_link *link) +{ + dc_link_dp_disable_hpd(link); +} + + +void dc_link_set_test_pattern(struct dc_link *link, + enum dp_test_pattern test_pattern, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size) +{ + if (link != NULL) + dc_link_dp_set_test_pattern( + link, + test_pattern, + p_link_settings, + p_custom_pattern, + cust_pattern_size); +} + static void destruct(struct dc *dc) { dc_release_state(dc->current_state); @@ -402,9 +467,6 @@ static void destruct(struct dc *dc) if (dc->ctx->created_bios) dal_bios_parser_destroy(&dc->ctx->dc_bios); - if (dc->ctx->logger) - dal_logger_destroy(&dc->ctx->logger); - kfree(dc->ctx); dc->ctx = NULL; @@ -414,7 +476,7 @@ static void destruct(struct dc *dc) kfree(dc->bw_dceip); dc->bw_dceip = NULL; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 kfree(dc->dcn_soc); dc->dcn_soc = NULL; @@ -427,11 +489,10 @@ static void destruct(struct dc *dc) static bool construct(struct dc *dc, const struct dc_init_data *init_params) { - struct dal_logger *logger; struct dc_context *dc_ctx; struct bw_calcs_dceip *dc_dceip; struct bw_calcs_vbios *dc_vbios; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 struct dcn_soc_bounding_box *dcn_soc; struct dcn_ip_params *dcn_ip; #endif @@ -453,7 +514,7 @@ static bool construct(struct dc *dc, } dc->bw_vbios = dc_vbios; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL); if (!dcn_soc) { dm_error("%s: failed to create dcn_soc\n", __func__); @@ -492,14 +553,7 @@ static bool construct(struct dc *dc, } /* Create logger */ - logger = dal_logger_create(dc_ctx, init_params->log_mask); - if (!logger) { - /* can *not* call logger. call base driver 'print error' */ - dm_error("%s: failed to create Logger!\n", __func__); - goto fail; - } - dc_ctx->logger = logger; dc_ctx->dce_environment = init_params->dce_environment; dc_version = resource_parse_asic_id(init_params->asic_id); @@ -918,9 +972,7 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) for (i = 0; i < context->stream_count; i++) { struct dc_stream_state *stream = context->streams[i]; - dc_stream_log(stream, - dc->ctx->logger, - LOG_DC); + dc_stream_log(dc, stream); } result = dc_commit_state_no_check(dc, context); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index e1ebdf7b5eaf3080882e5c3ea99de0278d9acdb0..caece7c13bc642114d06779b12e613cdc1c6b8d7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -348,7 +348,7 @@ void context_clock_trace( struct dc *dc, struct dc_state *context) { -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 DC_LOGGER_INIT(dc->ctx->logger); CLOCK_TRACE("Current: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n", 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 fa56c0fc02bf512ccc67ba15413c8521d6ad41b9..a4429c90c60c4ac8a6ca2e952bd0821c915891f1 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -313,7 +313,7 @@ static enum signal_type get_basic_signal_type( * @brief * Check whether there is a dongle on DP connector */ -static bool is_dp_sink_present(struct dc_link *link) +bool dc_link_is_dp_sink_present(struct dc_link *link) { enum gpio_result gpio_result; uint32_t clock_pin = 0; @@ -406,7 +406,7 @@ static enum signal_type link_detect_sink( * we assume signal is DVI; it could be corrected * to HDMI after dongle detection */ - if (!is_dp_sink_present(link)) + if (!dm_helpers_is_dp_sink_present(link)) result = SIGNAL_TYPE_DVI_SINGLE_LINK; } } @@ -498,6 +498,10 @@ static bool detect_dp( sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST; link->type = dc_connection_mst_branch; + dal_ddc_service_set_transaction_type( + link->ddc, + sink_caps->transaction_type); + /* * This call will initiate MST topology discovery. Which * will detect MST ports and add new DRM connector DRM @@ -525,6 +529,10 @@ static bool detect_dp( if (reason == DETECT_REASON_BOOT) boot = true; + dm_helpers_dp_update_branch_info( + link->ctx, + link); + if (!dm_helpers_dp_mst_start_top_mgr( link->ctx, link, boot)) { diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index ae48d603ebd6ca73c289c71f50795f5d3bd6f65e..08c9d73b9ab727776f337540ed32b388d5e700a4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -33,6 +33,10 @@ #include "include/vector.h" #include "core_types.h" #include "dc_link_ddc.h" +#include "i2caux/engine.h" +#include "i2caux/i2c_engine.h" +#include "i2caux/aux_engine.h" +#include "i2caux/i2caux.h" #define AUX_POWER_UP_WA_DELAY 500 #define I2C_OVER_AUX_DEFER_WA_DELAY 70 @@ -629,83 +633,62 @@ bool dal_ddc_service_query_ddc_data( return ret; } -enum ddc_result dal_ddc_service_read_dpcd_data( - struct ddc_service *ddc, - bool i2c, - enum i2c_mot_mode mot, - uint32_t address, - uint8_t *data, - uint32_t len, - uint32_t *read) +int dc_link_aux_transfer(struct ddc_service *ddc, + unsigned int address, + uint8_t *reply, + void *buffer, + unsigned int size, + enum aux_transaction_type type, + enum i2caux_transaction_action action) { - struct aux_payload read_payload = { - .i2c_over_aux = i2c, - .write = false, - .address = address, - .length = len, - .data = data, - }; - struct aux_command command = { - .payloads = &read_payload, - .number_of_payloads = 1, - .defer_delay = 0, - .max_defer_write_retry = 0, - .mot = mot - }; - - *read = 0; - - if (len > DEFAULT_AUX_MAX_DATA_SIZE) { - BREAK_TO_DEBUGGER(); - return DDC_RESULT_FAILED_INVALID_OPERATION; - } + struct i2caux *i2caux = ddc->ctx->i2caux; + struct ddc *ddc_pin = ddc->ddc_pin; + struct aux_engine *engine; + enum aux_channel_operation_result operation_result; + struct aux_request_transaction_data aux_req; + struct aux_reply_transaction_data aux_rep; + uint8_t returned_bytes = 0; + int res = -1; + uint32_t status; - if (dal_i2caux_submit_aux_command( - ddc->ctx->i2caux, - ddc->ddc_pin, - &command)) { - *read = command.payloads->length; - return DDC_RESULT_SUCESSFULL; - } + memset(&aux_req, 0, sizeof(aux_req)); + memset(&aux_rep, 0, sizeof(aux_rep)); - return DDC_RESULT_FAILED_OPERATION; -} + engine = i2caux->funcs->acquire_aux_engine(i2caux, ddc_pin); -enum ddc_result dal_ddc_service_write_dpcd_data( - struct ddc_service *ddc, - bool i2c, - enum i2c_mot_mode mot, - uint32_t address, - const uint8_t *data, - uint32_t len) -{ - struct aux_payload write_payload = { - .i2c_over_aux = i2c, - .write = true, - .address = address, - .length = len, - .data = (uint8_t *)data, - }; - struct aux_command command = { - .payloads = &write_payload, - .number_of_payloads = 1, - .defer_delay = 0, - .max_defer_write_retry = 0, - .mot = mot - }; - - if (len > DEFAULT_AUX_MAX_DATA_SIZE) { - BREAK_TO_DEBUGGER(); - return DDC_RESULT_FAILED_INVALID_OPERATION; - } + aux_req.type = type; + aux_req.action = action; + + aux_req.address = address; + aux_req.delay = 0; + aux_req.length = size; + aux_req.data = buffer; - if (dal_i2caux_submit_aux_command( - ddc->ctx->i2caux, - ddc->ddc_pin, - &command)) - return DDC_RESULT_SUCESSFULL; + engine->funcs->submit_channel_request(engine, &aux_req); + operation_result = engine->funcs->get_channel_status(engine, &returned_bytes); + + switch (operation_result) { + case AUX_CHANNEL_OPERATION_SUCCEEDED: + res = returned_bytes; + + if (res <= size && res >= 0) + res = engine->funcs->read_channel_reply(engine, size, + buffer, reply, + &status); + + break; + case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: + res = 0; + break; + case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN: + case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY: + case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT: + res = -1; + break; + } - return DDC_RESULT_FAILED_OPERATION; + i2caux->funcs->release_engine(i2caux, &engine->base); + return res; } /*test only function*/ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 84586b679d73ee17b1da80e9a859ed3465cb2ff6..474cd3e0175210777664d44ea9a754334809eb1a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -39,7 +39,7 @@ static bool decide_fallback_link_setting( struct dc_link_settings initial_link_settings, struct dc_link_settings *current_link_setting, enum link_training_result training_result); -static struct dc_link_settings get_common_supported_link_settings ( +static struct dc_link_settings get_common_supported_link_settings( struct dc_link_settings link_setting_a, struct dc_link_settings link_setting_b); @@ -94,8 +94,8 @@ static void dpcd_set_link_settings( uint8_t rate = (uint8_t) (lt_settings->link_settings.link_rate); - union down_spread_ctrl downspread = {{0}}; - union lane_count_set lane_count_set = {{0}}; + union down_spread_ctrl downspread = { {0} }; + union lane_count_set lane_count_set = { {0} }; uint8_t link_set_buffer[2]; downspread.raw = (uint8_t) @@ -165,11 +165,11 @@ static void dpcd_set_lt_pattern_and_lane_settings( const struct link_training_settings *lt_settings, enum hw_dp_training_pattern pattern) { - union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}}; + union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = { { {0} } }; const uint32_t dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET; uint8_t dpcd_lt_buffer[5] = {0}; - union dpcd_training_pattern dpcd_pattern = {{0}}; + union dpcd_training_pattern dpcd_pattern = { {0} }; uint32_t lane; uint32_t size_in_bytes; bool edp_workaround = false; /* TODO link_prop.INTERNAL */ @@ -233,7 +233,7 @@ static void dpcd_set_lt_pattern_and_lane_settings( link, DP_TRAINING_PATTERN_SET, &dpcd_pattern.raw, - sizeof(dpcd_pattern.raw) ); + sizeof(dpcd_pattern.raw)); core_link_write_dpcd( link, @@ -247,7 +247,7 @@ static void dpcd_set_lt_pattern_and_lane_settings( link, dpcd_base_lt_offset, dpcd_lt_buffer, - size_in_bytes + sizeof(dpcd_pattern.raw) ); + size_in_bytes + sizeof(dpcd_pattern.raw)); link->cur_lane_setting = lt_settings->lane_settings[0]; } @@ -429,8 +429,8 @@ static void get_lane_status_and_drive_settings( struct link_training_settings *req_settings) { uint8_t dpcd_buf[6] = {0}; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {{{0}}}; - struct link_training_settings request_settings = {{0}}; + union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } }; + struct link_training_settings request_settings = { {0} }; uint32_t lane; memset(req_settings, '\0', sizeof(struct link_training_settings)); @@ -652,7 +652,7 @@ static bool perform_post_lt_adj_req_sequence( if (req_drv_setting_changed) { update_drive_settings( - lt_settings,req_settings); + lt_settings, req_settings); dc_link_dp_set_drive_settings(link, lt_settings); @@ -725,8 +725,8 @@ static enum link_training_result perform_channel_equalization_sequence( enum hw_dp_training_pattern hw_tr_pattern; uint32_t retries_ch_eq; enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; - union lane_align_status_updated dpcd_lane_status_updated = {{0}}; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}}; + union lane_align_status_updated dpcd_lane_status_updated = { {0} }; + union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } }; hw_tr_pattern = get_supported_tp(link); @@ -1028,6 +1028,9 @@ enum link_training_result dc_link_dp_perform_link_training( lt_settings.lane_settings[0].VOLTAGE_SWING, lt_settings.lane_settings[0].PRE_EMPHASIS); + if (status != LINK_TRAINING_SUCCESS) + link->ctx->dc->debug.debug_data.ltFailCount++; + return status; } @@ -1183,7 +1186,7 @@ bool dp_hbr_verify_link_cap( return success; } -static struct dc_link_settings get_common_supported_link_settings ( +static struct dc_link_settings get_common_supported_link_settings( struct dc_link_settings link_setting_a, struct dc_link_settings link_setting_b) { @@ -1429,6 +1432,7 @@ static uint32_t bandwidth_in_kbps_from_link_settings( uint32_t lane_count = link_setting->lane_count; uint32_t kbps = link_rate_in_kbps; + kbps *= lane_count; kbps *= 8; /* 8 bits per byte*/ @@ -1446,9 +1450,9 @@ bool dp_validate_mode_timing( const struct dc_link_settings *link_setting; /*always DP fail safe mode*/ - if (timing->pix_clk_khz == (uint32_t)25175 && - timing->h_addressable == (uint32_t)640 && - timing->v_addressable == (uint32_t)480) + if (timing->pix_clk_khz == (uint32_t) 25175 && + timing->h_addressable == (uint32_t) 640 && + timing->v_addressable == (uint32_t) 480) return true; /* We always use verified link settings */ @@ -1996,12 +2000,16 @@ static void handle_automated_test(struct dc_link *link) sizeof(test_response)); } -bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data) +bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss) { - union hpd_irq_data hpd_irq_dpcd_data = {{{{0}}}}; + union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } }; union device_service_irq device_service_clear = { { 0 } }; enum dc_status result; + bool status = false; + + if (out_link_loss) + *out_link_loss = false; /* For use cases related to down stream connection status change, * PSR and device auto test, refer to function handle_sst_hpd_irq * in DAL2.1*/ @@ -2076,6 +2084,8 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd true, LINK_TRAINING_ATTEMPTS); status = false; + if (out_link_loss) + *out_link_loss = true; } if (link->type == dc_connection_active_dongle && @@ -2262,6 +2272,11 @@ static void get_active_converter_info( link->dpcd_caps.branch_hw_revision = dp_hw_fw_revision.ieee_hw_rev; + + memmove( + link->dpcd_caps.branch_fw_revision, + dp_hw_fw_revision.ieee_fw_rev, + sizeof(dp_hw_fw_revision.ieee_fw_rev)); } } @@ -2317,6 +2332,7 @@ static bool retrieve_link_cap(struct dc_link *link) enum dc_status status = DC_ERROR_UNEXPECTED; uint32_t read_dpcd_retry_cnt = 3; int i; + struct dp_sink_hw_fw_revision dp_hw_fw_revision; memset(dpcd_data, '\0', sizeof(dpcd_data)); memset(&down_strm_port_count, @@ -2408,6 +2424,25 @@ static bool retrieve_link_cap(struct dc_link *link) (sink_id.ieee_oui[1] << 8) + (sink_id.ieee_oui[2]); + memmove( + link->dpcd_caps.sink_dev_id_str, + sink_id.ieee_device_id, + sizeof(sink_id.ieee_device_id)); + + core_link_read_dpcd( + link, + DP_SINK_HW_REVISION_START, + (uint8_t *)&dp_hw_fw_revision, + sizeof(dp_hw_fw_revision)); + + link->dpcd_caps.sink_hw_revision = + dp_hw_fw_revision.ieee_hw_rev; + + memmove( + link->dpcd_caps.sink_fw_revision, + dp_hw_fw_revision.ieee_fw_rev, + sizeof(dp_hw_fw_revision.ieee_fw_rev)); + /* Connectivity log: detection */ CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: "); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index c5fc5250e2bfc43980bda04c7078721e814f14dc..2e65715f76a1ce0ad95f89a7fe47ba672320add3 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -41,7 +41,7 @@ #include "dce100/dce100_resource.h" #include "dce110/dce110_resource.h" #include "dce112/dce112_resource.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "dcn10/dcn10_resource.h" #endif #include "dce120/dce120_resource.h" @@ -85,7 +85,7 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) case FAMILY_AI: dc_version = DCE_VERSION_12_0; break; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case FAMILY_RV: dc_version = DCN_VERSION_1_0; break; @@ -136,7 +136,7 @@ struct resource_pool *dc_create_resource_pool( num_virtual_links, dc); break; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: res_pool = dcn10_create_resource_pool( num_virtual_links, dc); @@ -1213,7 +1213,7 @@ static struct pipe_ctx *acquire_free_pipe_for_stream( } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 static int acquire_first_split_pipe( struct resource_context *res_ctx, const struct resource_pool *pool, @@ -1284,7 +1284,7 @@ bool dc_add_plane_to_context( free_pipe = acquire_free_pipe_for_stream(context, pool, stream); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (!free_pipe) { int pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); if (pipe_idx >= 0) @@ -1705,8 +1705,8 @@ enum dc_status dc_add_stream_to_ctx( struct dc_context *dc_ctx = dc->ctx; enum dc_status res; - if (new_ctx->stream_count >= dc->res_pool->pipe_count) { - DC_ERROR("Max streams reached, can add stream %p !\n", stream); + if (new_ctx->stream_count >= dc->res_pool->timing_generator_count) { + DC_ERROR("Max streams reached, can't add stream %p !\n", stream); return DC_ERROR_UNEXPECTED; } @@ -1882,7 +1882,7 @@ enum dc_status resource_map_pool_resources( /* acquire new resources */ pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 if (pipe_idx < 0) pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); #endif diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 3732a1de9d6c2852f862dc14bbf1571ab7db2055..fdcc8ab19bf3f3eb979ab643f7b1d217551f6900 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -30,6 +30,8 @@ #include "ipp.h" #include "timing_generator.h" +#define DC_LOGGER dc->ctx->logger + /******************************************************************************* * Private functions ******************************************************************************/ @@ -212,6 +214,8 @@ bool dc_stream_set_cursor_attributes( } core_dc->hwss.set_cursor_attribute(pipe_ctx); + if (core_dc->hwss.set_cursor_sdr_white_level) + core_dc->hwss.set_cursor_sdr_white_level(pipe_ctx); } if (pipe_to_program) @@ -317,16 +321,10 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, return ret; } - -void dc_stream_log( - const struct dc_stream_state *stream, - struct dal_logger *dm_logger, - enum dc_log_type log_type) +void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream) { - - dm_logger_write(dm_logger, - log_type, - "core_stream 0x%x: src: %d, %d, %d, %d; dst: %d, %d, %d, %d, colorSpace:%d\n", + DC_LOG_DC( + "core_stream 0x%p: src: %d, %d, %d, %d; dst: %d, %d, %d, %d, colorSpace:%d\n", stream, stream->src.x, stream->src.y, @@ -337,21 +335,18 @@ void dc_stream_log( stream->dst.width, stream->dst.height, stream->output_color_space); - dm_logger_write(dm_logger, - log_type, + DC_LOG_DC( "\tpix_clk_khz: %d, h_total: %d, v_total: %d, pixelencoder:%d, displaycolorDepth:%d\n", stream->timing.pix_clk_khz, stream->timing.h_total, stream->timing.v_total, stream->timing.pixel_encoding, stream->timing.display_color_depth); - dm_logger_write(dm_logger, - log_type, + DC_LOG_DC( "\tsink name: %s, serial: %d\n", stream->sink->edid_caps.display_name, stream->sink->edid_caps.serial_number); - dm_logger_write(dm_logger, - log_type, + DC_LOG_DC( "\tlink: %d\n", stream->sink->link->link_index); } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 0cb7e10d2505bb3e5aec77a52baf5740f67f8477..ceb4c37258936271ce662e7a675d5024b424ffcd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.52" +#define DC_VER "3.1.56" #define MAX_SURFACES 3 #define MAX_STREAMS 6 @@ -169,6 +169,12 @@ struct dc_config { bool disable_disp_pll_sharing; }; +enum visual_confirm { + VISUAL_CONFIRM_DISABLE = 0, + VISUAL_CONFIRM_SURFACE = 1, + VISUAL_CONFIRM_HDR = 2, +}; + enum dcc_option { DCC_ENABLE = 0, DCC_DISABLE = 1, @@ -202,7 +208,7 @@ struct dc_clocks { }; struct dc_debug { - bool surface_visual_confirm; + enum visual_confirm visual_confirm; bool sanity_checks; bool max_disp_clk; bool surface_trace; @@ -249,7 +255,15 @@ struct dc_debug { bool always_use_regamma; bool p010_mpo_support; bool recovery_enabled; + bool avoid_vbios_exec_table; + bool scl_reset_length10; + bool hdmi20_disable; + struct { + uint32_t ltFailCount; + uint32_t i2cErrorCount; + uint32_t auxErrorCount; + } debug_data; }; struct dc_state; struct resource_pool; @@ -275,7 +289,7 @@ struct dc { /* Inputs into BW and WM calculations. */ struct bw_calcs_dceip *bw_dceip; struct bw_calcs_vbios *bw_vbios; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 struct dcn_soc_bounding_box *dcn_soc; struct dcn_ip_params *dcn_ip; struct display_mode_lib dml; @@ -384,7 +398,8 @@ enum dc_transfer_func_predefined { TRANSFER_FUNCTION_LINEAR, TRANSFER_FUNCTION_UNITY, TRANSFER_FUNCTION_HLG, - TRANSFER_FUNCTION_HLG12 + TRANSFER_FUNCTION_HLG12, + TRANSFER_FUNCTION_GAMMA22 }; struct dc_transfer_func { @@ -627,9 +642,14 @@ struct dpcd_caps { struct dc_dongle_caps dongle_caps; uint32_t sink_dev_id; + int8_t sink_dev_id_str[6]; + int8_t sink_hw_revision; + int8_t sink_fw_revision[2]; + uint32_t branch_dev_id; int8_t branch_dev_name[6]; int8_t branch_hw_revision; + int8_t branch_fw_revision[2]; bool allow_invalid_MSA_timing_param; bool panel_mode_edp; diff --git a/drivers/gpu/drm/amd/display/dc/dc_helper.c b/drivers/gpu/drm/amd/display/dc/dc_helper.c index bd0fda0ceb919d3d159db4af83409404e8ef873b..e68077e655658b374cdede4c2338ee60d2d5abb5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dc_helper.c @@ -255,3 +255,54 @@ uint32_t generic_reg_wait(const struct dc_context *ctx, return reg_val; } + +void generic_write_indirect_reg(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index, uint32_t data) +{ + dm_write_reg(ctx, addr_index, index); + dm_write_reg(ctx, addr_data, data); +} + +uint32_t generic_read_indirect_reg(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index) +{ + uint32_t value = 0; + + dm_write_reg(ctx, addr_index, index); + value = dm_read_reg(ctx, addr_data); + + return value; +} + + +uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index, uint32_t reg_val, int n, + uint8_t shift1, uint32_t mask1, uint32_t field_value1, + ...) +{ + uint32_t shift, mask, field_value; + int i = 1; + + va_list ap; + + va_start(ap, field_value1); + + reg_val = set_reg_field_value_ex(reg_val, field_value1, mask1, shift1); + + while (i < n) { + shift = va_arg(ap, uint32_t); + mask = va_arg(ap, uint32_t); + field_value = va_arg(ap, uint32_t); + + reg_val = set_reg_field_value_ex(reg_val, field_value, mask, shift); + i++; + } + + generic_write_indirect_reg(ctx, addr_index, addr_data, index, reg_val); + va_end(ap); + + return reg_val; +} 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 14afbc5c0a62191ffc571e8ddd7fa7ad9e6b0e55..9cfd7ea845e3ffe31840f06cfaeea056fcc1940d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -404,9 +404,11 @@ struct dc_cursor_position { struct dc_cursor_mi_param { unsigned int pixel_clk_khz; unsigned int ref_clk_khz; - unsigned int viewport_x_start; - unsigned int viewport_width; + struct rect viewport; struct fixed31_32 h_scale_ratio; + struct fixed31_32 v_scale_ratio; + enum dc_rotation_angle rotation; + bool mirror; }; /* IPP related types */ @@ -490,6 +492,7 @@ struct dc_cursor_attributes { uint32_t height; enum dc_cursor_color_format color_format; + uint32_t sdr_white_level; // for boosting (SDR) cursor in HDR mode /* In case we support HW Cursor rotation in the future */ enum dc_rotation_angle rotation_angle; @@ -497,6 +500,11 @@ struct dc_cursor_attributes { union dc_cursor_attribute_flags attribute_flags; }; +struct dpp_cursor_attributes { + int bias; + int scale; +}; + /* OPP */ enum dc_color_space { diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 8a716baa1203bdcd7b85f912aa6a22d523f57a5e..070a56926308ac4d314792a39fb3642371301e82 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -172,7 +172,7 @@ bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason); * false - no change in Downstream port status. No further action required * from DM. */ bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link, - union hpd_irq_data *hpd_irq_dpcd_data); + union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss); struct dc_sink_init_data; @@ -210,10 +210,29 @@ bool dc_link_dp_set_test_pattern( void dc_link_enable_hpd_filter(struct dc_link *link, bool enable); +bool dc_link_is_dp_sink_present(struct dc_link *link); + /* * DPCD access interfaces */ +void dc_link_set_drive_settings(struct dc *dc, + struct link_training_settings *lt_settings, + const struct dc_link *link); +void dc_link_perform_link_training(struct dc *dc, + struct dc_link_settings *link_setting, + bool skip_video_pattern); +void dc_link_set_preferred_link_settings(struct dc *dc, + struct dc_link_settings *link_setting, + struct dc_link *link); +void dc_link_enable_hpd(const struct dc_link *link); +void dc_link_disable_hpd(const struct dc_link *link); +void dc_link_set_test_pattern(struct dc_link *link, + enum dp_test_pattern test_pattern, + const struct link_training_settings *p_link_settings, + const unsigned char *p_custom_pattern, + unsigned int cust_pattern_size); + bool dc_submit_i2c( struct dc *dc, uint32_t link_index, diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index af503e0286a752e9b953a3981aac083baa70b54c..cbfe418006cbade10cbfc58313fcfee45d1482f6 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -100,6 +100,7 @@ struct dc_stream_state { struct dc_cursor_attributes cursor_attributes; struct dc_cursor_position cursor_position; + uint32_t sdr_white_level; // for boosting (SDR) cursor in HDR mode /* from stream struct */ struct kref refcount; @@ -147,10 +148,7 @@ void dc_commit_updates_for_stream(struct dc *dc, /* * Log the current stream state. */ -void dc_stream_log( - const struct dc_stream_state *stream, - struct dal_logger *dc_logger, - enum dc_log_type log_type); +void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream); uint8_t dc_get_current_stream_count(struct dc *dc); struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i); @@ -258,6 +256,7 @@ bool dc_stream_set_cursor_position( struct dc_stream_state *stream, const struct dc_cursor_position *position); + bool dc_stream_adjust_vmin_vmax(struct dc *dc, struct dc_stream_state **stream, int num_streams, diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index c96e526d07bb6c23f720d839ba4b0648ef3bb00c..8c6eb78b0c3bd8df91dce93bdb899cfad8d97ba5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -77,8 +77,6 @@ struct dc_context { struct dc *dc; void *driver_context; /* e.g. amdgpu_device */ - - struct dal_logger *logger; void *cgs_device; enum dce_environment dce_environment; @@ -194,6 +192,7 @@ union display_content_support { struct dc_panel_patch { unsigned int dppowerup_delay; + unsigned int extra_t12_ms; }; struct dc_edid_caps { 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 ca137757a69e106e128b4d97c6c2dd99a940ae9a..439dcf3b596ccdec9447656796499b7848673848 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 @@ -592,7 +592,7 @@ static uint32_t dce110_get_pix_clk_dividers( case DCE_VERSION_11_2: case DCE_VERSION_11_22: case DCE_VERSION_12_0: -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: #endif @@ -909,7 +909,7 @@ static bool dce110_program_pix_clk( struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); struct bp_pixel_clock_parameters bp_pc_params = {0}; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) { unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0; unsigned dp_dto_ref_kHz = 700000; @@ -982,7 +982,7 @@ static bool dce110_program_pix_clk( case DCE_VERSION_11_2: case DCE_VERSION_11_22: case DCE_VERSION_12_0: -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: #endif diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h index c45e2f76189e7be44dc5178f3b1d25aec9c23f3a..801bb65707b3204ed1055d583926b055658a7179 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h @@ -55,7 +55,7 @@ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, mask_sh) -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #define CS_COMMON_REG_LIST_DCN1_0(index, pllid) \ SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index 6882dc953a2c23a18b56ff00ef6d562486482989..8f8a2abac3f301f894b9070aa93901c9403ff24e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -30,7 +30,7 @@ #include "bios_parser_interface.h" #include "dc.h" #include "dmcu.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "dcn_calcs.h" #endif #include "core_types.h" @@ -478,7 +478,7 @@ static void dce12_update_clocks(struct dccg *dccg, } } -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 static int dcn1_determine_dppclk_threshold(struct dccg *dccg, struct dc_clocks *new_clocks) { bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; @@ -666,7 +666,7 @@ static void dce_update_clocks(struct dccg *dccg, } } -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 static const struct display_clock_funcs dcn1_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .set_dispclk = dce112_set_clock, @@ -821,7 +821,7 @@ struct dccg *dce120_dccg_create(struct dc_context *ctx) return &clk_dce->base; } -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 struct dccg *dcn1_dccg_create(struct dc_context *ctx) { struct dc_debug *debug = &ctx->dc->debug; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h index 7ce0a54e548f47151dfe0920c8fb795cf7b70a90..e5e44adc6c27cda88930ab020c04ee6e0458e803 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h @@ -44,18 +44,14 @@ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, mask_sh) #define CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh) \ - CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ - CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh),\ - CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh) + CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) #define CLK_REG_FIELD_LIST(type) \ type DPREFCLK_SRC_SEL; \ type DENTIST_DPREFCLK_WDIVIDER; \ type DENTIST_DISPCLK_WDIVIDER; \ - type DENTIST_DPPCLK_WDIVIDER; \ - type DENTIST_DISPCLK_CHG_DONE; \ - type DENTIST_DPPCLK_CHG_DONE; + type DENTIST_DISPCLK_CHG_DONE; struct dccg_shift { CLK_REG_FIELD_LIST(uint8_t) @@ -115,7 +111,7 @@ struct dccg *dce112_dccg_create( struct dccg *dce120_dccg_create(struct dc_context *ctx); -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 struct dccg *dcn1_dccg_create(struct dc_context *ctx); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index a576b8bbb3cd4c1da1e0c3adec0bb53f47a3e1b5..062a46543887ac150247295b0ceff1403aae159f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -314,7 +314,7 @@ static void dce_get_psr_wait_loop( return; } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 static void dcn10_get_dmcu_state(struct dmcu *dmcu) { struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); @@ -735,7 +735,7 @@ static const struct dmcu_funcs dce_funcs = { .is_dmcu_initialized = dce_is_dmcu_initialized }; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 static const struct dmcu_funcs dcn10_funcs = { .dmcu_init = dcn10_dmcu_init, .load_iram = dcn10_dmcu_load_iram, @@ -787,7 +787,7 @@ struct dmcu *dce_dmcu_create( return &dmcu_dce->base; } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 struct dmcu *dcn10_dmcu_create( struct dc_context *ctx, const struct dce_dmcu_registers *regs, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 057407892618463a999082ca2bde82b8ab69520d..64dc75378541539028b7333f22d00329240a3166 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -147,6 +147,7 @@ SR(DCCG_GATE_DISABLE_CNTL2), \ SR(DCFCLK_CNTL),\ SR(DCFCLK_CNTL), \ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ /* todo: get these from GVM instead of reading registers ourselves */\ MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\ MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\ @@ -275,6 +276,8 @@ struct dce_hwseq_registers { uint32_t MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB; uint32_t MC_VM_SYSTEM_APERTURE_LOW_ADDR; uint32_t MC_VM_SYSTEM_APERTURE_HIGH_ADDR; + uint32_t AZALIA_AUDIO_DTO; + uint32_t AZALIA_CONTROLLER_CLOCK_GATING; }; /* set field name */ #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ @@ -361,7 +364,8 @@ struct dce_hwseq_registers { HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh), \ HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ - HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh) + HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh), \ + HWS_SF(, DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh) #define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\ HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ @@ -500,7 +504,8 @@ struct dce_hwseq_registers { type D1VGA_MODE_ENABLE; \ type D2VGA_MODE_ENABLE; \ type D3VGA_MODE_ENABLE; \ - type D4VGA_MODE_ENABLE; + type D4VGA_MODE_ENABLE; \ + type AZALIA_AUDIO_DTO_MODULE; struct dce_hwseq_shift { HWSEQ_REG_FIELD_LIST(uint8_t) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index dbe3b26b6d9eb6134bf34f184827a19841d28cbd..60e3c6a73d370c7ecbad78ee664beb3d9d19833a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -646,6 +646,9 @@ static bool dce110_link_encoder_validate_hdmi_output( if (!enc110->base.features.flags.bits.HDMI_6GB_EN && adjusted_pix_clk_khz >= 300000) return false; + if (enc110->base.ctx->dc->debug.hdmi20_disable && + crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + return false; return true; } @@ -773,6 +776,9 @@ void dce110_link_encoder_construct( __func__, result); } + if (enc110->base.ctx->dc->debug.hdmi20_disable) { + enc110->base.features.flags.bits.HDMI_6GB_EN = 0; + } } bool dce110_link_encoder_validate_output_with_stream( diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index b235a75355b855e03cfd679126e72a9e30dd7d00..85686d9176364e0373248c4808eb631b5169173a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c @@ -729,7 +729,7 @@ static bool dce_mi_program_surface_flip_and_addr( return true; } -static struct mem_input_funcs dce_mi_funcs = { +static const struct mem_input_funcs dce_mi_funcs = { .mem_input_program_display_marks = dce_mi_program_display_marks, .allocate_mem_input = dce_mi_allocate_dmif, .free_mem_input = dce_mi_free_dmif, @@ -741,6 +741,29 @@ static struct mem_input_funcs dce_mi_funcs = { .mem_input_is_flip_pending = dce_mi_is_flip_pending }; +static const struct mem_input_funcs dce112_mi_funcs = { + .mem_input_program_display_marks = dce112_mi_program_display_marks, + .allocate_mem_input = dce_mi_allocate_dmif, + .free_mem_input = dce_mi_free_dmif, + .mem_input_program_surface_flip_and_addr = + dce_mi_program_surface_flip_and_addr, + .mem_input_program_pte_vm = dce_mi_program_pte_vm, + .mem_input_program_surface_config = + dce_mi_program_surface_config, + .mem_input_is_flip_pending = dce_mi_is_flip_pending +}; + +static const struct mem_input_funcs dce120_mi_funcs = { + .mem_input_program_display_marks = dce120_mi_program_display_marks, + .allocate_mem_input = dce_mi_allocate_dmif, + .free_mem_input = dce_mi_free_dmif, + .mem_input_program_surface_flip_and_addr = + dce_mi_program_surface_flip_and_addr, + .mem_input_program_pte_vm = dce_mi_program_pte_vm, + .mem_input_program_surface_config = + dce_mi_program_surface_config, + .mem_input_is_flip_pending = dce_mi_is_flip_pending +}; void dce_mem_input_construct( struct dce_mem_input *dce_mi, @@ -769,7 +792,7 @@ void dce112_mem_input_construct( const struct dce_mem_input_mask *mi_mask) { dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); - dce_mi->base.funcs->mem_input_program_display_marks = dce112_mi_program_display_marks; + dce_mi->base.funcs = &dce112_mi_funcs; } void dce120_mem_input_construct( @@ -781,5 +804,5 @@ void dce120_mem_input_construct( const struct dce_mem_input_mask *mi_mask) { dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); - dce_mi->base.funcs->mem_input_program_display_marks = dce120_mi_program_display_marks; + dce_mi->base.funcs = &dce120_mi_funcs; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 91642e6848587b54e2d6f7b33a9ea460c133926a..b139b40178200f41ce4c31e31beb899da0835df8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -135,7 +135,7 @@ static void dce110_update_generic_info_packet( AFMT_GENERIC0_UPDATE, (packet_index == 0), AFMT_GENERIC2_UPDATE, (packet_index == 2)); } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (REG(AFMT_VBI_PACKET_CONTROL1)) { switch (packet_index) { case 0: @@ -229,7 +229,7 @@ static void dce110_update_hdmi_info_packet( HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case 4: if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, @@ -274,7 +274,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( struct dc_crtc_timing *crtc_timing, enum dc_color_space output_color_space) { -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 uint32_t h_active_start; uint32_t v_active_start; uint32_t misc0 = 0; @@ -317,7 +317,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN) REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (enc110->se_mask->DP_VID_N_MUL) REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1); #endif @@ -328,7 +328,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( break; } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (REG(DP_MSA_MISC)) misc1 = REG_READ(DP_MSA_MISC); #endif @@ -362,7 +362,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( /* set dynamic range and YCbCr range */ -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 switch (crtc_timing->display_color_depth) { case COLOR_DEPTH_666: colorimetry_bpc = 0; @@ -441,7 +441,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( DP_DYN_RANGE, dynamic_range_rgb, DP_YCBCR_RANGE, dynamic_range_ycbcr); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (REG(DP_MSA_COLORIMETRY)) REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0); @@ -476,7 +476,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( crtc_timing->v_front_porch; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 /* start at begining of left border */ if (REG(DP_MSA_TIMING_PARAM2)) REG_SET_2(DP_MSA_TIMING_PARAM2, 0, @@ -751,7 +751,7 @@ static void dce110_stream_encoder_update_hdmi_info_packets( dce110_update_hdmi_info_packet(enc110, 3, &info_frame->hdrsmd); } -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 if (enc110->se_mask->HDMI_DB_DISABLE) { /* for bring up, disable dp double TODO */ if (REG(HDMI_DB_CONTROL)) @@ -789,7 +789,7 @@ static void dce110_stream_encoder_stop_hdmi_info_packets( HDMI_GENERIC1_LINE, 0, HDMI_GENERIC1_SEND, 0); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 /* stop generic packets 2 & 3 on HDMI */ if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c index a02e719d779443be17d5cd85b0da1650a89dc4e4..ab63d0d0304cb1012164edf8017b1d89aad638e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c @@ -155,7 +155,7 @@ static void program_overscan( int overscan_bottom = data->v_active - data->recout.y - data->recout.height; - if (xfm_dce->base.ctx->dc->debug.surface_visual_confirm) { + if (xfm_dce->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) { overscan_bottom += 2; overscan_right += 2; } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 9cbd5036db0794868a57bcf034bb3cec8899c3fd..33a14e163f880b950aa33b9358f47f281ed6c439 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -864,17 +864,22 @@ void hwss_edp_power_control( if (power_up) { unsigned long long current_ts = dm_get_timestamp(ctx); unsigned long long duration_in_ms = - dm_get_elapse_time_in_ns( + div64_u64(dm_get_elapse_time_in_ns( ctx, current_ts, - div64_u64(link->link_trace.time_stamp.edp_poweroff, 1000000)); + link->link_trace.time_stamp.edp_poweroff), 1000000); unsigned long long wait_time_ms = 0; /* max 500ms from LCDVDD off to on */ + unsigned long long edp_poweroff_time_ms = 500; + + if (link->local_sink != NULL) + edp_poweroff_time_ms = + 500 + link->local_sink->edid_caps.panel_patch.extra_t12_ms; if (link->link_trace.time_stamp.edp_poweroff == 0) - wait_time_ms = 500; - else if (duration_in_ms < 500) - wait_time_ms = 500 - duration_in_ms; + wait_time_ms = edp_poweroff_time_ms; + else if (duration_in_ms < edp_poweroff_time_ms) + wait_time_ms = edp_poweroff_time_ms - duration_in_ms; if (wait_time_ms) { msleep(wait_time_ms); @@ -1245,13 +1250,13 @@ static void program_scaler(const struct dc *dc, { struct tg_color color = {0}; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 /* TOFPGA */ if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) return; #endif - if (dc->debug.surface_visual_confirm) + if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) get_surface_visual_confirm_color(pipe_ctx, &color); else color_space_to_black_color(dc, @@ -2801,9 +2806,11 @@ void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) struct dc_cursor_mi_param param = { .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, - .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, - .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, - .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz + .viewport = pipe_ctx->plane_res.scl_data.viewport, + .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, + .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, + .rotation = pipe_ctx->plane_state->rotation, + .mirror = pipe_ctx->plane_state->horizontal_mirror }; if (pipe_ctx->plane_state->address.type diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c index 0564c8e312529a6d4133ca1d0010172ca8c187da..9b9fc3d96c0712c83e843531c14cb59db67b9727 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c @@ -1011,7 +1011,7 @@ void dce110_free_mem_input_v( { } -static struct mem_input_funcs dce110_mem_input_v_funcs = { +static const struct mem_input_funcs dce110_mem_input_v_funcs = { .mem_input_program_display_marks = dce_mem_input_v_program_display_marks, .mem_input_program_chroma_display_marks = diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 3edaa006bd57651920aed570928d8fa39a513523..1c902e49a71244355eeb773555eaa639d58aa17b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -794,43 +794,38 @@ static bool dce110_validate_bandwidth( if (memcmp(&dc->current_state->bw.dce, &context->bw.dce, sizeof(context->bw.dce))) { - struct log_entry log_entry; - dm_logger_open( - dc->ctx->logger, - &log_entry, - LOG_BANDWIDTH_CALCS); - dm_logger_append(&log_entry, "%s: finish,\n" + + DC_LOG_BANDWIDTH_CALCS( + "%s: finish,\n" + "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" + "stutMark_b: %d stutMark_a: %d\n" "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" - "stutMark_b: %d stutMark_a: %d\n", + "stutMark_b: %d stutMark_a: %d\n" + "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" + "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n" + "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n" + "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n" + , __func__, context->bw.dce.nbp_state_change_wm_ns[0].b_mark, context->bw.dce.nbp_state_change_wm_ns[0].a_mark, context->bw.dce.urgent_wm_ns[0].b_mark, context->bw.dce.urgent_wm_ns[0].a_mark, context->bw.dce.stutter_exit_wm_ns[0].b_mark, - context->bw.dce.stutter_exit_wm_ns[0].a_mark); - dm_logger_append(&log_entry, - "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" - "stutMark_b: %d stutMark_a: %d\n", + context->bw.dce.stutter_exit_wm_ns[0].a_mark, context->bw.dce.nbp_state_change_wm_ns[1].b_mark, context->bw.dce.nbp_state_change_wm_ns[1].a_mark, context->bw.dce.urgent_wm_ns[1].b_mark, context->bw.dce.urgent_wm_ns[1].a_mark, context->bw.dce.stutter_exit_wm_ns[1].b_mark, - context->bw.dce.stutter_exit_wm_ns[1].a_mark); - dm_logger_append(&log_entry, - "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" - "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n", + context->bw.dce.stutter_exit_wm_ns[1].a_mark, context->bw.dce.nbp_state_change_wm_ns[2].b_mark, context->bw.dce.nbp_state_change_wm_ns[2].a_mark, context->bw.dce.urgent_wm_ns[2].b_mark, context->bw.dce.urgent_wm_ns[2].a_mark, context->bw.dce.stutter_exit_wm_ns[2].b_mark, context->bw.dce.stutter_exit_wm_ns[2].a_mark, - context->bw.dce.stutter_mode_enable); - dm_logger_append(&log_entry, - "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n" - "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n", + context->bw.dce.stutter_mode_enable, context->bw.dce.cpuc_state_change_enable, context->bw.dce.cpup_state_change_enable, context->bw.dce.nbp_state_change_enable, @@ -840,7 +835,6 @@ static bool dce110_validate_bandwidth( context->bw.dce.sclk_deep_sleep_khz, context->bw.dce.yclk_khz, context->bw.dce.blackout_recovery_time_us); - dm_logger_close(&log_entry); } return result; } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c index a7dce060204fcccac68edd94c6010b00889c882c..aa8d6b10d2c3fe3cca25617b545336efb37e6655 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c @@ -235,7 +235,7 @@ static void program_overscan( int overscan_right = data->h_active - data->recout.x - data->recout.width; int overscan_bottom = data->v_active - data->recout.y - data->recout.height; - if (xfm_dce->base.ctx->dc->debug.surface_visual_confirm) { + if (xfm_dce->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) { overscan_bottom += 2; overscan_right += 2; } diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 9e1afb11e6ad028aecd8be957b7bb7ca2b037f4b..30d5b32892d69e405f7a3c19f949f2269ea2b60c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -744,43 +744,38 @@ bool dce112_validate_bandwidth( if (memcmp(&dc->current_state->bw.dce, &context->bw.dce, sizeof(context->bw.dce))) { - struct log_entry log_entry; - dm_logger_open( - dc->ctx->logger, - &log_entry, - LOG_BANDWIDTH_CALCS); - dm_logger_append(&log_entry, "%s: finish,\n" + + DC_LOG_BANDWIDTH_CALCS( + "%s: finish,\n" + "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" + "stutMark_b: %d stutMark_a: %d\n" "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" - "stutMark_b: %d stutMark_a: %d\n", + "stutMark_b: %d stutMark_a: %d\n" + "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" + "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n" + "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n" + "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n" + , __func__, context->bw.dce.nbp_state_change_wm_ns[0].b_mark, context->bw.dce.nbp_state_change_wm_ns[0].a_mark, context->bw.dce.urgent_wm_ns[0].b_mark, context->bw.dce.urgent_wm_ns[0].a_mark, context->bw.dce.stutter_exit_wm_ns[0].b_mark, - context->bw.dce.stutter_exit_wm_ns[0].a_mark); - dm_logger_append(&log_entry, - "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" - "stutMark_b: %d stutMark_a: %d\n", + context->bw.dce.stutter_exit_wm_ns[0].a_mark, context->bw.dce.nbp_state_change_wm_ns[1].b_mark, context->bw.dce.nbp_state_change_wm_ns[1].a_mark, context->bw.dce.urgent_wm_ns[1].b_mark, context->bw.dce.urgent_wm_ns[1].a_mark, context->bw.dce.stutter_exit_wm_ns[1].b_mark, - context->bw.dce.stutter_exit_wm_ns[1].a_mark); - dm_logger_append(&log_entry, - "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" - "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n", + context->bw.dce.stutter_exit_wm_ns[1].a_mark, context->bw.dce.nbp_state_change_wm_ns[2].b_mark, context->bw.dce.nbp_state_change_wm_ns[2].a_mark, context->bw.dce.urgent_wm_ns[2].b_mark, context->bw.dce.urgent_wm_ns[2].a_mark, context->bw.dce.stutter_exit_wm_ns[2].b_mark, context->bw.dce.stutter_exit_wm_ns[2].a_mark, - context->bw.dce.stutter_mode_enable); - dm_logger_append(&log_entry, - "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n" - "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n", + context->bw.dce.stutter_mode_enable, context->bw.dce.cpuc_state_change_enable, context->bw.dce.cpup_state_change_enable, context->bw.dce.nbp_state_change_enable, @@ -790,7 +785,6 @@ bool dce112_validate_bandwidth( context->bw.dce.sclk_deep_sleep_khz, context->bw.dce.yclk_khz, context->bw.dce.blackout_recovery_time_us); - dm_logger_close(&log_entry); } return result; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index 742fd497ed006c92846a93d35e842511bd7bf8fb..bf8b68f8db4f7ffab3329b7170906abbbdc42d2d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -445,10 +445,10 @@ void dpp1_set_cursor_position( uint32_t width) { struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); - int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; + int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; uint32_t cur_en = pos->enable ? 1 : 0; - if (src_x_offset >= (int)param->viewport_width) + if (src_x_offset >= (int)param->viewport.width) cur_en = 0; /* not visible beyond right edge*/ if (src_x_offset + (int)width <= 0) @@ -459,6 +459,18 @@ void dpp1_set_cursor_position( } +void dpp1_cnv_set_optional_cursor_attributes( + struct dpp *dpp_base, + struct dpp_cursor_attributes *attr) +{ + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); + + if (attr) { + REG_UPDATE(CURSOR0_FP_SCALE_BIAS, CUR0_FP_BIAS, attr->bias); + REG_UPDATE(CURSOR0_FP_SCALE_BIAS, CUR0_FP_SCALE, attr->scale); + } +} + void dpp1_dppclk_control( struct dpp *dpp_base, bool dppclk_div, @@ -499,6 +511,7 @@ static const struct dpp_funcs dcn10_dpp_funcs = { .dpp_full_bypass = dpp1_full_bypass, .set_cursor_attributes = dpp1_set_cursor_attributes, .set_cursor_position = dpp1_set_cursor_position, + .set_optional_cursor_attributes = dpp1_cnv_set_optional_cursor_attributes, .dpp_dppclk_control = dpp1_dppclk_control, .dpp_set_hdr_multiplier = dpp1_set_hdr_multiplier, }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index e862cafa6501b78e7601fe9e95ebf7f81b728130..e2889e61b18c682dd796de5b756fb2a1815631a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -119,6 +119,7 @@ SRI(CURSOR0_CONTROL, CNVC_CUR, id), \ SRI(CURSOR0_COLOR0, CNVC_CUR, id), \ SRI(CURSOR0_COLOR1, CNVC_CUR, id), \ + SRI(CURSOR0_FP_SCALE_BIAS, CNVC_CUR, id), \ SRI(DPP_CONTROL, DPP_TOP, id), \ SRI(CM_HDR_MULT_COEF, CM, id) @@ -324,6 +325,8 @@ TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \ TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \ TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh), \ + TF_SF(CNVC_CUR0_CURSOR0_FP_SCALE_BIAS, CUR0_FP_BIAS, mask_sh), \ + TF_SF(CNVC_CUR0_CURSOR0_FP_SCALE_BIAS, CUR0_FP_SCALE, mask_sh), \ TF_SF(DPP_TOP0_DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \ TF_SF(CM0_CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, mask_sh) @@ -1076,7 +1079,9 @@ type CUR0_COLOR1; \ type DPPCLK_RATE_CONTROL; \ type DPP_CLOCK_ENABLE; \ - type CM_HDR_MULT_COEF; + type CM_HDR_MULT_COEF; \ + type CUR0_FP_BIAS; \ + type CUR0_FP_SCALE; struct dcn_dpp_shift { TF_REG_FIELD_LIST(uint8_t) @@ -1329,7 +1334,8 @@ struct dcn_dpp_mask { uint32_t CURSOR0_COLOR0; \ uint32_t CURSOR0_COLOR1; \ uint32_t DPP_CONTROL; \ - uint32_t CM_HDR_MULT_COEF; + uint32_t CM_HDR_MULT_COEF; \ + uint32_t CURSOR0_FP_SCALE_BIAS; struct dcn_dpp_registers { DPP_COMMON_REG_VARIABLE_LIST @@ -1370,6 +1376,10 @@ void dpp1_set_cursor_position( const struct dc_cursor_mi_param *param, uint32_t width); +void dpp1_cnv_set_optional_cursor_attributes( + struct dpp *dpp_base, + struct dpp_cursor_attributes *attr); + bool dpp1_dscl_is_lb_conf_valid( int ceil_vratio, int num_partitions, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index f862fd148ccaff5190597a9fc34118299c57122e..4a863a5dab4178103698f574e1fa64b9dd85a625 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -621,6 +621,10 @@ static void dpp1_dscl_set_manual_ratio_init( static void dpp1_dscl_set_recout( struct dcn10_dpp *dpp, const struct rect *recout) { + int visual_confirm_on = 0; + if (dpp->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) + visual_confirm_on = 1; + REG_SET_2(RECOUT_START, 0, /* First pixel of RECOUT */ RECOUT_START_X, recout->x, @@ -632,8 +636,7 @@ static void dpp1_dscl_set_recout( RECOUT_WIDTH, recout->width, /* Number of RECOUT vertical lines */ RECOUT_HEIGHT, recout->height - - dpp->base.ctx->dc->debug.surface_visual_confirm * 4 * - (dpp->base.inst + 1)); + - visual_confirm_on * 4 * (dpp->base.inst + 1)); } /* Main function to program scaler and line buffer in manual scaling mode */ @@ -655,6 +658,12 @@ void dpp1_dscl_set_scaler_manual_scale( dpp->scl_data = *scl_data; + /* Autocal off */ + REG_SET_3(DSCL_AUTOCAL, 0, + AUTOCAL_MODE, AUTOCAL_MODE_OFF, + AUTOCAL_NUM_PIPE, 0, + AUTOCAL_PIPE_ID, 0); + /* Recout */ dpp1_dscl_set_recout(dpp, &scl_data->recout); @@ -678,12 +687,6 @@ void dpp1_dscl_set_scaler_manual_scale( if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) return; - /* Autocal off */ - REG_SET_3(DSCL_AUTOCAL, 0, - AUTOCAL_MODE, AUTOCAL_MODE_OFF, - AUTOCAL_NUM_PIPE, 0, - AUTOCAL_PIPE_ID, 0); - /* Black offsets */ if (ycbcr) REG_SET_2(SCL_BLACK_OFFSET, 0, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 93f52c58bc695c1be0ead3c02f1b51cb220749cd..332354ca6529ea5a4ca4b32aa847d9a7e838fa6e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -152,16 +152,14 @@ void hubp1_program_tiling( PIPE_ALIGNED, info->gfx9.pipe_aligned); } -void hubp1_program_size_and_rotation( +void hubp1_program_size( struct hubp *hubp, - enum dc_rotation_angle rotation, enum surface_pixel_format format, const union plane_size *plane_size, - struct dc_plane_dcc_param *dcc, - bool horizontal_mirror) + struct dc_plane_dcc_param *dcc) { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c, mirror; + uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c; /* Program data and meta surface pitch (calculation from addrlib) * 444 or 420 luma @@ -192,13 +190,22 @@ void hubp1_program_size_and_rotation( if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) REG_UPDATE_2(DCSURF_SURFACE_PITCH_C, PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c); +} + +void hubp1_program_rotation( + struct hubp *hubp, + enum dc_rotation_angle rotation, + bool horizontal_mirror) +{ + struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); + uint32_t mirror; + if (horizontal_mirror) mirror = 1; else mirror = 0; - /* Program rotation angle and horz mirror - no mirror */ if (rotation == ROTATION_ANGLE_0) REG_UPDATE_2(DCSURF_SURFACE_CONFIG, @@ -450,9 +457,6 @@ bool hubp1_program_surface_flip_and_addr( hubp->request_address = *address; - if (flip_immediate) - hubp->current_address = *address; - return true; } @@ -481,8 +485,8 @@ void hubp1_program_surface_config( { hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks); hubp1_program_tiling(hubp, tiling_info, format); - hubp1_program_size_and_rotation( - hubp, rotation, format, plane_size, dcc, horizontal_mirror); + hubp1_program_size(hubp, format, plane_size, dcc); + hubp1_program_rotation(hubp, rotation, horizontal_mirror); hubp1_program_pixel_format(hubp, format); } @@ -688,7 +692,6 @@ bool hubp1_is_flip_pending(struct hubp *hubp) if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part) return true; - hubp->current_address = hubp->request_address; return false; } @@ -1061,9 +1064,11 @@ void hubp1_cursor_set_position( const struct dc_cursor_mi_param *param) { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; + int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; + int x_hotspot = pos->x_hotspot; + int y_hotspot = pos->y_hotspot; + uint32_t dst_x_offset; uint32_t cur_en = pos->enable ? 1 : 0; - uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; /* * Guard aganst cursor_set_position() from being called with invalid @@ -1075,6 +1080,18 @@ void hubp1_cursor_set_position( if (hubp->curs_attr.address.quad_part == 0) return; + if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { + src_x_offset = pos->y - pos->y_hotspot - param->viewport.x; + y_hotspot = pos->x_hotspot; + x_hotspot = pos->y_hotspot; + } + + if (param->mirror) { + x_hotspot = param->viewport.width - x_hotspot; + src_x_offset = param->viewport.x + param->viewport.width - src_x_offset; + } + + dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; dst_x_offset *= param->ref_clk_khz; dst_x_offset /= param->pixel_clk_khz; @@ -1085,7 +1102,7 @@ void hubp1_cursor_set_position( dc_fixpt_from_int(dst_x_offset), param->h_scale_ratio)); - if (src_x_offset >= (int)param->viewport_width) + if (src_x_offset >= (int)param->viewport.width) cur_en = 0; /* not visible beyond right edge*/ if (src_x_offset + (int)hubp->curs_attr.width <= 0) @@ -1102,8 +1119,8 @@ void hubp1_cursor_set_position( CURSOR_Y_POSITION, pos->y); REG_SET_2(CURSOR_HOT_SPOT, 0, - CURSOR_HOT_SPOT_X, pos->x_hotspot, - CURSOR_HOT_SPOT_Y, pos->y_hotspot); + CURSOR_HOT_SPOT_X, x_hotspot, + CURSOR_HOT_SPOT_Y, y_hotspot); REG_SET(CURSOR_DST_OFFSET, 0, CURSOR_DST_X_OFFSET, dst_x_offset); @@ -1125,7 +1142,7 @@ void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst) REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst); } -static struct hubp_funcs dcn10_hubp_funcs = { +static const struct hubp_funcs dcn10_hubp_funcs = { .hubp_program_surface_flip_and_addr = hubp1_program_surface_flip_and_addr, .hubp_program_surface_config = diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h index d901d5092969d6897022243cea08b6351caaa0f1..f689feace82d189ef1e99a16a955b364c1b61e34 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h @@ -268,8 +268,6 @@ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_PITCH, META_PITCH, mask_sh),\ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_PITCH_C, PITCH_C, mask_sh),\ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_PITCH_C, META_PITCH_C, mask_sh),\ - HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, ROTATION_ANGLE, mask_sh),\ - HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, H_MIRROR_EN, mask_sh),\ HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, SURFACE_PIXEL_FORMAT, mask_sh),\ HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL, SURFACE_FLIP_TYPE, mask_sh),\ HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL, SURFACE_FLIP_PENDING, mask_sh),\ @@ -388,6 +386,8 @@ #define HUBP_MASK_SH_LIST_DCN10(mask_sh)\ HUBP_MASK_SH_LIST_DCN(mask_sh),\ HUBP_MASK_SH_LIST_DCN_VM(mask_sh),\ + HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, ROTATION_ANGLE, mask_sh),\ + HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, H_MIRROR_EN, mask_sh),\ HUBP_SF(HUBPREQ0_PREFETCH_SETTINS, DST_Y_PREFETCH, mask_sh),\ HUBP_SF(HUBPREQ0_PREFETCH_SETTINS, VRATIO_PREFETCH, mask_sh),\ HUBP_SF(HUBPREQ0_PREFETCH_SETTINS_C, VRATIO_PREFETCH_C, mask_sh),\ @@ -679,12 +679,15 @@ void hubp1_program_pixel_format( struct hubp *hubp, enum surface_pixel_format format); -void hubp1_program_size_and_rotation( +void hubp1_program_size( struct hubp *hubp, - enum dc_rotation_angle rotation, enum surface_pixel_format format, const union plane_size *plane_size, - struct dc_plane_dcc_param *dcc, + struct dc_plane_dcc_param *dcc); + +void hubp1_program_rotation( + struct hubp *hubp, + enum dc_rotation_angle rotation, bool horizontal_mirror); void hubp1_program_tiling( diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 3b2cb2d3b8a61f6fb2c55bfb427a06d747c2d1f1..c87f6e603055a3dae9f75c5e6f8786ebfba9ef8a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -834,7 +834,7 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc) } -static void dcn10_verify_allow_pstate_change_high(struct dc *dc) +void dcn10_verify_allow_pstate_change_high(struct dc *dc) { static bool should_log_hw_state; /* prevent hw state log by default */ @@ -1157,12 +1157,19 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c if (plane_state == NULL) return; + addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr); + pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr( pipe_ctx->plane_res.hubp, &plane_state->address, plane_state->flip_immediate); + plane_state->status.requested_address = plane_state->address; + + if (plane_state->flip_immediate) + plane_state->status.current_address = plane_state->address; + if (addr_patched) pipe_ctx->plane_state->address.grph_stereo.left_addr = addr; } @@ -1768,6 +1775,43 @@ static void dcn10_get_surface_visual_confirm_color( } } +static void dcn10_get_hdr_visual_confirm_color( + struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + uint32_t color_value = MAX_TG_COLOR_VALUE; + + // Determine the overscan color based on the top-most (desktop) plane's context + struct pipe_ctx *top_pipe_ctx = pipe_ctx; + + while (top_pipe_ctx->top_pipe != NULL) + top_pipe_ctx = top_pipe_ctx->top_pipe; + + switch (top_pipe_ctx->plane_res.scl_data.format) { + case PIXEL_FORMAT_ARGB2101010: + if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_UNITY) { + /* HDR10, ARGB2101010 - set boarder color to red */ + color->color_r_cr = color_value; + } + break; + case PIXEL_FORMAT_FP16: + if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { + /* HDR10, FP16 - set boarder color to blue */ + color->color_b_cb = color_value; + } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) { + /* FreeSync 2 HDR - set boarder color to green */ + color->color_g_y = color_value; + } + break; + default: + /* SDR - set boarder color to Gray */ + color->color_r_cr = color_value/2; + color->color_b_cb = color_value/2; + color->color_g_y = color_value/2; + break; + } +} + static uint16_t fixed_point_to_int_frac( struct fixed31_32 arg, uint8_t integer_bits, @@ -1848,11 +1892,10 @@ static void update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state) dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params); } - -static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) +static void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) { struct hubp *hubp = pipe_ctx->plane_res.hubp; - struct mpcc_blnd_cfg blnd_cfg; + struct mpcc_blnd_cfg blnd_cfg = {0}; bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; int mpcc_id; struct mpcc *new_mpcc; @@ -1863,13 +1906,17 @@ static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) /* TODO: proper fix once fpga works */ - if (dc->debug.surface_visual_confirm) + if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) { + dcn10_get_hdr_visual_confirm_color( + pipe_ctx, &blnd_cfg.black_color); + } else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) { dcn10_get_surface_visual_confirm_color( pipe_ctx, &blnd_cfg.black_color); - else + } else { color_space_to_black_color( - dc, pipe_ctx->stream->output_color_space, - &blnd_cfg.black_color); + dc, pipe_ctx->stream->output_color_space, + &blnd_cfg.black_color); + } if (per_pixel_alpha) blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; @@ -1994,7 +2041,7 @@ static void update_dchubp_dpp( if (plane_state->update_flags.bits.full_update || plane_state->update_flags.bits.per_pixel_alpha_change) - update_mpcc(dc, pipe_ctx); + dc->hwss.update_mpcc(dc, pipe_ctx); if (plane_state->update_flags.bits.full_update || plane_state->update_flags.bits.per_pixel_alpha_change || @@ -2104,6 +2151,33 @@ static void set_hdr_multiplier(struct pipe_ctx *pipe_ctx) pipe_ctx->plane_res.dpp, hw_mult); } +void dcn10_program_pipe( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct dc_state *context) +{ + if (pipe_ctx->plane_state->update_flags.bits.full_update) + dcn10_enable_plane(dc, pipe_ctx, context); + + update_dchubp_dpp(dc, pipe_ctx, context); + + set_hdr_multiplier(pipe_ctx); + + if (pipe_ctx->plane_state->update_flags.bits.full_update || + pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || + pipe_ctx->plane_state->update_flags.bits.gamma_change) + dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state); + + /* dcn10_translate_regamma_to_hw_format takes 750us to finish + * only do gamma programming for full update. + * TODO: This can be further optimized/cleaned up + * Always call this for now since it does memcmp inside before + * doing heavy calculation and programming + */ + if (pipe_ctx->plane_state->update_flags.bits.full_update) + dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); +} + static void program_all_pipe_in_tree( struct dc *dc, struct pipe_ctx *pipe_ctx, @@ -2122,29 +2196,11 @@ static void program_all_pipe_in_tree( pipe_ctx->stream_res.tg); dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); + } if (pipe_ctx->plane_state != NULL) { - if (pipe_ctx->plane_state->update_flags.bits.full_update) - dcn10_enable_plane(dc, pipe_ctx, context); - - update_dchubp_dpp(dc, pipe_ctx, context); - - set_hdr_multiplier(pipe_ctx); - - if (pipe_ctx->plane_state->update_flags.bits.full_update || - pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || - pipe_ctx->plane_state->update_flags.bits.gamma_change) - dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state); - - /* dcn10_translate_regamma_to_hw_format takes 750us to finish - * only do gamma programming for full update. - * TODO: This can be further optimized/cleaned up - * Always call this for now since it does memcmp inside before - * doing heavy calculation and programming - */ - if (pipe_ctx->plane_state->update_flags.bits.full_update) - dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); + dcn10_program_pipe(dc, pipe_ctx, context); } if (pipe_ctx->bottom_pipe != NULL && pipe_ctx->bottom_pipe != pipe_ctx) { @@ -2269,7 +2325,7 @@ static void dcn10_apply_ctx_for_surface( old_pipe_ctx->plane_state && old_pipe_ctx->stream_res.tg == tg) { - hwss1_plane_atomic_disconnect(dc, old_pipe_ctx); + dc->hwss.plane_atomic_disconnect(dc, old_pipe_ctx); removed_pipe[i] = true; DC_LOG_DC("Reset mpcc for pipe %d\n", @@ -2484,16 +2540,20 @@ static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx) { struct dc_plane_state *plane_state = pipe_ctx->plane_state; struct timing_generator *tg = pipe_ctx->stream_res.tg; + bool flip_pending; if (plane_state == NULL) return; - plane_state->status.is_flip_pending = - pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending( + flip_pending = pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending( pipe_ctx->plane_res.hubp); - plane_state->status.current_address = pipe_ctx->plane_res.hubp->current_address; - if (pipe_ctx->plane_res.hubp->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && + plane_state->status.is_flip_pending = flip_pending; + + if (!flip_pending) + plane_state->status.current_address = plane_state->status.requested_address; + + if (plane_state->status.current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && tg->funcs->is_stereo_left_eye) { plane_state->status.is_right_eye = !tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); @@ -2520,9 +2580,11 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) struct dc_cursor_mi_param param = { .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, - .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, - .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, - .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz + .viewport = pipe_ctx->plane_res.scl_data.viewport, + .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, + .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, + .rotation = pipe_ctx->plane_state->rotation, + .mirror = pipe_ctx->plane_state->horizontal_mirror }; if (pipe_ctx->plane_state->address.type @@ -2546,6 +2608,33 @@ static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx) pipe_ctx->plane_res.dpp, attributes->color_format); } +static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx) +{ + uint32_t sdr_white_level = pipe_ctx->stream->cursor_attributes.sdr_white_level; + struct fixed31_32 multiplier; + struct dpp_cursor_attributes opt_attr = { 0 }; + uint32_t hw_scale = 0x3c00; // 1.0 default multiplier + struct custom_float_format fmt; + + if (!pipe_ctx->plane_res.dpp->funcs->set_optional_cursor_attributes) + return; + + fmt.exponenta_bits = 5; + fmt.mantissa_bits = 10; + fmt.sign = true; + + if (sdr_white_level > 80) { + multiplier = dc_fixpt_from_fraction(sdr_white_level, 80); + convert_to_custom_float_format(multiplier, &fmt, &hw_scale); + } + + opt_attr.scale = hw_scale; + opt_attr.bias = 0; + + pipe_ctx->plane_res.dpp->funcs->set_optional_cursor_attributes( + pipe_ctx->plane_res.dpp, &opt_attr); +} + static const struct hw_sequencer_funcs dcn10_funcs = { .program_gamut_remap = program_gamut_remap, .program_csc_matrix = program_csc_matrix, @@ -2553,7 +2642,9 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, .update_plane_addr = dcn10_update_plane_addr, + .plane_atomic_disconnect = hwss1_plane_atomic_disconnect, .update_dchub = dcn10_update_dchub, + .update_mpcc = dcn10_update_mpcc, .update_pending_status = dcn10_update_pending_status, .set_input_transfer_func = dcn10_set_input_transfer_func, .set_output_transfer_func = dcn10_set_output_transfer_func, @@ -2591,7 +2682,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .edp_power_control = hwss_edp_power_control, .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, .set_cursor_position = dcn10_set_cursor_position, - .set_cursor_attribute = dcn10_set_cursor_attribute + .set_cursor_attribute = dcn10_set_cursor_attribute, + .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index 44f734b73f9ea41d75e65c49131d6f4b4a27dfdd..7139fb73e966eeaf79823c6204b9fc34ccd5d6da 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -39,4 +39,11 @@ bool is_rgb_cspace(enum dc_color_space output_color_space); void hwss1_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx); +void dcn10_verify_allow_pstate_change_high(struct dc *dc); + +void dcn10_program_pipe( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct dc_state *context); + #endif /* __DC_HWSS_DCN10_H__ */ 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 fd9dc70190a88b26a8d5424fc8bb3a1b03aaea6d..6f675206a136a7406859f5486ef5400893f75b11 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 @@ -65,11 +65,6 @@ enum { DP_MST_UPDATE_MAX_RETRY = 50 }; - - -static void aux_initialize(struct dcn10_link_encoder *enc10); - - static const struct link_encoder_funcs dcn10_lnk_enc_funcs = { .validate_output_with_stream = dcn10_link_encoder_validate_output_with_stream, @@ -445,12 +440,11 @@ static uint8_t get_frontend_source( } } -static void configure_encoder( +void configure_encoder( struct dcn10_link_encoder *enc10, const struct dc_link_settings *link_settings) { /* set number of lanes */ - REG_SET(DP_CONFIG, 0, DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE); @@ -602,6 +596,9 @@ static bool dcn10_link_encoder_validate_hdmi_output( if (!enc10->base.features.flags.bits.HDMI_6GB_EN && adjusted_pix_clk_khz >= 300000) return false; + if (enc10->base.ctx->dc->debug.hdmi20_disable && + crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + return false; return true; } @@ -734,6 +731,9 @@ void dcn10_link_encoder_construct( __func__, result); } + if (enc10->base.ctx->dc->debug.hdmi20_disable) { + enc10->base.features.flags.bits.HDMI_6GB_EN = 0; + } } bool dcn10_link_encoder_validate_output_with_stream( @@ -812,7 +812,7 @@ void dcn10_link_encoder_hw_init( ASSERT(result == BP_RESULT_OK); } - aux_initialize(enc10); + dcn10_aux_initialize(enc10); /* reinitialize HPD. * hpd_initialize() will pass DIG_FE id to HW context. @@ -1349,8 +1349,7 @@ void dcn10_link_encoder_disable_hpd(struct link_encoder *enc) FN(reg, f1), v1,\ FN(reg, f2), v2) -static void aux_initialize( - struct dcn10_link_encoder *enc10) +void dcn10_aux_initialize(struct dcn10_link_encoder *enc10) { enum hpd_source_id hpd_source = enc10->base.hpd_source; 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 2a97cdb2cfbb361655fbfdc16fba83e66d627797..49ead12b25329f497e6acf2c43411e1a8548ff11 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(TMDS_CTL_BITS, DIG, id), \ SRI(DP_CONFIG, DP, id), \ SRI(DP_DPHY_CNTL, DP, id), \ SRI(DP_DPHY_PRBS_CNTL, DP, id), \ @@ -64,6 +65,7 @@ SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id) + #define LE_DCN10_REG_LIST(id)\ LE_DCN_COMMON_REG_LIST(id) @@ -100,6 +102,7 @@ struct dcn10_link_enc_registers { uint32_t DP_DPHY_BS_SR_SWAP_CNTL; uint32_t DP_DPHY_HBR2_PATTERN_CONTROL; uint32_t DP_SEC_CNTL1; + uint32_t TMDS_CTL_BITS; }; #define LE_SF(reg_name, field_name, post_fix)\ @@ -110,6 +113,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_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),\ LE_SF(DP0_DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE1, mask_sh),\ @@ -198,10 +202,11 @@ struct dcn10_link_enc_registers { type DP_MSE_SAT_SLOT_COUNT3;\ type DP_MSE_SAT_UPDATE;\ type DP_MSE_16_MTP_KEEPOUT;\ + type DC_HPD_EN;\ + type TMDS_CTL0;\ type AUX_HPD_SEL;\ type AUX_LS_READ_EN;\ - type AUX_RX_RECEIVE_WINDOW;\ - type DC_HPD_EN + type AUX_RX_RECEIVE_WINDOW struct dcn10_link_enc_shift { DCN_LINK_ENCODER_REG_FIELD_LIST(uint8_t); @@ -266,6 +271,10 @@ void dcn10_link_encoder_setup( struct link_encoder *enc, enum signal_type signal); +void configure_encoder( + struct dcn10_link_encoder *enc10, + const struct dc_link_settings *link_settings); + /* enables TMDS PHY output */ /* TODO: still need depth or just pass in adjusted pixel clock? */ void dcn10_link_encoder_enable_tmds_output( @@ -327,4 +336,6 @@ void dcn10_psr_program_secondary_packet(struct link_encoder *enc, bool dcn10_is_dig_enabled(struct link_encoder *enc); +void dcn10_aux_initialize(struct dcn10_link_encoder *enc10); + #endif /* __DC_LINK_ENCODER__DCN10_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c index 9ca51ae46de743c9a9b455177a33b6eb25716b39..958994edf2c49de84428848bd25abe15e466a036 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -428,7 +428,7 @@ void mpc1_read_mpcc_state( MPCC_BUSY, &s->busy); } -const struct mpc_funcs dcn10_mpc_funcs = { +static const struct mpc_funcs dcn10_mpc_funcs = { .read_mpcc_state = mpc1_read_mpcc_state, .insert_plane = mpc1_insert_plane, .remove_mpcc = mpc1_remove_mpcc, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c index 77a1a9d541a410119f92e77cc144477137337983..ab958cff3b7601a0c2dbe187ddb443af6800643c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c @@ -385,7 +385,7 @@ void opp1_destroy(struct output_pixel_processor **opp) *opp = NULL; } -static struct opp_funcs dcn10_opp_funcs = { +static const struct opp_funcs dcn10_opp_funcs = { .opp_set_dyn_expansion = opp1_set_dyn_expansion, .opp_program_fmt = opp1_program_fmt, .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index e6a3ade154b92f475c70c5ecfc904271dd6a231f..411f89218e0194fcd80980b239c9e514acc0d9f8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -1324,6 +1324,72 @@ bool optc1_is_optc_underflow_occurred(struct timing_generator *optc) return (underflow_occurred == 1); } +bool optc1_configure_crc(struct timing_generator *optc, + const struct crc_params *params) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + /* Cannot configure crc on a CRTC that is disabled */ + if (!optc1_is_tg_enabled(optc)) + return false; + + REG_WRITE(OTG_CRC_CNTL, 0); + + if (!params->enable) + return true; + + /* Program frame boundaries */ + /* Window A x axis start and end. */ + REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL, + OTG_CRC0_WINDOWA_X_START, params->windowa_x_start, + OTG_CRC0_WINDOWA_X_END, params->windowa_x_end); + + /* Window A y axis start and end. */ + REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL, + OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start, + OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end); + + /* Window B x axis start and end. */ + REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL, + OTG_CRC0_WINDOWB_X_START, params->windowb_x_start, + OTG_CRC0_WINDOWB_X_END, params->windowb_x_end); + + /* Window B y axis start and end. */ + REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL, + OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start, + OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end); + + /* Set crc mode and selection, and enable. Only using CRC0*/ + REG_UPDATE_3(OTG_CRC_CNTL, + OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0, + OTG_CRC0_SELECT, params->selection, + OTG_CRC_EN, 1); + + return true; +} + +bool optc1_get_crc(struct timing_generator *optc, + uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) +{ + uint32_t field = 0; + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_GET(OTG_CRC_CNTL, OTG_CRC_EN, &field); + + /* Early return if CRC is not enabled for this CRTC */ + if (!field) + return false; + + REG_GET_2(OTG_CRC0_DATA_RG, + CRC0_R_CR, r_cr, + CRC0_G_Y, g_y); + + REG_GET(OTG_CRC0_DATA_B, + CRC0_B_CB, b_cb); + + return true; +} + static const struct timing_generator_funcs dcn10_tg_funcs = { .validate_timing = optc1_validate_timing, .program_timing = optc1_program_timing, @@ -1360,6 +1426,8 @@ static const struct timing_generator_funcs dcn10_tg_funcs = { .is_tg_enabled = optc1_is_tg_enabled, .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, .clear_optc_underflow = optc1_clear_optc_underflow, + .get_crc = optc1_get_crc, + .configure_crc = optc1_configure_crc, }; void dcn10_timing_generator_init(struct optc *optc1) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h index 59ed272e0c493e77a6bbc9cec3da169c7ebba90c..c1b114209fe8da2f1e5499660548f4db855f889c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h @@ -75,7 +75,14 @@ SRI(CONTROL, VTG, inst),\ SRI(OTG_VERT_SYNC_CONTROL, OTG, inst),\ SRI(OTG_MASTER_UPDATE_MODE, OTG, inst),\ - SRI(OTG_GSL_CONTROL, OTG, inst) + SRI(OTG_GSL_CONTROL, OTG, inst),\ + SRI(OTG_CRC_CNTL, OTG, inst),\ + SRI(OTG_CRC0_DATA_RG, OTG, inst),\ + SRI(OTG_CRC0_DATA_B, OTG, inst),\ + SRI(OTG_CRC0_WINDOWA_X_CONTROL, OTG, inst),\ + SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\ + SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\ + SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst) #define TG_COMMON_REG_LIST_DCN1_0(inst) \ TG_COMMON_REG_LIST_DCN(inst),\ @@ -138,6 +145,13 @@ struct dcn_optc_registers { uint32_t OTG_GSL_WINDOW_X; uint32_t OTG_GSL_WINDOW_Y; uint32_t OTG_VUPDATE_KEEPOUT; + uint32_t OTG_CRC_CNTL; + uint32_t OTG_CRC0_DATA_RG; + uint32_t OTG_CRC0_DATA_B; + uint32_t OTG_CRC0_WINDOWA_X_CONTROL; + uint32_t OTG_CRC0_WINDOWA_Y_CONTROL; + uint32_t OTG_CRC0_WINDOWB_X_CONTROL; + uint32_t OTG_CRC0_WINDOWB_Y_CONTROL; }; #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ @@ -232,7 +246,21 @@ struct dcn_optc_registers { SF(OTG0_OTG_GSL_CONTROL, OTG_GSL2_EN, mask_sh),\ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_EN, mask_sh),\ SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_FORCE_DELAY, mask_sh),\ - SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh) + SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\ + SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\ + SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\ + SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\ + SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\ + SF(OTG0_OTG_CRC0_DATA_RG, CRC0_G_Y, mask_sh),\ + SF(OTG0_OTG_CRC0_DATA_B, CRC0_B_CB, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL, OTG_CRC0_WINDOWA_X_START, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL, OTG_CRC0_WINDOWA_X_END, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWA_Y_CONTROL, OTG_CRC0_WINDOWA_Y_START, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWA_Y_CONTROL, OTG_CRC0_WINDOWA_Y_END, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_START, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\ + SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh) #define TG_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ @@ -363,7 +391,22 @@ struct dcn_optc_registers { type OTG_MASTER_UPDATE_LOCK_GSL_EN;\ type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET;\ type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET;\ - type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN; + type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;\ + type OTG_CRC_CONT_EN;\ + type OTG_CRC0_SELECT;\ + type OTG_CRC_EN;\ + type CRC0_R_CR;\ + type CRC0_G_Y;\ + type CRC0_B_CB;\ + type OTG_CRC0_WINDOWA_X_START;\ + type OTG_CRC0_WINDOWA_X_END;\ + type OTG_CRC0_WINDOWA_Y_START;\ + type OTG_CRC0_WINDOWA_Y_END;\ + type OTG_CRC0_WINDOWB_X_START;\ + type OTG_CRC0_WINDOWB_X_END;\ + type OTG_CRC0_WINDOWB_Y_START;\ + type OTG_CRC0_WINDOWB_Y_END; + #define TG_REG_FIELD_LIST(type) \ TG_REG_FIELD_LIST_DCN1_0(type) @@ -511,4 +554,15 @@ bool optc1_get_otg_active_size(struct timing_generator *optc, uint32_t *otg_active_width, uint32_t *otg_active_height); +void optc1_enable_crtc_reset( + struct timing_generator *optc, + int source_tg_inst, + struct crtc_trigger_info *crtc_tp); + +bool optc1_configure_crc(struct timing_generator *optc, + const struct crc_params *params); + +bool optc1_get_crc(struct timing_generator *optc, + uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb); + #endif /* __DC_TIMING_GENERATOR_DCN10_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 771e0cf29bbaaed70272ee402c27e2e5fe93fca7..84581b3c392ba508e5a6c6d194d6eadda3c2c3ca 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1035,11 +1035,11 @@ static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_st return DC_OK; } -static struct dc_cap_funcs cap_funcs = { +static const struct dc_cap_funcs cap_funcs = { .get_dcc_compression_cap = dcn10_get_dcc_compression_cap }; -static struct resource_funcs dcn10_res_pool_funcs = { +static const struct resource_funcs dcn10_res_pool_funcs = { .destroy = dcn10_destroy_resource_pool, .link_enc_create = dcn10_link_encoder_create, .validate_bandwidth = dcn_validate_bandwidth, diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index 034369fbb9e2cb5e5f0eb95931fb7b9e9ddafdfb..5d4527d03045e1902f65bf5f5ea511dd58875f04 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -40,6 +40,14 @@ enum dc_edid_status dm_helpers_parse_edid_caps( const struct dc_edid *edid, struct dc_edid_caps *edid_caps); + +/* + * Update DP branch info + */ +void dm_helpers_dp_update_branch_info( + struct dc_context *ctx, + const struct dc_link *link); + /* * Writes payload allocation table in immediate downstream device. */ @@ -103,6 +111,9 @@ bool dm_helpers_submit_i2c( const struct dc_link *link, struct i2c_command *cmd); +bool dm_helpers_is_dp_sink_present( + struct dc_link *link); + enum dc_edid_status dm_helpers_read_local_edid( struct dc_context *ctx, struct dc_link *link, 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 6943801c5fd3f5c509e7f181d87df2cb8914b6a2..cbafce649e3334e9e834fb0d9492a7d10ae07c46 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 @@ -111,6 +111,8 @@ struct _vcs_dpi_soc_bounding_box_st { double xfc_bus_transport_time_us; double xfc_xbuf_latency_tolerance_us; int use_urgent_burst_bw; + double max_hscl_ratio; + double max_vscl_ratio; struct _vcs_dpi_voltage_scaling_st clock_limits[7]; }; @@ -303,6 +305,7 @@ struct _vcs_dpi_display_pipe_dest_params_st { unsigned char otg_inst; unsigned char odm_split_cnt; unsigned char odm_combine; + unsigned char use_maximum_vstartup; }; struct _vcs_dpi_display_pipe_params_st { diff --git a/drivers/gpu/drm/amd/display/dc/gpio/Makefile b/drivers/gpu/drm/amd/display/dc/gpio/Makefile index 562ee189d780c4de20d150a16497c27ef44300a8..b9d9930a49743cbae8d54c45d88326a7c3444be9 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/Makefile +++ b/drivers/gpu/drm/amd/display/dc/gpio/Makefile @@ -61,7 +61,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCE120) ############################################################################### # DCN 1x ############################################################################### -ifdef CONFIG_DRM_AMD_DC_DCN1_0 +ifdef CONFIG_X86 GPIO_DCN10 = hw_translate_dcn10.o hw_factory_dcn10.o AMD_DAL_GPIO_DCN10 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn10/,$(GPIO_DCN10)) diff --git a/drivers/gpu/drm/amd/display/dc/gpio/ddc_regs.h b/drivers/gpu/drm/amd/display/dc/gpio/ddc_regs.h index 9c4a56c738c0127aa06224b085500f41f3aa6944..bf40725f982ff4cc92b534aa859a339ba38b4324 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/ddc_regs.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/ddc_regs.h @@ -82,13 +82,16 @@ DDC_GPIO_I2C_REG_LIST(cd),\ .ddc_setup = 0 -#define DDC_MASK_SH_LIST(mask_sh) \ +#define DDC_MASK_SH_LIST_COMMON(mask_sh) \ SF_DDC(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE, mask_sh),\ SF_DDC(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_EDID_DETECT_ENABLE, mask_sh),\ SF_DDC(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_EDID_DETECT_MODE, mask_sh),\ SF_DDC(DC_GPIO_DDC1_MASK, DC_GPIO_DDC1DATA_PD_EN, mask_sh),\ SF_DDC(DC_GPIO_DDC1_MASK, DC_GPIO_DDC1CLK_PD_EN, mask_sh),\ - SF_DDC(DC_GPIO_DDC1_MASK, AUX_PAD1_MODE, mask_sh),\ + SF_DDC(DC_GPIO_DDC1_MASK, AUX_PAD1_MODE, mask_sh) + +#define DDC_MASK_SH_LIST(mask_sh) \ + DDC_MASK_SH_LIST_COMMON(mask_sh),\ SF_DDC(DC_GPIO_I2CPAD_MASK, DC_GPIO_SDA_PD_DIS, mask_sh),\ SF_DDC(DC_GPIO_I2CPAD_MASK, DC_GPIO_SCL_PD_DIS, mask_sh) diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index ab5483c0c502cedbe04e83375a04da6799a5c12a..f20161c5706d7278cc0c48f92eedebf0bdf0ce73 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -375,6 +375,7 @@ struct gpio *dal_gpio_create_irq( case GPIO_ID_GPIO_PAD: break; default: + id = GPIO_ID_HPD; ASSERT_CRITICAL(false); return NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index 0caee3523017fe74e45a217e604cd57004a64486..83df779984e5da9d32df682f5fea318426684d00 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c @@ -43,7 +43,7 @@ #include "dce80/hw_factory_dce80.h" #include "dce110/hw_factory_dce110.h" #include "dce120/hw_factory_dce120.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "dcn10/hw_factory_dcn10.h" #endif @@ -81,7 +81,7 @@ bool dal_hw_factory_init( case DCE_VERSION_12_0: dal_hw_factory_dce120_init(factory); return true; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: dal_hw_factory_dcn10_init(factory); return true; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c index 55c7074885413e8ebba1ce2ccc886f6586850c87..e7541310480b1ce32f60fff366f56d99c0884b4b 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c @@ -43,7 +43,7 @@ #include "dce80/hw_translate_dce80.h" #include "dce110/hw_translate_dce110.h" #include "dce120/hw_translate_dce120.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "dcn10/hw_translate_dcn10.h" #endif @@ -78,7 +78,7 @@ bool dal_hw_translate_init( case DCE_VERSION_12_0: dal_hw_translate_dce120_init(translate); return true; -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: dal_hw_translate_dcn10_init(translate); return true; diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile b/drivers/gpu/drm/amd/display/dc/i2caux/Makefile index 352885cb4d0763dd3bb4912e59722abd9ee4589c..a851d07f01901c1f4dad48090f26d3e0fd1c31c3 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/Makefile +++ b/drivers/gpu/drm/amd/display/dc/i2caux/Makefile @@ -71,7 +71,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE112) ############################################################################### # DCN 1.0 family ############################################################################### -ifdef CONFIG_DRM_AMD_DC_DCN1_0 +ifdef CONFIG_X86 I2CAUX_DCN1 = i2caux_dcn10.o AMD_DAL_I2CAUX_DCN1 = $(addprefix $(AMDDALPATH)/dc/i2caux/dcn10/,$(I2CAUX_DCN1)) diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c index 1d7309611978e9f07162e919879414618c45e4e0..0afd2fa57bbe5efbf9c988591862dab7b468f7e6 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c @@ -128,8 +128,20 @@ static void process_read_reply( ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR; ctx->operation_succeeded = false; + } else if (ctx->returned_byte < ctx->current_read_length) { + ctx->current_read_length -= ctx->returned_byte; + + ctx->offset += ctx->returned_byte; + + ++ctx->invalid_reply_retry_aux_on_ack; + + if (ctx->invalid_reply_retry_aux_on_ack > + AUX_INVALID_REPLY_RETRY_COUNTER) { + ctx->status = + I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR; + ctx->operation_succeeded = false; + } } else { - ctx->current_read_length = ctx->returned_byte; ctx->status = I2CAUX_TRANSACTION_STATUS_SUCCEEDED; ctx->transaction_complete = true; ctx->operation_succeeded = true; @@ -290,7 +302,6 @@ static bool read_command( ctx.operation_succeeded); } - request->payload.length = ctx.reply.length; return ctx.operation_succeeded; } diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h index b01488f710d51dd5a8a2f7b9ff1bd589f99db5f8..c33a2898d9671e26d05c9a3345b71c3f8484a70f 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h @@ -44,6 +44,12 @@ struct aux_engine_funcs { void (*process_channel_reply)( struct aux_engine *engine, struct aux_reply_transaction_data *reply); + int (*read_channel_reply)( + struct aux_engine *engine, + uint32_t size, + uint8_t *buffer, + uint8_t *reply_result, + uint32_t *sw_status); enum aux_channel_operation_result (*get_channel_status)( struct aux_engine *engine, uint8_t *returned_bytes); diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce100/i2caux_dce100.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce100/i2caux_dce100.c index e8d3781deaed028dbee299c3800b5cf7cb7162f3..8b704ab0471cd2cea6a3daacd8c945648354b427 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce100/i2caux_dce100.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce100/i2caux_dce100.c @@ -97,6 +97,7 @@ struct i2caux *dal_i2caux_dce100_create( dal_i2caux_dce110_construct(i2caux_dce110, ctx, + ARRAY_SIZE(dce100_aux_regs), dce100_aux_regs, dce100_hw_engine_regs, &i2c_shift, diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c index 2b927f25937b4f48ccf4abbe6a58a97017041f71..ae5caa97cacaf61049c07c448e9f454976097c9f 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c @@ -275,61 +275,92 @@ static void submit_channel_request( REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1); } -static void process_channel_reply( - struct aux_engine *engine, - struct aux_reply_transaction_data *reply) +static int read_channel_reply(struct aux_engine *engine, uint32_t size, + uint8_t *buffer, uint8_t *reply_result, + uint32_t *sw_status) { struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine); + uint32_t bytes_replied; + uint32_t reply_result_32; - /* Need to do a read to get the number of bytes to process - * Alternatively, this information can be passed - - * but that causes coupling which isn't good either. */ + *sw_status = REG_GET(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, + &bytes_replied); - uint32_t bytes_replied; - uint32_t value; + /* In case HPD is LOW, exit AUX transaction */ + if ((*sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) + return -1; - value = REG_GET(AUX_SW_STATUS, - AUX_SW_REPLY_BYTE_COUNT, &bytes_replied); + /* Need at least the status byte */ + if (!bytes_replied) + return -1; - /* in case HPD is LOW, exit AUX transaction */ - if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { - reply->status = AUX_TRANSACTION_REPLY_HPD_DISCON; - return; - } + REG_UPDATE_1BY1_3(AUX_SW_DATA, + AUX_SW_INDEX, 0, + AUX_SW_AUTOINCREMENT_DISABLE, 1, + AUX_SW_DATA_RW, 1); - if (bytes_replied) { - uint32_t reply_result; + REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32); + reply_result_32 = reply_result_32 >> 4; + *reply_result = (uint8_t)reply_result_32; - REG_UPDATE_1BY1_3(AUX_SW_DATA, - AUX_SW_INDEX, 0, - AUX_SW_AUTOINCREMENT_DISABLE, 1, - AUX_SW_DATA_RW, 1); + if (reply_result_32 == 0) { /* ACK */ + uint32_t i = 0; - REG_GET(AUX_SW_DATA, - AUX_SW_DATA, &reply_result); + /* First byte was already used to get the command status */ + --bytes_replied; - reply_result = reply_result >> 4; + /* Do not overflow buffer */ + if (bytes_replied > size) + return -1; - switch (reply_result) { - case 0: /* ACK */ { - uint32_t i = 0; + while (i < bytes_replied) { + uint32_t aux_sw_data_val; - /* first byte was already used - * to get the command status */ - --bytes_replied; + REG_GET(AUX_SW_DATA, AUX_SW_DATA, &aux_sw_data_val); + buffer[i] = aux_sw_data_val; + ++i; + } + + return i; + } + + return 0; +} + +static void process_channel_reply( + struct aux_engine *engine, + struct aux_reply_transaction_data *reply) +{ + int bytes_replied; + uint8_t reply_result; + uint32_t sw_status; - while (i < bytes_replied) { - uint32_t aux_sw_data_val; + bytes_replied = read_channel_reply(engine, reply->length, reply->data, + &reply_result, &sw_status); - REG_GET(AUX_SW_DATA, - AUX_SW_DATA, &aux_sw_data_val); + /* in case HPD is LOW, exit AUX transaction */ + if ((sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { + reply->status = AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; + return; + } - reply->data[i] = aux_sw_data_val; - ++i; - } + if (bytes_replied < 0) { + /* Need to handle an error case... + * Hopefully, upper layer function won't call this function if + * the number of bytes in the reply was 0, because there was + * surely an error that was asserted that should have been + * handled for hot plug case, this could happens + */ + if (!(sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { + reply->status = AUX_TRANSACTION_REPLY_INVALID; + ASSERT_CRITICAL(false); + return; + } + } else { + switch (reply_result) { + case 0: /* ACK */ reply->status = AUX_TRANSACTION_REPLY_AUX_ACK; - } break; case 1: /* NACK */ reply->status = AUX_TRANSACTION_REPLY_AUX_NACK; @@ -346,17 +377,6 @@ static void process_channel_reply( default: reply->status = AUX_TRANSACTION_REPLY_INVALID; } - } else { - /* Need to handle an error case... - * hopefully, upper layer function won't call this function - * if the number of bytes in the reply was 0 - * because there was surely an error that was asserted - * that should have been handled - * for hot plug case, this could happens*/ - if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { - reply->status = AUX_TRANSACTION_REPLY_INVALID; - ASSERT_CRITICAL(false); - } } } @@ -427,6 +447,7 @@ static const struct aux_engine_funcs aux_engine_funcs = { .acquire_engine = acquire_engine, .submit_channel_request = submit_channel_request, .process_channel_reply = process_channel_reply, + .read_channel_reply = read_channel_reply, .get_channel_status = get_channel_status, .is_engine_available = is_engine_available, }; diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c index b7256f595052b88a617a68213bd0eee8e4eb26b0..9cbe1a7a6bcb2c994b327c41bd68e151e10a14e6 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c @@ -62,12 +62,7 @@ enum dc_i2c_arbitration { DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_HIGH }; -enum { - /* No timeout in HW - * (timeout implemented in SW by querying status) */ - I2C_SETUP_TIME_LIMIT = 255, - I2C_HW_BUFFER_SIZE = 538 -}; + /* * @brief @@ -152,6 +147,11 @@ static bool setup_engine( struct i2c_engine *i2c_engine) { struct i2c_hw_engine_dce110 *hw_engine = FROM_I2C_ENGINE(i2c_engine); + uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE; + uint32_t reset_length = 0; + + if (hw_engine->base.base.setup_limit != 0) + i2c_setup_limit = hw_engine->base.base.setup_limit; /* Program pin select */ REG_UPDATE_6( @@ -164,11 +164,15 @@ static bool setup_engine( DC_I2C_DDC_SELECT, hw_engine->engine_id); /* Program time limit */ - REG_UPDATE_N( - SETUP, 2, - FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), I2C_SETUP_TIME_LIMIT, - FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1); - + if (hw_engine->base.base.send_reset_length == 0) { + /*pre-dcn*/ + REG_UPDATE_N( + SETUP, 2, + FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT), i2c_setup_limit, + FN(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE), 1); + } else { + reset_length = hw_engine->base.base.send_reset_length; + } /* Program HW priority * set to High - interrupt software I2C at any time * Enable restart of SW I2C that was interrupted by HW diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h index 5bb04085f670657b5c2d50aa3c6debc46ea059a8..fea2946906ed67682b1adde2194ff15c7051748e 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h @@ -192,6 +192,7 @@ struct i2c_hw_engine_dce110 { /* number of pending transactions (before GO) */ uint32_t transaction_count; uint32_t engine_keep_power_up_count; + uint32_t i2_setup_time_limit; }; struct i2c_hw_engine_dce110_create_arg { @@ -207,4 +208,11 @@ struct i2c_hw_engine_dce110_create_arg { struct i2c_engine *dal_i2c_hw_engine_dce110_create( const struct i2c_hw_engine_dce110_create_arg *arg); +enum { + I2C_SETUP_TIME_LIMIT_DCE = 255, + I2C_SETUP_TIME_LIMIT_DCN = 3, + I2C_HW_BUFFER_SIZE = 538, + I2C_SEND_RESET_LENGTH_9 = 9, + I2C_SEND_RESET_LENGTH_10 = 10, +}; #endif diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c index 2a047f8ca0e9ab3d9023204edc0b01167f8c26b8..1d748ac1d6d655e3cc8d36af03b96127f27115fb 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c @@ -43,6 +43,9 @@ #include "i2c_sw_engine_dce110.h" #include "i2c_hw_engine_dce110.h" #include "aux_engine_dce110.h" +#include "../../dc.h" +#include "dc_types.h" + /* * Post-requisites: headers required by this unit @@ -199,6 +202,7 @@ static const struct dce110_i2c_hw_engine_mask i2c_mask = { void dal_i2caux_dce110_construct( struct i2caux_dce110 *i2caux_dce110, struct dc_context *ctx, + unsigned int num_i2caux_inst, const struct dce110_aux_registers aux_regs[], const struct dce110_i2c_hw_engine_registers i2c_hw_engine_regs[], const struct dce110_i2c_hw_engine_shift *i2c_shift, @@ -249,9 +253,22 @@ void dal_i2caux_dce110_construct( base->i2c_hw_engines[line_id] = dal_i2c_hw_engine_dce110_create(&hw_arg_dce110); - + if (base->i2c_hw_engines[line_id] != NULL) { + switch (ctx->dce_version) { + case DCN_VERSION_1_0: + base->i2c_hw_engines[line_id]->setup_limit = + I2C_SETUP_TIME_LIMIT_DCN; + base->i2c_hw_engines[line_id]->send_reset_length = 0; + break; + default: + base->i2c_hw_engines[line_id]->setup_limit = + I2C_SETUP_TIME_LIMIT_DCE; + base->i2c_hw_engines[line_id]->send_reset_length = 0; + break; + } + } ++i; - } while (i < ARRAY_SIZE(hw_ddc_lines)); + } while (i < num_i2caux_inst); /* Create AUX engines for all lines which has assisted HW AUX * 'i' (loop counter) used as DDC/AUX engine_id */ @@ -272,7 +289,7 @@ void dal_i2caux_dce110_construct( dal_aux_engine_dce110_create(&aux_init_data); ++i; - } while (i < ARRAY_SIZE(hw_aux_lines)); + } while (i < num_i2caux_inst); /*TODO Generic I2C SW and HW*/ } @@ -303,6 +320,7 @@ struct i2caux *dal_i2caux_dce110_create( dal_i2caux_dce110_construct(i2caux_dce110, ctx, + ARRAY_SIZE(dce110_aux_regs), dce110_aux_regs, i2c_hw_engine_regs, &i2c_shift, diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.h b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.h index 1b1f71c60ac93baac87d3dae2926035b5a67628f..d3d8cc58666acb12b4cf4996794ac86e19d21bf7 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.h @@ -45,6 +45,7 @@ struct i2caux *dal_i2caux_dce110_create( void dal_i2caux_dce110_construct( struct i2caux_dce110 *i2caux_dce110, struct dc_context *ctx, + unsigned int num_i2caux_inst, const struct dce110_aux_registers *aux_regs, const struct dce110_i2c_hw_engine_registers *i2c_hw_engine_regs, const struct dce110_i2c_hw_engine_shift *i2c_shift, diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c index dafc1a727f7f9c0135cab912723e3d071c1ae74b..a9db047387245e351a9555d43774574b3681643a 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c @@ -93,6 +93,7 @@ static void construct( { dal_i2caux_dce110_construct(i2caux_dce110, ctx, + ARRAY_SIZE(dce112_aux_regs), dce112_aux_regs, dce112_hw_engine_regs, &i2c_shift, diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c index 0e7b1826002792dd930564625dad714e25508293..6a4f344c1db4945f25f80de0a831f7a95b6fa4b7 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c @@ -111,6 +111,7 @@ struct i2caux *dal_i2caux_dce120_create( dal_i2caux_dce110_construct(i2caux_dce110, ctx, + ARRAY_SIZE(dce120_aux_regs), dce120_aux_regs, dce120_hw_engine_regs, &i2c_shift, diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c b/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c index e44a8901f38bc7335716fa6189ee19413ced4995..a59c1f50c1e8eb84f15ad645ba1d62a375f1d6af 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c @@ -111,6 +111,7 @@ struct i2caux *dal_i2caux_dcn10_create( dal_i2caux_dce110_construct(i2caux_dce110, ctx, + ARRAY_SIZE(dcn10_aux_regs), dcn10_aux_regs, dcn10_hw_engine_regs, &i2c_shift, diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h b/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h index 58fc0f25ecebb68d1d7900cf58c620d5109aa9b1..ded6ea34b714cc81d9dd51aec780dd39f6a64c9d 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h +++ b/drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h @@ -86,6 +86,8 @@ struct i2c_engine { struct engine base; const struct i2c_engine_funcs *funcs; uint32_t timeout_delay; + uint32_t setup_limit; + uint32_t send_reset_length; }; void dal_i2c_engine_construct( diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c index 14dc8c94d862b049f7c5f7b760d91e201be8ac37..f7ed355fc84f44441563a8aea903477cf89ed5d9 100644 --- a/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c +++ b/drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c @@ -59,7 +59,7 @@ #include "dce120/i2caux_dce120.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "dcn10/i2caux_dcn10.h" #endif @@ -91,7 +91,7 @@ struct i2caux *dal_i2caux_create( return dal_i2caux_dce100_create(ctx); case DCE_VERSION_12_0: return dal_i2caux_dce120_create(ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 case DCN_VERSION_1_0: return dal_i2caux_dcn10_create(ctx); #endif @@ -254,7 +254,6 @@ bool dal_i2caux_submit_aux_command( break; } - cmd->payloads->length = request.payload.length; ++index_of_payload; } diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 00d728e629fa663b966bc7aa48f3c34b247736bc..4446652a9a9e4c68e6044bae89ae3db4a3d3402a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -33,7 +33,7 @@ #include "dc_bios_types.h" #include "mem_input.h" #include "hubp.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "mpc.h" #endif @@ -148,7 +148,6 @@ struct resource_pool { unsigned int underlay_pipe_index; unsigned int stream_enc_count; unsigned int ref_clock_inKhz; - unsigned int dentist_vco_freq_khz; unsigned int timing_generator_count; /* @@ -222,7 +221,7 @@ struct pipe_ctx { struct pipe_ctx *top_pipe; struct pipe_ctx *bottom_pipe; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 struct _vcs_dpi_display_dlg_regs_st dlg_regs; struct _vcs_dpi_display_ttu_regs_st ttu_regs; struct _vcs_dpi_display_rq_regs_st rq_regs; @@ -277,7 +276,7 @@ struct dc_state { /* Note: these are big structures, do *not* put on stack! */ struct dm_pp_display_configuration pp_display_cfg; -#ifdef CONFIG_DRM_AMD_DC_DCN1_0 +#ifdef CONFIG_X86 struct dcn_bw_internal_vars dcn_bw_vars; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h index 30b3a08b91be27dade29620cfc5dbf857c89bad1..538b83303b866e8f5a58b9b47751a3b6ace2578d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h @@ -102,22 +102,13 @@ bool dal_ddc_service_query_ddc_data( uint8_t *read_buf, uint32_t read_size); -enum ddc_result dal_ddc_service_read_dpcd_data( - struct ddc_service *ddc, - bool i2c, - enum i2c_mot_mode mot, - uint32_t address, - uint8_t *data, - uint32_t len, - uint32_t *read); - -enum ddc_result dal_ddc_service_write_dpcd_data( - struct ddc_service *ddc, - bool i2c, - enum i2c_mot_mode mot, - uint32_t address, - const uint8_t *data, - uint32_t len); +int dc_link_aux_transfer(struct ddc_service *ddc, + unsigned int address, + uint8_t *reply, + void *buffer, + unsigned int size, + enum aux_transaction_type type, + enum i2caux_transaction_action action); void dal_ddc_service_write_scdc_data( struct ddc_service *ddc_service, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h index 582458f028f8479f52951ac1948f3101e2abb8e8..74ad94b0e4f088cd5c0cc14a2fe3d90fcc3fe9b8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -151,6 +151,9 @@ struct dpp_funcs { void (*dpp_set_hdr_multiplier)( struct dpp *dpp_base, uint32_t multiplier); + void (*set_optional_cursor_attributes)( + struct dpp *dpp_base, + struct dpp_cursor_attributes *attr); void (*dpp_dppclk_control)( struct dpp *dpp_base, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index 97df82cddf829c0f8954053835b21f75baf23999..4f3f9e68ccfa46426b65d43149019fe53b04f5be 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -43,10 +43,9 @@ enum cursor_lines_per_chunk { }; struct hubp { - struct hubp_funcs *funcs; + const struct hubp_funcs *funcs; struct dc_context *ctx; struct dc_plane_address request_address; - struct dc_plane_address current_address; int inst; /* run time states */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h index 47f1dc5a43b74ffab7b429e1d5975a2b07fa8f3d..da89c2edb07c758034d640045201465833dfa245 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h @@ -64,7 +64,7 @@ struct stutter_modes { }; struct mem_input { - struct mem_input_funcs *funcs; + const struct mem_input_funcs *funcs; struct dc_context *ctx; struct dc_plane_address request_address; struct dc_plane_address current_address; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 2506601120afab6ec9f895b48e837a41c616fdb5..a14ce4de80b264856f73ad20236f5844aa9005c9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -102,10 +102,18 @@ struct hw_sequencer_funcs { const struct dc *dc, struct pipe_ctx *pipe_ctx); + void (*plane_atomic_disconnect)( + struct dc *dc, + struct pipe_ctx *pipe_ctx); + void (*update_dchub)( struct dce_hwseq *hws, struct dchub_init_data *dh_data); + void (*update_mpcc)( + struct dc *dc, + struct pipe_ctx *pipe_ctx); + void (*update_pending_status)( struct pipe_ctx *pipe_ctx); @@ -215,6 +223,7 @@ struct hw_sequencer_funcs { void (*set_cursor_position)(struct pipe_ctx *pipe); void (*set_cursor_attribute)(struct pipe_ctx *pipe); + void (*set_cursor_sdr_white_level)(struct pipe_ctx *pipe); }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h index 3306e7b0b3e344960dbeb99633cd05209184a952..cf5a84b9e27c44691938bb381fcee20b1923cd9b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h +++ b/drivers/gpu/drm/amd/display/dc/inc/reg_helper.h @@ -445,4 +445,50 @@ uint32_t generic_reg_get8(const struct dc_context *ctx, uint32_t addr, uint8_t shift6, uint32_t mask6, uint32_t *field_value6, uint8_t shift7, uint32_t mask7, uint32_t *field_value7, uint8_t shift8, uint32_t mask8, uint32_t *field_value8); + + +/* indirect register access */ + +#define IX_REG_SET_N(index_reg_name, data_reg_name, index, n, initial_val, ...) \ + generic_indirect_reg_update_ex(CTX, \ + REG(index_reg_name), REG(data_reg_name), IND_REG(index), \ + initial_val, \ + n, __VA_ARGS__) + +#define IX_REG_SET_2(index_reg_name, data_reg_name, index, init_value, f1, v1, f2, v2) \ + IX_REG_SET_N(index_reg_name, data_reg_name, index, 2, init_value, \ + FN(reg, f1), v1,\ + FN(reg, f2), v2) + + +#define IX_REG_READ(index_reg_name, data_reg_name, index) \ + generic_read_indirect_reg(CTX, REG(index_reg_name), REG(data_reg_name), IND_REG(index)) + + + +#define IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, n, ...) \ + generic_indirect_reg_update_ex(CTX, \ + REG(index_reg_name), REG(data_reg_name), IND_REG(index), \ + IX_REG_READ(index_reg_name, data_reg_name, index), \ + n, __VA_ARGS__) + +#define IX_REG_UPDATE_2(index_reg_name, data_reg_name, index, f1, v1, f2, v2) \ + IX_REG_UPDATE_N(index_reg_name, data_reg_name, index, 2,\ + FN(reg, f1), v1,\ + FN(reg, f2), v2) + +void generic_write_indirect_reg(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index, uint32_t data); + +uint32_t generic_read_indirect_reg(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index); + +uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx, + uint32_t addr_index, uint32_t addr_data, + uint32_t index, uint32_t reg_val, int n, + uint8_t shift1, uint32_t mask1, uint32_t field_value1, + ...); + #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_REG_HELPER_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile index 498515aad4a50bf35133755d1bded3a387a0817e..a76ee600eceeae72befe641578fd2c6032432647 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/Makefile +++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile @@ -60,7 +60,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCE12) ############################################################################### # DCN 1x ############################################################################### -ifdef CONFIG_DRM_AMD_DC_DCN1_0 +ifdef CONFIG_X86 IRQ_DCN1 = irq_service_dcn10.o AMD_DAL_IRQ_DCN1 = $(addprefix $(AMDDALPATH)/dc/irq/dcn10/,$(IRQ_DCN1)) diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c index 604bea01fc13ee5eea9840d238d0fbcc98eec113..ae3fd0a235ba45ce900fe6b0aeba7354b7b847cf 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c @@ -36,7 +36,7 @@ #include "dce120/irq_service_dce120.h" -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include "dcn10/irq_service_dcn10.h" #endif diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h index a407892905af29661a70ad75a6c76c5d502163c3..c9fce9066ad8b43b970c450c25690b3d5bb9096b 100644 --- a/drivers/gpu/drm/amd/display/dc/os_types.h +++ b/drivers/gpu/drm/amd/display/dc/os_types.h @@ -48,7 +48,7 @@ #define dm_error(fmt, ...) DRM_ERROR(fmt, ##__VA_ARGS__) -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) +#ifdef CONFIG_X86 #include <asm/fpu/api.h> #endif diff --git a/drivers/gpu/drm/amd/display/include/dpcd_defs.h b/drivers/gpu/drm/amd/display/include/dpcd_defs.h index d8e52e3b8e3c7bb72f5778f7b6650df80043023f..1c66166d0a949257ac262c0c236452cc431f99e9 100644 --- a/drivers/gpu/drm/amd/display/include/dpcd_defs.h +++ b/drivers/gpu/drm/amd/display/include/dpcd_defs.h @@ -27,6 +27,9 @@ #define __DAL_DPCD_DEFS_H__ #include <drm/drm_dp_helper.h> +#ifndef DP_SINK_HW_REVISION_START // can remove this once the define gets into linux drm_dp_helper.h +#define DP_SINK_HW_REVISION_START 0x409 +#endif enum dpcd_revision { DPCD_REV_10 = 0x10, diff --git a/drivers/gpu/drm/amd/display/include/logger_interface.h b/drivers/gpu/drm/amd/display/include/logger_interface.h index 0f10ed710e0d0e943c0af310dc6adb587bd56371..e3c79616682dca79e6c06e55900550859e6daab4 100644 --- a/drivers/gpu/drm/amd/display/include/logger_interface.h +++ b/drivers/gpu/drm/amd/display/include/logger_interface.h @@ -40,49 +40,7 @@ struct dc_state; * */ -struct dal_logger *dal_logger_create(struct dc_context *ctx, uint32_t log_mask); - -uint32_t dal_logger_destroy(struct dal_logger **logger); - -void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn); - -void dm_logger_write( - struct dal_logger *logger, - enum dc_log_type log_type, - const char *msg, - ...); - -void dm_logger_append( - struct log_entry *entry, - const char *msg, - ...); - -void dm_logger_append_va( - struct log_entry *entry, - const char *msg, - va_list args); - -void dm_logger_append_heading(struct log_entry *entry); - -void dm_logger_open( - struct dal_logger *logger, - struct log_entry *entry, - enum dc_log_type log_type); - -void dm_logger_close(struct log_entry *entry); - -void dc_conn_log(struct dc_context *ctx, - const struct dc_link *link, - uint8_t *hex_data, - int hex_data_count, - enum dc_log_type event, - const char *msg, - ...); - -void logger_write(struct dal_logger *logger, - enum dc_log_type log_type, - const char *msg, - void *paralist); +void dc_conn_log_hex_linux(const uint8_t *hex_data, int hex_data_count); void pre_surface_trace( struct dc *dc, @@ -108,28 +66,31 @@ void context_clock_trace( * marked by this macro. * Note that the message will be printed exactly once for every function * it is used in order to avoid repeating of the same message. */ + #define DAL_LOGGER_NOT_IMPL(fmt, ...) \ -{ \ - static bool print_not_impl = true; \ -\ - if (print_not_impl == true) { \ - print_not_impl = false; \ - dm_logger_write(ctx->logger, LOG_WARNING, \ - "DAL_NOT_IMPL: " fmt, ##__VA_ARGS__); \ - } \ -} + do { \ + static bool print_not_impl = true; \ + if (print_not_impl == true) { \ + print_not_impl = false; \ + DRM_WARN("DAL_NOT_IMPL: " fmt, ##__VA_ARGS__); \ + } \ + } while (0) /****************************************************************************** * Convenience macros to save on typing. *****************************************************************************/ #define DC_ERROR(...) \ - dm_logger_write(dc_ctx->logger, LOG_ERROR, \ - __VA_ARGS__) + do { \ + (void)(dc_ctx); \ + DC_LOG_ERROR(__VA_ARGS__); \ + } while (0) #define DC_SYNC_INFO(...) \ - dm_logger_write(dc_ctx->logger, LOG_SYNC, \ - __VA_ARGS__) + do { \ + (void)(dc_ctx); \ + DC_LOG_SYNC(__VA_ARGS__); \ + } while (0) /* Connectivity log format: * [time stamp] [drm] [Major_minor] [connector name] message..... @@ -139,20 +100,30 @@ void context_clock_trace( */ #define CONN_DATA_DETECT(link, hex_data, hex_len, ...) \ - dc_conn_log(link->ctx, link, hex_data, hex_len, \ - LOG_EVENT_DETECTION, ##__VA_ARGS__) + do { \ + (void)(link); \ + dc_conn_log_hex_linux(hex_data, hex_len); \ + DC_LOG_EVENT_DETECTION(__VA_ARGS__); \ + } while (0) #define CONN_DATA_LINK_LOSS(link, hex_data, hex_len, ...) \ - dc_conn_log(link->ctx, link, hex_data, hex_len, \ - LOG_EVENT_LINK_LOSS, ##__VA_ARGS__) + do { \ + (void)(link); \ + dc_conn_log_hex_linux(hex_data, hex_len); \ + DC_LOG_EVENT_LINK_LOSS(__VA_ARGS__); \ + } while (0) #define CONN_MSG_LT(link, ...) \ - dc_conn_log(link->ctx, link, NULL, 0, \ - LOG_EVENT_LINK_TRAINING, ##__VA_ARGS__) + do { \ + (void)(link); \ + DC_LOG_EVENT_LINK_TRAINING(__VA_ARGS__); \ + } while (0) #define CONN_MSG_MODE(link, ...) \ - dc_conn_log(link->ctx, link, NULL, 0, \ - LOG_EVENT_MODE_SET, ##__VA_ARGS__) + do { \ + (void)(link); \ + DC_LOG_EVENT_MODE_SET(__VA_ARGS__); \ + } while (0) /* * Display Test Next logging @@ -167,38 +138,21 @@ void context_clock_trace( dm_dtn_log_end(dc_ctx) #define PERFORMANCE_TRACE_START() \ - unsigned long long perf_trc_start_stmp = dm_get_timestamp(dc->ctx); \ - unsigned long long perf_trc_start_log_msk = dc->ctx->logger->mask; \ - unsigned int perf_trc_start_log_flags = dc->ctx->logger->flags.value; \ - if (dc->debug.performance_trace) {\ - dm_logger_flush_buffer(dc->ctx->logger, false);\ - dc->ctx->logger->mask = 1<<LOG_PERF_TRACE;\ - dc->ctx->logger->flags.bits.ENABLE_CONSOLE = 0;\ - dc->ctx->logger->flags.bits.ENABLE_BUFFER = 1;\ - } - -#define PERFORMANCE_TRACE_END() do {\ - unsigned long long perf_trc_end_stmp = dm_get_timestamp(dc->ctx);\ - if (dc->debug.performance_trace) {\ - dm_logger_write(dc->ctx->logger, \ - LOG_PERF_TRACE, \ - "%s duration: %d ticks\n", __func__,\ + unsigned long long perf_trc_start_stmp = dm_get_timestamp(dc->ctx) + +#define PERFORMANCE_TRACE_END() \ + do { \ + unsigned long long perf_trc_end_stmp = dm_get_timestamp(dc->ctx); \ + if (dc->debug.performance_trace) { \ + DC_LOG_PERF_TRACE("%s duration: %lld ticks\n", __func__, \ perf_trc_end_stmp - perf_trc_start_stmp); \ - if (perf_trc_start_log_msk != 1<<LOG_PERF_TRACE) {\ - dc->ctx->logger->mask = perf_trc_start_log_msk;\ - dc->ctx->logger->flags.value = perf_trc_start_log_flags;\ - dm_logger_flush_buffer(dc->ctx->logger, false);\ } \ - } \ -} while (0) + } while (0) -#define DISPLAY_STATS_BEGIN(entry) \ - dm_logger_open(dc->ctx->logger, &entry, LOG_DISPLAYSTATS) +#define DISPLAY_STATS_BEGIN(entry) (void)(entry) -#define DISPLAY_STATS(msg, ...) \ - dm_logger_append(&log_entry, msg, ##__VA_ARGS__) +#define DISPLAY_STATS(msg, ...) DC_LOG_PERF_TRACE(msg, __VA_ARGS__) -#define DISPLAY_STATS_END(entry) \ - dm_logger_close(&entry) +#define DISPLAY_STATS_END(entry) (void)(entry) #endif /* __DAL_LOGGER_INTERFACE_H__ */ diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h index 0a540b9897a6798169f56e0b6a763042e1faccf0..ad3695e67b76feb866c0132e043c70b8a0b294cb 100644 --- a/drivers/gpu/drm/amd/display/include/logger_types.h +++ b/drivers/gpu/drm/amd/display/include/logger_types.h @@ -138,63 +138,4 @@ enum dc_log_type { (1 << LOG_HW_AUDIO)| \ (1 << LOG_BANDWIDTH_CALCS)*/ -union logger_flags { - struct { - uint32_t ENABLE_CONSOLE:1; /* Print to console */ - uint32_t ENABLE_BUFFER:1; /* Print to buffer */ - uint32_t RESERVED:30; - } bits; - uint32_t value; -}; - -struct log_entry { - struct dal_logger *logger; - enum dc_log_type type; - - char *buf; - uint32_t buf_offset; - uint32_t max_buf_bytes; -}; - -/** -* Structure for enumerating log types -*/ -struct dc_log_type_info { - enum dc_log_type type; - char name[MAX_NAME_LEN]; -}; - -/* Structure for keeping track of offsets, buffer, etc */ - -#define DAL_LOGGER_BUFFER_MAX_SIZE 2048 - -/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes, - * change log line size to 896 to meet the request. - */ -#define LOG_MAX_LINE_SIZE 896 - -struct dal_logger { - - /* How far into the circular buffer has been read by dsat - * Read offset should never cross write offset. Write \0's to - * read data just to be sure? - */ - uint32_t buffer_read_offset; - - /* How far into the circular buffer we have written - * Write offset should never cross read offset - */ - uint32_t buffer_write_offset; - - uint32_t open_count; - - char *log_buffer; /* Pointer to malloc'ed buffer */ - uint32_t log_buffer_size; /* Size of circular buffer */ - - uint32_t mask; /*array of masks for major elements*/ - - union logger_flags flags; - struct dc_context *ctx; -}; - #endif /* __DAL_LOGGER_TYPES_H__ */ diff --git a/drivers/gpu/drm/amd/display/modules/color/luts_1d.h b/drivers/gpu/drm/amd/display/modules/color/luts_1d.h new file mode 100644 index 0000000000000000000000000000000000000000..66b1fad572ace8cb3e8486fdfefc102a02e1e98a --- /dev/null +++ b/drivers/gpu/drm/amd/display/modules/color/luts_1d.h @@ -0,0 +1,51 @@ +/* + * Copyright 2016 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ +#ifndef LUTS_1D_H +#define LUTS_1D_H + +#include "hw_shared.h" + +struct point_config { + uint32_t custom_float_x; + uint32_t custom_float_y; + uint32_t custom_float_slope; +}; + +struct lut_point { + uint32_t red; + uint32_t green; + uint32_t blue; + uint32_t delta_red; + uint32_t delta_green; + uint32_t delta_blue; +}; + +struct pwl_1dlut_parameter { + struct gamma_curve arr_curve_points[34]; + struct point_config arr_points[2]; + struct lut_point rgb_resulted[256]; + uint32_t hw_points_num; +}; +#endif // LUTS_1D_H diff --git a/drivers/gpu/drm/amd/include/ivsrcid/gfx/irqsrcs_gfx_9_0.h b/drivers/gpu/drm/amd/include/ivsrcid/gfx/irqsrcs_gfx_9_0.h new file mode 100644 index 0000000000000000000000000000000000000000..36306c57a2b418573a4afea85367e63541dc8c4d --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/gfx/irqsrcs_gfx_9_0.h @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_GFX_9_0_H__ +#define __IRQSRCS_GFX_9_0_H__ + + +#define GFX_9_0__SRCID__CP_RB_INTERRUPT_PKT 176 /* B0 CP_INTERRUPT pkt in RB */ +#define GFX_9_0__SRCID__CP_IB1_INTERRUPT_PKT 177 /* B1 CP_INTERRUPT pkt in IB1 */ +#define GFX_9_0__SRCID__CP_IB2_INTERRUPT_PKT 178 /* B2 CP_INTERRUPT pkt in IB2 */ +#define GFX_9_0__SRCID__CP_PM4_PKT_RSVD_BIT_ERROR 180 /* B4 PM4 Pkt Rsvd Bits Error */ +#define GFX_9_0__SRCID__CP_EOP_INTERRUPT 181 /* B5 End-of-Pipe Interrupt */ +#define GFX_9_0__SRCID__CP_BAD_OPCODE_ERROR 183 /* B7 Bad Opcode Error */ +#define GFX_9_0__SRCID__CP_PRIV_REG_FAULT 184 /* B8 Privileged Register Fault */ +#define GFX_9_0__SRCID__CP_PRIV_INSTR_FAULT 185 /* B9 Privileged Instr Fault */ +#define GFX_9_0__SRCID__CP_WAIT_MEM_SEM_FAULT 186 /* BA Wait Memory Semaphore Fault (Synchronization Object Fault) */ +#define GFX_9_0__SRCID__CP_CTX_EMPTY_INTERRUPT 187 /* BB Context Empty Interrupt */ +#define GFX_9_0__SRCID__CP_CTX_BUSY_INTERRUPT 188 /* BC Context Busy Interrupt */ +#define GFX_9_0__SRCID__CP_ME_WAIT_REG_MEM_POLL_TIMEOUT 192 /* C0 CP.ME Wait_Reg_Mem Poll Timeout */ +#define GFX_9_0__SRCID__CP_SIG_INCOMPLETE 193 /* C1 "Surface Probe Fault Signal Incomplete" */ +#define GFX_9_0__SRCID__CP_PREEMPT_ACK 194 /* C2 Preemption Ack-wledge */ +#define GFX_9_0__SRCID__CP_GPF 195 /* C3 General Protection Fault (GPF) */ +#define GFX_9_0__SRCID__CP_GDS_ALLOC_ERROR 196 /* C4 GDS Alloc Error */ +#define GFX_9_0__SRCID__CP_ECC_ERROR 197 /* C5 ECC Error */ +#define GFX_9_0__SRCID__CP_COMPUTE_QUERY_STATUS 199 /* C7 Compute query status */ +#define GFX_9_0__SRCID__CP_VM_DOORBELL 200 /* C8 Unattached VM Doorbell Received */ +#define GFX_9_0__SRCID__CP_FUE_ERROR 201 /* C9 ECC FUE Error */ +#define GFX_9_0__SRCID__RLC_STRM_PERF_MONITOR_INTERRUPT 202 /* CA Streaming Perf Monitor Interrupt */ +#define GFX_9_0__SRCID__GRBM_RD_TIMEOUT_ERROR 232 /* E8 CRead timeout error */ +#define GFX_9_0__SRCID__GRBM_REG_GUI_IDLE 233 /* E9 Register GUI Idle */ +#define GFX_9_0__SRCID__SQ_INTERRUPT_ID 239 /* EF SQ Interrupt (ttrace wrap, errors) */ + +#endif /* __IRQSRCS_GFX_9_0_H__ */ diff --git a/drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h b/drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h index c6b6f97de9de5951b301825b6b36f9ad8171699b..aaed7f59e0e23395418bb24d5114b2d7d3de246e 100644 --- a/drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h +++ b/drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h @@ -198,4 +198,102 @@ #define VISLANDS30_IV_SRCID_HPD_RX_F 42 // 0x2a #define VISLANDS30_IV_EXTID_HPD_RX_F 11 +#define VISLANDS30_IV_SRCID_GPIO_19 0x00000053 /* 83 */ + +#define VISLANDS30_IV_SRCID_SRBM_READ_TIMEOUT_ERR 0x00000060 /* 96 */ +#define VISLANDS30_IV_SRCID_SRBM_CTX_SWITCH 0x00000061 /* 97 */ + +#define VISLANDS30_IV_SRBM_REG_ACCESS_ERROR 0x00000062 /* 98 */ + + +#define VISLANDS30_IV_SRCID_UVD_ENC_GEN_PURP 0x00000077 /* 119 */ +#define VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE 0x0000007c /* 124 */ + +#define VISLANDS30_IV_SRCID_BIF_PF_VF_MSGBUF_VALID 0x00000087 /* 135 */ + +#define VISLANDS30_IV_SRCID_BIF_VF_PF_MSGBUF_ACK 0x0000008a /* 138 */ + +#define VISLANDS30_IV_SRCID_SYS_PAGE_INV_FAULT 0x0000008c /* 140 */ +#define VISLANDS30_IV_SRCID_SYS_MEM_PROT_FAULT 0x0000008d /* 141 */ + +#define VISLANDS30_IV_SRCID_SEM_PAGE_INV_FAULT 0x00000090 /* 144 */ +#define VISLANDS30_IV_SRCID_SEM_MEM_PROT_FAULT 0x00000091 /* 145 */ + +#define VISLANDS30_IV_SRCID_GFX_PAGE_INV_FAULT 0x00000092 /* 146 */ +#define VISLANDS30_IV_SRCID_GFX_MEM_PROT_FAULT 0x00000093 /* 147 */ + +#define VISLANDS30_IV_SRCID_ACP 0x000000a2 /* 162 */ + +#define VISLANDS30_IV_SRCID_VCE_TRAP 0x000000a7 /* 167 */ +#define VISLANDS30_IV_EXTID_VCE_TRAP_GENERAL_PURPOSE 0 +#define VISLANDS30_IV_EXTID_VCE_TRAP_LOW_LATENCY 1 +#define VISLANDS30_IV_EXTID_VCE_TRAP_REAL_TIME 2 + +#define VISLANDS30_IV_SRCID_CP_INT_RB 0x000000b0 /* 176 */ +#define VISLANDS30_IV_SRCID_CP_INT_IB1 0x000000b1 /* 177 */ +#define VISLANDS30_IV_SRCID_CP_INT_IB2 0x000000b2 /* 178 */ +#define VISLANDS30_IV_SRCID_CP_PM4_RES_BITS_ERR 0x000000b4 /* 180 */ +#define VISLANDS30_IV_SRCID_CP_END_OF_PIPE 0x000000b5 /* 181 */ +#define VISLANDS30_IV_SRCID_CP_BAD_OPCODE 0x000000b7 /* 183 */ +#define VISLANDS30_IV_SRCID_CP_PRIV_REG_FAULT 0x000000b8 /* 184 */ +#define VISLANDS30_IV_SRCID_CP_PRIV_INSTR_FAULT 0x000000b9 /* 185 */ +#define VISLANDS30_IV_SRCID_CP_WAIT_MEM_SEM_FAULT 0x000000ba /* 186 */ +#define VISLANDS30_IV_SRCID_CP_GUI_IDLE 0x000000bb /* 187 */ +#define VISLANDS30_IV_SRCID_CP_GUI_BUSY 0x000000bc /* 188 */ + +#define VISLANDS30_IV_SRCID_CP_COMPUTE_QUERY_STATUS 0x000000bf /* 191 */ +#define VISLANDS30_IV_SRCID_CP_ECC_ERROR 0x000000c5 /* 197 */ + +#define CARRIZO_IV_SRCID_CP_COMPUTE_QUERY_STATUS 0x000000c7 /* 199 */ + +#define VISLANDS30_IV_SRCID_CP_WAIT_REG_MEM_POLL_TIMEOUT 0x000000c0 /* 192 */ +#define VISLANDS30_IV_SRCID_CP_SEM_SIG_INCOMPL 0x000000c1 /* 193 */ +#define VISLANDS30_IV_SRCID_CP_PREEMPT_ACK 0x000000c2 /* 194 */ +#define VISLANDS30_IV_SRCID_CP_GENERAL_PROT_FAULT 0x000000c3 /* 195 */ +#define VISLANDS30_IV_SRCID_CP_GDS_ALLOC_ERROR 0x000000c4 /* 196 */ +#define VISLANDS30_IV_SRCID_CP_ECC_ERROR 0x000000c5 /* 197 */ + +#define VISLANDS30_IV_SRCID_RLC_STRM_PERF_MONITOR 0x000000ca /* 202 */ + +#define VISLANDS30_IV_SDMA_ATOMIC_SRC_ID 0x000000da /* 218 */ + +#define VISLANDS30_IV_SRCID_SDMA_ECC_ERROR 0x000000dc /* 220 */ + +#define VISLANDS30_IV_SRCID_SDMA_TRAP 0x000000e0 /* 224 */ +#define VISLANDS30_IV_SRCID_SDMA_SEM_INCOMPLETE 0x000000e1 /* 225 */ +#define VISLANDS30_IV_SRCID_SDMA_SEM_WAIT 0x000000e2 /* 226 */ + + +#define VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER 0x000000e5 /* 229 */ + +#define VISLANDS30_IV_SRCID_CG_TSS_THERMAL_LOW_TO_HIGH 0x000000e6 /* 230 */ +#define VISLANDS30_IV_SRCID_CG_TSS_THERMAL_HIGH_TO_LOW 0x000000e7 /* 231 */ + +#define VISLANDS30_IV_SRCID_GRBM_READ_TIMEOUT_ERR 0x000000e8 /* 232 */ +#define VISLANDS30_IV_SRCID_GRBM_REG_GUI_IDLE 0x000000e9 /* 233 */ + +#define VISLANDS30_IV_SRCID_SQ_INTERRUPT_MSG 0x000000ef /* 239 */ + +#define VISLANDS30_IV_SRCID_SDMA_PREEMPT 0x000000f0 /* 240 */ +#define VISLANDS30_IV_SRCID_SDMA_VM_HOLE 0x000000f2 /* 242 */ +#define VISLANDS30_IV_SRCID_SDMA_CTXEMPTY 0x000000f3 /* 243 */ +#define VISLANDS30_IV_SRCID_SDMA_DOORBELL_INVALID 0x000000f4 /* 244 */ +#define VISLANDS30_IV_SRCID_SDMA_FROZEN 0x000000f5 /* 245 */ +#define VISLANDS30_IV_SRCID_SDMA_POLL_TIMEOUT 0x000000f6 /* 246 */ +#define VISLANDS30_IV_SRCID_SDMA_SRBM_WRITE 0x000000f7 /* 247 */ + +#define VISLANDS30_IV_SRCID_CG_THERMAL_TRIG 0x000000f8 /* 248 */ + +#define VISLANDS30_IV_SRCID_SMU_DISP_TIMER_TRIGGER 0x000000fd /* 253 */ + +/* These are not "real" source ids defined by HW */ +#define VISLANDS30_IV_SRCID_VM_CONTEXT_ALL 0x00000100 /* 256 */ +#define VISLANDS30_IV_EXTID_VM_CONTEXT0_ALL 0 +#define VISLANDS30_IV_EXTID_VM_CONTEXT1_ALL 1 + + +/* IV Extended IDs */ +#define VISLANDS30_IV_EXTID_NONE 0x00000000 +#define VISLANDS30_IV_EXTID_INVALID 0xffffffff + #endif // _IVSRCID_VISLANDS30_H_ diff --git a/drivers/gpu/drm/amd/include/ivsrcid/sdma0/irqsrcs_sdma0_4_0.h b/drivers/gpu/drm/amd/include/ivsrcid/sdma0/irqsrcs_sdma0_4_0.h new file mode 100644 index 0000000000000000000000000000000000000000..802413832fe80f1e93d358fcb2979da5e4de4522 --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/sdma0/irqsrcs_sdma0_4_0.h @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_SDMA0_4_0_H__ +#define __IRQSRCS_SDMA0_4_0_H__ + +#define SDMA0_4_0__SRCID__SDMA_ATOMIC_RTN_DONE 217 /* 0xD9 SDMA atomic*_rtn ops complete */ +#define SDMA0_4_0__SRCID__SDMA_ATOMIC_TIMEOUT 218 /* 0xDA SDMA atomic CMPSWAP loop timeout */ +#define SDMA0_4_0__SRCID__SDMA_IB_PREEMPT 219 /* 0xDB sdma mid-command buffer preempt interrupt */ +#define SDMA0_4_0__SRCID__SDMA_ECC 220 /* 0xDC ECC Error */ +#define SDMA0_4_0__SRCID__SDMA_PAGE_FAULT 221 /* 0xDD Page Fault Error from UTCL2 when nack=3 */ +#define SDMA0_4_0__SRCID__SDMA_PAGE_NULL 222 /* 0xDE Page Null from UTCL2 when nack=2 */ +#define SDMA0_4_0__SRCID__SDMA_XNACK 223 /* 0xDF Page retry timeout after UTCL2 return nack=1 */ +#define SDMA0_4_0__SRCID__SDMA_TRAP 224 /* 0xE0 Trap */ +#define SDMA0_4_0__SRCID__SDMA_SEM_INCOMPLETE_TIMEOUT 225 /* 0xE1 0xDAGPF (Sem incomplete timeout) */ +#define SDMA0_4_0__SRCID__SDMA_SEM_WAIT_FAIL_TIMEOUT 226 /* 0xE2 Semaphore wait fail timeout */ +#define SDMA0_4_0__SRCID__SDMA_SRAM_ECC 228 /* 0xE4 SRAM ECC Error */ +#define SDMA0_4_0__SRCID__SDMA_PREEMPT 240 /* 0xF0 SDMA New Run List */ +#define SDMA0_4_0__SRCID__SDMA_VM_HOLE 242 /* 0xF2 MC or SEM address in VM hole */ +#define SDMA0_4_0__SRCID__SDMA_CTXEMPTY 243 /* 0xF3 Context Empty */ +#define SDMA0_4_0__SRCID__SDMA_DOORBELL_INVALID 244 /* 0xF4 Doorbell BE invalid */ +#define SDMA0_4_0__SRCID__SDMA_FROZEN 245 /* 0xF5 SDMA Frozen */ +#define SDMA0_4_0__SRCID__SDMA_POLL_TIMEOUT 246 /* 0xF6 SRBM read poll timeout */ +#define SDMA0_4_0__SRCID__SDMA_SRBMWRITE 247 /* 0xF7 SRBM write Protection */ + +#endif /* __IRQSRCS_SDMA_4_0_H__ */ + + diff --git a/drivers/gpu/drm/amd/include/ivsrcid/sdma1/irqsrcs_sdma1_4_0.h b/drivers/gpu/drm/amd/include/ivsrcid/sdma1/irqsrcs_sdma1_4_0.h new file mode 100644 index 0000000000000000000000000000000000000000..d12a35619f9aa2b5353f24f70ccc4e8ff6b74e45 --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/sdma1/irqsrcs_sdma1_4_0.h @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_SDMA1_4_0_H__ +#define __IRQSRCS_SDMA1_4_0_H__ + +#define SDMA1_4_0__SRCID__SDMA_ATOMIC_RTN_DONE 217 /* 0xD9 SDMA atomic*_rtn ops complete */ +#define SDMA1_4_0__SRCID__SDMA_ATOMIC_TIMEOUT 218 /* 0xDA SDMA atomic CMPSWAP loop timeout */ +#define SDMA1_4_0__SRCID__SDMA_IB_PREEMPT 219 /* 0xDB sdma mid-command buffer preempt interrupt */ +#define SDMA1_4_0__SRCID__SDMA_ECC 220 /* 0xDC ECC Error */ +#define SDMA1_4_0__SRCID__SDMA_PAGE_FAULT 221 /* 0xDD Page Fault Error from UTCL2 when nack=3 */ +#define SDMA1_4_0__SRCID__SDMA_PAGE_NULL 222 /* 0xDE Page Null from UTCL2 when nack=2 */ +#define SDMA1_4_0__SRCID__SDMA_XNACK 223 /* 0xDF Page retry timeout after UTCL2 return nack=1 */ +#define SDMA1_4_0__SRCID__SDMA_TRAP 224 /* 0xE0 Trap */ +#define SDMA1_4_0__SRCID__SDMA_SEM_INCOMPLETE_TIMEOUT 225 /* 0xE1 0xDAGPF (Sem incomplete timeout) */ +#define SDMA1_4_0__SRCID__SDMA_SEM_WAIT_FAIL_TIMEOUT 226 /* 0xE2 Semaphore wait fail timeout */ +#define SDMA1_4_0__SRCID__SDMA_SRAM_ECC 228 /* 0xE4 SRAM ECC Error */ +#define SDMA1_4_0__SRCID__SDMA_PREEMPT 240 /* 0xF0 SDMA New Run List */ +#define SDMA1_4_0__SRCID__SDMA_VM_HOLE 242 /* 0xF2 MC or SEM address in VM hole */ +#define SDMA1_4_0__SRCID__SDMA_CTXEMPTY 243 /* 0xF3 Context Empty */ +#define SDMA1_4_0__SRCID__SDMA_DOORBELL_INVALID 244 /* 0xF4 Doorbell BE invalid */ +#define SDMA1_4_0__SRCID__SDMA_FROZEN 245 /* 0xF5 SDMA Frozen */ +#define SDMA1_4_0__SRCID__SDMA_POLL_TIMEOUT 246 /* 0xF6 SRBM read poll timeout */ +#define SDMA1_4_0__SRCID__SDMA_SRBMWRITE 247 /* 0xF7 SRBM write Protection */ + +#endif /* __IRQSRCS_SDMA1_4_0_H__ */ + + diff --git a/drivers/gpu/drm/amd/include/ivsrcid/smuio/irqsrcs_smuio_9_0.h b/drivers/gpu/drm/amd/include/ivsrcid/smuio/irqsrcs_smuio_9_0.h new file mode 100644 index 0000000000000000000000000000000000000000..02bab4673cd4e0d6b9ea813476db5dd08a567ea4 --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/smuio/irqsrcs_smuio_9_0.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_SMUIO_9_0_H__ +#define __IRQSRCS_SMUIO_9_0_H__ + +#define SMUIO_9_0__SRCID__SMUIO_GPIO19 83 /* GPIO19 interrupt */ + +#endif /* __IRQSRCS_SMUIO_9_0_H__ */ + diff --git a/drivers/gpu/drm/amd/include/ivsrcid/thm/irqsrcs_thm_9_0.h b/drivers/gpu/drm/amd/include/ivsrcid/thm/irqsrcs_thm_9_0.h new file mode 100644 index 0000000000000000000000000000000000000000..5218bc53fb2db7d56457778ead9d820876092861 --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/thm/irqsrcs_thm_9_0.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_THM_9_0_H__ +#define __IRQSRCS_THM_9_0_H__ + +#define THM_9_0__SRCID__THM_DIG_THERM_L2H 0 /* ASIC_TEMP > CG_THERMAL_INT.DIG_THERM_INTH */ +#define THM_9_0__SRCID__THM_DIG_THERM_H2L 1 /* ASIC_TEMP < CG_THERMAL_INT.DIG_THERM_INTL */ + +#endif /* __IRQSRCS_THM_9_0_H__ */ + diff --git a/drivers/gpu/drm/amd/include/ivsrcid/uvd/irqsrcs_uvd_7_0.h b/drivers/gpu/drm/amd/include/ivsrcid/uvd/irqsrcs_uvd_7_0.h new file mode 100644 index 0000000000000000000000000000000000000000..fb041aee6c66aa0b5f7aaf8d1da42e355cac870d --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/uvd/irqsrcs_uvd_7_0.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_UVD_7_0_H__ +#define __IRQSRCS_UVD_7_0_H__ + +#define UVD_7_0__SRCID__UVD_ENC_GEN_PURP 119 +#define UVD_7_0__SRCID__UVD_ENC_LOW_LATENCY 120 +#define UVD_7_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT 124 /* UVD system message interrupt */ + +#endif /* __IRQSRCS_UVD_7_0_H__ */ + diff --git a/drivers/gpu/drm/amd/include/ivsrcid/vce/irqsrcs_vce_4_0.h b/drivers/gpu/drm/amd/include/ivsrcid/vce/irqsrcs_vce_4_0.h new file mode 100644 index 0000000000000000000000000000000000000000..3440bab565af5bd73eb1a6f15558575a902a3d8a --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/vce/irqsrcs_vce_4_0.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_VCE_4_0_H__ +#define __IRQSRCS_VCE_4_0_H__ + +#define VCE_4_0__CTXID__VCE_TRAP_GENERAL_PURPOSE 0 +#define VCE_4_0__CTXID__VCE_TRAP_LOW_LATENCY 1 +#define VCE_4_0__CTXID__VCE_TRAP_REAL_TIME 2 + +#endif /* __IRQSRCS_VCE_4_0_H__ */ + diff --git a/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_1_0.h b/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_1_0.h new file mode 100644 index 0000000000000000000000000000000000000000..e5951709bfc365a123f4dd902de7d36ae176c6c6 --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_1_0.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_VCN_1_0_H__ +#define __IRQSRCS_VCN_1_0_H__ + +#define VCN_1_0__SRCID__UVD_ENC_GENERAL_PURPOSE 119 /* 0x77 Encoder General Purpose */ +#define VCN_1_0__SRCID__UVD_ENC_LOW_LATENCY 120 /* 0x78 Encoder Low Latency */ +#define VCN_1_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT 124 /* 0x7c UVD system message interrupt */ + +#endif /* __IRQSRCS_VCN_1_0_H__ */ + diff --git a/drivers/gpu/drm/amd/include/ivsrcid/vmc/irqsrcs_vmc_1_0.h b/drivers/gpu/drm/amd/include/ivsrcid/vmc/irqsrcs_vmc_1_0.h new file mode 100644 index 0000000000000000000000000000000000000000..d130936c99890cb802879e1e930dbfd1e9d153ad --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/vmc/irqsrcs_vmc_1_0.h @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_VMC_1_0_H__ +#define __IRQSRCS_VMC_1_0_H__ + + +#define VMC_1_0__SRCID__VM_FAULT 0 +#define VMC_1_0__SRCID__VM_CONTEXT0_ALL 256 +#define VMC_1_0__SRCID__VM_CONTEXT1_ALL 257 + +#define UTCL2_1_0__SRCID__FAULT 0 /* UTC L2 has encountered a fault or retry scenario */ + + +#endif /* __IRQSRCS_VMC_1_0_H__ */ diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 145e5c403bea55ceca2bfe10609e08f18b2e1289..75c208283e5f9ff936d81bb46f345742265a6da0 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1206,7 +1206,7 @@ static int pp_notify_smu_enable_pwe(void *handle) struct pp_hwmgr *hwmgr = handle; if (!hwmgr || !hwmgr->pm_en) - return -EINVAL;; + return -EINVAL; if (hwmgr->hwmgr_func->smus_notify_pwe == NULL) { pr_info("%s was not implemented.\n", __func__); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 9b675d9bd162d7b10e0f6d7de147df8894859c26..8994aa5c8cf80cb56734a3737c6bffc39bb3cfe0 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -147,10 +147,10 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr) smu7_init_function_pointers(hwmgr); break; case AMDGPU_FAMILY_AI: - hwmgr->feature_mask &= ~PP_GFXOFF_MASK; switch (hwmgr->chip_id) { case CHIP_VEGA10: case CHIP_VEGA20: + hwmgr->feature_mask &= ~PP_GFXOFF_MASK; hwmgr->smumgr_funcs = &vega10_smu_funcs; vega10_hwmgr_init(hwmgr); break; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 077b79938528dad66dff55a5b4eb02273b7240cb..052e60dfaf9fd77003bc49e82eb2d35646fdace2 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -48,6 +48,8 @@ #include "processpptables.h" #include "pp_thermal.h" +#include "ivsrcid/ivsrcid_vislands30.h" + #define MC_CG_ARB_FREQ_F0 0x0a #define MC_CG_ARB_FREQ_F1 0x0b #define MC_CG_ARB_FREQ_F2 0x0c @@ -4105,17 +4107,17 @@ static int smu7_register_irq_handlers(struct pp_hwmgr *hwmgr) amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev), AMDGPU_IH_CLIENTID_LEGACY, - 230, + VISLANDS30_IV_SRCID_CG_TSS_THERMAL_LOW_TO_HIGH, source); amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev), AMDGPU_IH_CLIENTID_LEGACY, - 231, + VISLANDS30_IV_SRCID_CG_TSS_THERMAL_HIGH_TO_LOW, source); /* Register CTF(GPIO_19) interrupt */ amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev), AMDGPU_IH_CLIENTID_LEGACY, - 83, + VISLANDS30_IV_SRCID_GPIO_19, source); return 0; @@ -4610,12 +4612,12 @@ static int smu7_get_sclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks) return -EINVAL; dep_sclk_table = table_info->vdd_dep_on_sclk; for (i = 0; i < dep_sclk_table->count; i++) - clocks->clock[i] = dep_sclk_table->entries[i].clk; + clocks->clock[i] = dep_sclk_table->entries[i].clk * 10; clocks->count = dep_sclk_table->count; } else if (hwmgr->pp_table_version == PP_TABLE_V0) { sclk_table = hwmgr->dyn_state.vddc_dependency_on_sclk; for (i = 0; i < sclk_table->count; i++) - clocks->clock[i] = sclk_table->entries[i].clk; + clocks->clock[i] = sclk_table->entries[i].clk * 10; clocks->count = sclk_table->count; } @@ -4647,7 +4649,7 @@ static int smu7_get_mclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks) return -EINVAL; dep_mclk_table = table_info->vdd_dep_on_mclk; for (i = 0; i < dep_mclk_table->count; i++) { - clocks->clock[i] = dep_mclk_table->entries[i].clk; + clocks->clock[i] = dep_mclk_table->entries[i].clk * 10; clocks->latency[i] = smu7_get_mem_latency(hwmgr, dep_mclk_table->entries[i].clk); } @@ -4655,7 +4657,7 @@ static int smu7_get_mclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks) } else if (hwmgr->pp_table_version == PP_TABLE_V0) { mclk_table = hwmgr->dyn_state.vddc_dependency_on_mclk; for (i = 0; i < mclk_table->count; i++) - clocks->clock[i] = mclk_table->entries[i].clk; + clocks->clock[i] = mclk_table->entries[i].clk * 10; clocks->count = mclk_table->count; } return 0; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c index 50690c72b2ea1ea816a5de9149a45079ec059257..288802f209dd90aefc822e1a0212a00f16f052e3 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c @@ -1604,17 +1604,17 @@ static int smu8_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type switch (type) { case amd_pp_disp_clock: for (i = 0; i < clocks->count; i++) - clocks->clock[i] = data->sys_info.display_clock[i]; + clocks->clock[i] = data->sys_info.display_clock[i] * 10; break; case amd_pp_sys_clock: table = hwmgr->dyn_state.vddc_dependency_on_sclk; for (i = 0; i < clocks->count; i++) - clocks->clock[i] = table->entries[i].clk; + clocks->clock[i] = table->entries[i].clk * 10; break; case amd_pp_mem_clock: clocks->count = SMU8_NUM_NBPMEMORYCLOCK; for (i = 0; i < clocks->count; i++) - clocks->clock[i] = data->sys_info.nbp_memory_clock[clocks->count - 1 - i]; + clocks->clock[i] = data->sys_info.nbp_memory_clock[clocks->count - 1 - i] * 10; break; default: return -1; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c index 3effb5583d1f141cb8aa81e6dd895c4c1928e94c..2aab1b4759459fb421443b30d563a1a4e1860e3a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c @@ -25,6 +25,9 @@ #include "ppatomctrl.h" #include "ppsmc.h" #include "atom.h" +#include "ivsrcid/thm/irqsrcs_thm_9_0.h" +#include "ivsrcid/smuio/irqsrcs_smuio_9_0.h" +#include "ivsrcid/ivsrcid_vislands30.h" uint8_t convert_to_vid(uint16_t vddc) { @@ -543,17 +546,17 @@ int phm_irq_process(struct amdgpu_device *adev, uint32_t src_id = entry->src_id; if (client_id == AMDGPU_IH_CLIENTID_LEGACY) { - if (src_id == 230) + if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_LOW_TO_HIGH) pr_warn("GPU over temperature range detected on PCIe %d:%d.%d!\n", PCI_BUS_NUM(adev->pdev->devfn), PCI_SLOT(adev->pdev->devfn), PCI_FUNC(adev->pdev->devfn)); - else if (src_id == 231) + else if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_HIGH_TO_LOW) pr_warn("GPU under temperature range detected on PCIe %d:%d.%d!\n", PCI_BUS_NUM(adev->pdev->devfn), PCI_SLOT(adev->pdev->devfn), PCI_FUNC(adev->pdev->devfn)); - else if (src_id == 83) + else if (src_id == VISLANDS30_IV_SRCID_GPIO_19) pr_warn("GPU Critical Temperature Fault detected on PCIe %d:%d.%d!\n", PCI_BUS_NUM(adev->pdev->devfn), PCI_SLOT(adev->pdev->devfn), @@ -594,17 +597,17 @@ int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr) amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev), SOC15_IH_CLIENTID_THM, - 0, + THM_9_0__SRCID__THM_DIG_THERM_L2H, source); amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev), SOC15_IH_CLIENTID_THM, - 1, + THM_9_0__SRCID__THM_DIG_THERM_H2L, source); /* Register CTF(GPIO_19) interrupt */ amdgpu_irq_add_id((struct amdgpu_device *)(hwmgr->adev), SOC15_IH_CLIENTID_ROM_SMUIO, - 83, + SMUIO_9_0__SRCID__SMUIO_GPIO19, source); return 0; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 5e771bc119d699d77aac4a9d992f21e955c14b73..1a0dccb3fac1f914715ec2fafe78b01898f1d857 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -2896,11 +2896,6 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) vega10_enable_disable_PCC_limit_feature(hwmgr, true); - if ((hwmgr->smu_version == 0x001c2c00) || - (hwmgr->smu_version == 0x001c2d00)) - smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_UpdatePkgPwrPidAlpha, 1); - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ConfigureTelemetry, data->config_telemetry); @@ -3801,7 +3796,7 @@ static int vega10_notify_smc_display_config_after_ps_adjustment( if (i < dpm_table->count) { clock_req.clock_type = amd_pp_dcef_clock; - clock_req.clock_freq_in_khz = dpm_table->dpm_levels[i].value; + clock_req.clock_freq_in_khz = dpm_table->dpm_levels[i].value * 10; if (!vega10_display_clock_voltage_request(hwmgr, &clock_req)) { smum_send_msg_to_smc_with_parameter( hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 57492878874fa950b61adcdf92fac1481303064c..4ed218dd8ba7a113766e91bf87497fd69638ac3e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -423,6 +423,11 @@ static int vega12_hwmgr_backend_init(struct pp_hwmgr *hwmgr) hwmgr->thermal_controller.advanceFanControlParameters.usFanPWMMinLimit * hwmgr->thermal_controller.fanInfo.ulMaxRPM / 100; + if (hwmgr->feature_mask & PP_GFXOFF_MASK) + data->gfxoff_controlled_by_driver = true; + else + data->gfxoff_controlled_by_driver = false; + return result; } @@ -472,7 +477,7 @@ static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, "[GetNumOfDpmLevel] failed to get dpm levels!", return ret); - vega12_read_arg_from_smc(hwmgr, num_of_levels); + *num_of_levels = smum_get_argument(hwmgr); PP_ASSERT_WITH_CODE(*num_of_levels > 0, "[GetNumOfDpmLevel] number of clk levels is invalid!", return -EINVAL); @@ -483,7 +488,7 @@ static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr, PPCLK_e clkID, uint32_t index, uint32_t *clock) { - int result; + int result = 0; /* *SMU expects the Clock ID to be in the top 16 bits. @@ -494,11 +499,7 @@ static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr, "[GetDpmFrequencyByIndex] Failed to get dpm frequency from SMU!", return -EINVAL); - result = vega12_read_arg_from_smc(hwmgr, clock); - - PP_ASSERT_WITH_CODE(*clock != 0, - "[GetDPMFrequencyByIndex] Failed to get dpm frequency by index.!", - return -EINVAL); + *clock = smum_get_argument(hwmgr); return result; } @@ -879,21 +880,21 @@ static int vega12_get_all_clock_ranges_helper(struct pp_hwmgr *hwmgr, smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clkid << 16)) == 0, "[GetClockRanges] Failed to get max ac clock from SMC!", return -EINVAL); - vega12_read_arg_from_smc(hwmgr, &(clock->ACMax)); + clock->ACMax = smum_get_argument(hwmgr); /* AC Min */ PP_ASSERT_WITH_CODE( smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clkid << 16)) == 0, "[GetClockRanges] Failed to get min ac clock from SMC!", return -EINVAL); - vega12_read_arg_from_smc(hwmgr, &(clock->ACMin)); + clock->ACMin = smum_get_argument(hwmgr); /* DC Max */ PP_ASSERT_WITH_CODE( smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDcModeMaxDpmFreq, (clkid << 16)) == 0, "[GetClockRanges] Failed to get max dc clock from SMC!", return -EINVAL); - vega12_read_arg_from_smc(hwmgr, &(clock->DCMax)); + clock->DCMax = smum_get_argument(hwmgr); return 0; } @@ -1214,7 +1215,7 @@ static int vega12_get_gpu_power(struct pp_hwmgr *hwmgr, uint32_t *query) "Failed to get current package power!", return -EINVAL); - vega12_read_arg_from_smc(hwmgr, &value); + value = smum_get_argument(hwmgr); /* power value is an integer */ *query = value << 8; #endif @@ -1230,11 +1231,8 @@ static int vega12_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16)) == 0, "[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!", - return -1); - PP_ASSERT_WITH_CODE( - vega12_read_arg_from_smc(hwmgr, &gfx_clk) == 0, - "[GetCurrentGfxClkFreq] Attempt to read arg from SMC Failed", - return -1); + return -EINVAL); + gfx_clk = smum_get_argument(hwmgr); *gfx_freq = gfx_clk * 100; @@ -1250,11 +1248,8 @@ static int vega12_get_current_mclk_freq(struct pp_hwmgr *hwmgr, uint32_t *mclk_f PP_ASSERT_WITH_CODE( smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16)) == 0, "[GetCurrentMClkFreq] Attempt to get Current MCLK Frequency Failed!", - return -1); - PP_ASSERT_WITH_CODE( - vega12_read_arg_from_smc(hwmgr, &mem_clk) == 0, - "[GetCurrentMClkFreq] Attempt to read arg from SMC Failed", - return -1); + return -EINVAL); + mem_clk = smum_get_argument(hwmgr); *mclk_freq = mem_clk * 100; @@ -1271,16 +1266,12 @@ static int vega12_get_current_activity_percent( #if 0 ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetAverageGfxActivity, 0); if (!ret) { - ret = vega12_read_arg_from_smc(hwmgr, ¤t_activity); - if (!ret) { - if (current_activity > 100) { - PP_ASSERT(false, - "[GetCurrentActivityPercent] Activity Percentage Exceeds 100!"); - current_activity = 100; - } - } else + current_activity = smum_get_argument(hwmgr); + if (current_activity > 100) { PP_ASSERT(false, - "[GetCurrentActivityPercent] Attempt To Read Average Graphics Activity from SMU Failed!"); + "[GetCurrentActivityPercent] Activity Percentage Exceeds 100!"); + current_activity = 100; + } } else PP_ASSERT(false, "[GetCurrentActivityPercent] Attempt To Send Get Average Graphics Activity to SMU Failed!"); @@ -1361,7 +1352,6 @@ int vega12_display_clock_voltage_request(struct pp_hwmgr *hwmgr, if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { switch (clk_type) { case amd_pp_dcef_clock: - clk_freq = clock_req->clock_freq_in_khz / 100; clk_select = PPCLK_DCEFCLK; break; case amd_pp_disp_clock: @@ -1410,7 +1400,7 @@ static int vega12_notify_smc_display_config_after_ps_adjustment( if (data->smu_features[GNLD_DPM_DCEFCLK].supported) { clock_req.clock_type = amd_pp_dcef_clock; - clock_req.clock_freq_in_khz = min_clocks.dcefClock; + clock_req.clock_freq_in_khz = min_clocks.dcefClock/10; if (!vega12_display_clock_voltage_request(hwmgr, &clock_req)) { if (data->smu_features[GNLD_DS_DCEFCLK].supported) PP_ASSERT_WITH_CODE( @@ -1877,7 +1867,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, for (i = 0; i < clocks.num_levels; i++) size += sprintf(buf + size, "%d: %uMhz %s\n", i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); + (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : ""); break; case PP_MCLK: @@ -1893,7 +1883,7 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, for (i = 0; i < clocks.num_levels; i++) size += sprintf(buf + size, "%d: %uMhz %s\n", i, clocks.data[i].clocks_in_khz / 1000, - (clocks.data[i].clocks_in_khz / 1000 == now) ? "*" : ""); + (clocks.data[i].clocks_in_khz / 1000 == now / 100) ? "*" : ""); break; case PP_PCIE: @@ -2329,6 +2319,38 @@ static int vega12_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, return 0; } +static int vega12_enable_gfx_off(struct pp_hwmgr *hwmgr) +{ + struct vega12_hwmgr *data = + (struct vega12_hwmgr *)(hwmgr->backend); + int ret = 0; + + if (data->gfxoff_controlled_by_driver) + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_AllowGfxOff); + + return ret; +} + +static int vega12_disable_gfx_off(struct pp_hwmgr *hwmgr) +{ + struct vega12_hwmgr *data = + (struct vega12_hwmgr *)(hwmgr->backend); + int ret = 0; + + if (data->gfxoff_controlled_by_driver) + ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisallowGfxOff); + + return ret; +} + +static int vega12_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable) +{ + if (enable) + return vega12_enable_gfx_off(hwmgr); + else + return vega12_disable_gfx_off(hwmgr); +} + static const struct pp_hwmgr_func vega12_hwmgr_funcs = { .backend_init = vega12_hwmgr_backend_init, .backend_fini = vega12_hwmgr_backend_fini, @@ -2378,6 +2400,7 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = { .get_thermal_temperature_range = vega12_get_thermal_temperature_range, .register_irq_handlers = smu9_register_irq_handlers, .start_thermal_controller = vega12_start_thermal_controller, + .powergate_gfx = vega12_gfx_off_control, }; int vega12_hwmgr_init(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h index e17237c90eeaaa32fb72d7bb0e9a8125c5a376b4..b3e424d289941aa85d741cc87d09aa541eb524ee 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h @@ -393,6 +393,9 @@ struct vega12_hwmgr { struct vega12_smc_state_table smc_state_table; struct vega12_clock_range clk_range[PPCLK_COUNT]; + + /* ---- Gfxoff ---- */ + bool gfxoff_controlled_by_driver; }; #define VEGA12_DPM2_NEAR_TDP_DEC 10 diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c index cfd9e6ccb790126a372ff95ca186af4ec16f3301..904eb2c9155b4b45ff21daee35eed31146cdd79f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c @@ -34,11 +34,9 @@ static int vega12_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm) PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentRpm), "Attempt to get current RPM from SMC Failed!", - return -1); - PP_ASSERT_WITH_CODE(!vega12_read_arg_from_smc(hwmgr, - current_rpm), - "Attempt to read current RPM from SMC Failed!", - return -1); + return -EINVAL); + *current_rpm = smum_get_argument(hwmgr); + return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index b3363f26039a75508edeb396d29781f4894db92b..d3d96260f440673ed39960d999c4094577904282 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -194,7 +194,7 @@ struct pp_smumgr_func { int (*request_smu_load_fw)(struct pp_hwmgr *hwmgr); int (*request_smu_load_specific_fw)(struct pp_hwmgr *hwmgr, uint32_t firmware); - int (*get_argument)(struct pp_hwmgr *hwmgr); + uint32_t (*get_argument)(struct pp_hwmgr *hwmgr); int (*send_msg_to_smc)(struct pp_hwmgr *hwmgr, uint16_t msg); int (*send_msg_to_smc_with_parameter)(struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter); diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h index 89dfbf53c7e6ad31097a85d2cf7394ade5530aa4..82550a8a3a3fc28916db07e603c8cbce3bdc33ff 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h @@ -80,7 +80,7 @@ enum SMU10_TABLE_ID { SMU10_CLOCKTABLE, }; -extern int smum_get_argument(struct pp_hwmgr *hwmgr); +extern uint32_t smum_get_argument(struct pp_hwmgr *hwmgr); extern int smum_download_powerplay_table(struct pp_hwmgr *hwmgr, void **table); diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile index 0a200406a1ec243312367a48a37062ef930297b4..8d557accaef2a5ac38d464cdeca3948af23545c4 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/smumgr/Makefile @@ -26,7 +26,7 @@ SMU_MGR = smumgr.o smu8_smumgr.o tonga_smumgr.o fiji_smumgr.o \ polaris10_smumgr.o iceland_smumgr.o \ smu7_smumgr.o vega10_smumgr.o smu10_smumgr.o ci_smumgr.o \ - vega12_smumgr.o vegam_smumgr.o + vega12_smumgr.o vegam_smumgr.o smu9_smumgr.o AMD_PP_SMUMGR = $(addprefix $(AMD_PP_PATH)/smumgr/,$(SMU_MGR)) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c index 0a563f6fe9ea6446b10f2b268acb75c631297512..bb07d43f3874454a9ba42d83dae54422b5154098 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c @@ -68,7 +68,7 @@ static int smu10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, return 0; } -static int smu10_read_arg_from_smc(struct pp_hwmgr *hwmgr) +static uint32_t smu10_read_arg_from_smc(struct pp_hwmgr *hwmgr) { struct amdgpu_device *adev = hwmgr->adev; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c index d644a9bb9078d081639aa09a72af9f92e3612fc2..a029e47c2319c5cf4804b9486cae02992d26e055 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c @@ -379,8 +379,7 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) { struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); uint32_t fw_to_load; - int result = 0; - struct SMU_DRAMData_TOC *toc; + int r = 0; if (!hwmgr->reload_fw) { pr_info("skip reloading...\n"); @@ -421,49 +420,62 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) + UCODE_ID_CP_MEC_JT2_MASK; } - toc = (struct SMU_DRAMData_TOC *)smu_data->header; - toc->num_entries = 0; - toc->structure_version = 1; + if (!smu_data->toc) { + struct SMU_DRAMData_TOC *toc; + + smu_data->toc = kzalloc(sizeof(struct SMU_DRAMData_TOC), GFP_KERNEL); + if (!smu_data->toc) + return -ENOMEM; + toc = smu_data->toc; + toc->num_entries = 0; + toc->structure_version = 1; - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_RLC_G, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_CP_CE, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, - UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - if (!hwmgr->not_vf) + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, + UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + if (!hwmgr->not_vf) + PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, UCODE_ID_MEC_STORAGE, &toc->entry[toc->num_entries++]), - "Failed to Get Firmware Entry.", return -EINVAL); - + "Failed to Get Firmware Entry.", r = -EINVAL; goto failed); + } + memcpy_toio(smu_data->header_buffer.kaddr, smu_data->toc, + sizeof(struct SMU_DRAMData_TOC)); smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_HI, upper_32_bits(smu_data->header_buffer.mc_addr)); smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_LO, lower_32_bits(smu_data->header_buffer.mc_addr)); if (smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_LoadUcodes, fw_to_load)) pr_err("Fail to Request SMU Load uCode"); - return result; + return r; + +failed: + kfree(smu_data->toc); + smu_data->toc = NULL; + return r; } /* Check if the FW has been loaded, SMU will not return if loading has not finished. */ @@ -570,7 +582,6 @@ int smu7_setup_pwr_virus(struct pp_hwmgr *hwmgr) int smu7_init(struct pp_hwmgr *hwmgr) { struct smu7_smumgr *smu_data; - uint64_t mc_addr = 0; int r; /* Allocate memory for backend private data */ smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend); @@ -584,15 +595,12 @@ int smu7_init(struct pp_hwmgr *hwmgr) PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &smu_data->header_buffer.handle, - &mc_addr, + &smu_data->header_buffer.mc_addr, &smu_data->header_buffer.kaddr); if (r) return -EINVAL; - smu_data->header = smu_data->header_buffer.kaddr; - smu_data->header_buffer.mc_addr = mc_addr; - if (!hwmgr->not_vf) return 0; @@ -602,7 +610,7 @@ int smu7_init(struct pp_hwmgr *hwmgr) PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &smu_data->smu_buffer.handle, - &mc_addr, + &smu_data->smu_buffer.mc_addr, &smu_data->smu_buffer.kaddr); if (r) { @@ -611,7 +619,6 @@ int smu7_init(struct pp_hwmgr *hwmgr) &smu_data->header_buffer.kaddr); return -EINVAL; } - smu_data->smu_buffer.mc_addr = mc_addr; if (smum_is_hw_avfs_present(hwmgr)) hwmgr->avfs_supported = true; @@ -633,6 +640,9 @@ int smu7_smu_fini(struct pp_hwmgr *hwmgr) &smu_data->smu_buffer.mc_addr, &smu_data->smu_buffer.kaddr); + + kfree(smu_data->toc); + smu_data->toc = NULL; kfree(hwmgr->smu_backend); hwmgr->smu_backend = NULL; return 0; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h index 39c9bfda0ab416665864c47b66f29c25c0c6f5fe..01f0538fba6b9e8edc20febbda4178dd4aa545d4 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h @@ -37,10 +37,9 @@ struct smu7_buffer_entry { }; struct smu7_smumgr { - uint8_t *header; - uint8_t *mec_image; struct smu7_buffer_entry smu_buffer; struct smu7_buffer_entry header_buffer; + struct SMU_DRAMData_TOC *toc; uint32_t soft_regs_start; uint32_t dpm_table_start; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c index c861d3023474c50fd68e42cb6292db6cfb896fe6..f7e3bc22bb93f8a44d071d1c796f7e5a6b718b80 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c @@ -52,10 +52,10 @@ static const enum smu8_scratch_entry firmware_list[] = { SMU8_SCRATCH_ENTRY_UCODE_ID_RLC_G, }; -static int smu8_get_argument(struct pp_hwmgr *hwmgr) +static uint32_t smu8_get_argument(struct pp_hwmgr *hwmgr) { if (hwmgr == NULL || hwmgr->device == NULL) - return -EINVAL; + return 0; return cgs_read_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0); diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c new file mode 100644 index 0000000000000000000000000000000000000000..079fc8e8f709f39d1ca764e6893fefaa640f58bc --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c @@ -0,0 +1,150 @@ +/* + * Copyright 2018 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 "smumgr.h" +#include "vega10_inc.h" +#include "soc15_common.h" +#include "pp_debug.h" + + +/* MP Apertures */ +#define MP0_Public 0x03800000 +#define MP0_SRAM 0x03900000 +#define MP1_Public 0x03b00000 +#define MP1_SRAM 0x03c00004 + +#define smnMP1_FIRMWARE_FLAGS 0x3010028 + +bool smu9_is_smc_ram_running(struct pp_hwmgr *hwmgr) +{ + struct amdgpu_device *adev = hwmgr->adev; + uint32_t mp1_fw_flags; + + WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2, + (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); + + mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2); + + if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) + return true; + + return false; +} + +/* + * Check if SMC has responded to previous message. + * + * @param smumgr the address of the powerplay hardware manager. + * @return TRUE SMC has responded, FALSE otherwise. + */ +static uint32_t smu9_wait_for_response(struct pp_hwmgr *hwmgr) +{ + struct amdgpu_device *adev = hwmgr->adev; + uint32_t reg; + uint32_t ret; + + reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); + + ret = phm_wait_for_register_unequal(hwmgr, reg, + 0, MP1_C2PMSG_90__CONTENT_MASK); + + if (ret) + pr_err("No response from smu\n"); + + return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90); +} + +/* + * Send a message to the SMC, and do not wait for its response. + * @param smumgr the address of the powerplay hardware manager. + * @param msg the message to send. + * @return Always return 0. + */ +static int smu9_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, + uint16_t msg) +{ + struct amdgpu_device *adev = hwmgr->adev; + + WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg); + + return 0; +} + +/* + * Send a message to the SMC, and wait for its response. + * @param hwmgr the address of the powerplay hardware manager. + * @param msg the message to send. + * @return Always return 0. + */ +int smu9_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) +{ + struct amdgpu_device *adev = hwmgr->adev; + uint32_t ret; + + smu9_wait_for_response(hwmgr); + + WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0); + + smu9_send_msg_to_smc_without_waiting(hwmgr, msg); + + ret = smu9_wait_for_response(hwmgr); + if (ret != 1) + pr_err("Failed to send message: 0x%x, ret value: 0x%x\n", msg, ret); + + return 0; +} + +/* + * Send a message to the SMC with parameter + * @param hwmgr: the address of the powerplay hardware manager. + * @param msg: the message to send. + * @param parameter: the parameter to send + * @return Always return 0. + */ +int smu9_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, + uint16_t msg, uint32_t parameter) +{ + struct amdgpu_device *adev = hwmgr->adev; + uint32_t ret; + + smu9_wait_for_response(hwmgr); + + WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0); + + WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter); + + smu9_send_msg_to_smc_without_waiting(hwmgr, msg); + + ret = smu9_wait_for_response(hwmgr); + if (ret != 1) + pr_err("Failed message: 0x%x, input parameter: 0x%x, error code: 0x%x\n", msg, parameter, ret); + + return 0; +} + +uint32_t smu9_get_argument(struct pp_hwmgr *hwmgr) +{ + struct amdgpu_device *adev = hwmgr->adev; + + return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82); +} diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.h new file mode 100644 index 0000000000000000000000000000000000000000..1462279ca1285105bad55155fae77fb33ab6c0f2 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.h @@ -0,0 +1,32 @@ +/* + * Copyright 2018 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 _SMU9_SMUMANAGER_H_ +#define _SMU9_SMUMANAGER_H_ + +bool smu9_is_smc_ram_running(struct pp_hwmgr *hwmgr); +int smu9_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg); +int smu9_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, + uint16_t msg, uint32_t parameter); +uint32_t smu9_get_argument(struct pp_hwmgr *hwmgr); + +#endif diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index c9837935f0f5e2303b634bc55efd283e9cd3baa0..99d5e4f98f49cd7ec103a70eee060b8c9e0241e4 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c @@ -96,7 +96,7 @@ int smum_process_firmware_header(struct pp_hwmgr *hwmgr) return 0; } -int smum_get_argument(struct pp_hwmgr *hwmgr) +uint32_t smum_get_argument(struct pp_hwmgr *hwmgr) { if (NULL != hwmgr->smumgr_funcs->get_argument) return hwmgr->smumgr_funcs->get_argument(hwmgr); diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c index e84669c448a30a0ea6900f2aa2a245e03df8b654..5d19115f410c93b8a465011f15cdaa8808e886e8 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c @@ -28,142 +28,11 @@ #include "vega10_hwmgr.h" #include "vega10_ppsmc.h" #include "smu9_driver_if.h" +#include "smu9_smumgr.h" #include "ppatomctrl.h" #include "pp_debug.h" -#define AVFS_EN_MSB 1568 -#define AVFS_EN_LSB 1568 - -/* Microcode file is stored in this buffer */ -#define BUFFER_SIZE 80000 -#define MAX_STRING_SIZE 15 -#define BUFFER_SIZETWO 131072 /* 128 *1024 */ - -/* MP Apertures */ -#define MP0_Public 0x03800000 -#define MP0_SRAM 0x03900000 -#define MP1_Public 0x03b00000 -#define MP1_SRAM 0x03c00004 - -#define smnMP1_FIRMWARE_FLAGS 0x3010028 -#define smnMP0_FW_INTF 0x3010104 -#define smnMP1_PUB_CTRL 0x3010b14 - -static bool vega10_is_smc_ram_running(struct pp_hwmgr *hwmgr) -{ - struct amdgpu_device *adev = hwmgr->adev; - uint32_t mp1_fw_flags; - - WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2, - (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); - - mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2); - - if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) - return true; - - return false; -} - -/* - * Check if SMC has responded to previous message. - * - * @param smumgr the address of the powerplay hardware manager. - * @return TRUE SMC has responded, FALSE otherwise. - */ -static uint32_t vega10_wait_for_response(struct pp_hwmgr *hwmgr) -{ - struct amdgpu_device *adev = hwmgr->adev; - uint32_t reg; - uint32_t ret; - - reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); - - ret = phm_wait_for_register_unequal(hwmgr, reg, - 0, MP1_C2PMSG_90__CONTENT_MASK); - - if (ret) - pr_err("No response from smu\n"); - - return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90); -} - -/* - * Send a message to the SMC, and do not wait for its response. - * @param smumgr the address of the powerplay hardware manager. - * @param msg the message to send. - * @return Always return 0. - */ -static int vega10_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, - uint16_t msg) -{ - struct amdgpu_device *adev = hwmgr->adev; - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg); - - return 0; -} - -/* - * Send a message to the SMC, and wait for its response. - * @param hwmgr the address of the powerplay hardware manager. - * @param msg the message to send. - * @return Always return 0. - */ -static int vega10_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) -{ - struct amdgpu_device *adev = hwmgr->adev; - uint32_t ret; - - vega10_wait_for_response(hwmgr); - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0); - - vega10_send_msg_to_smc_without_waiting(hwmgr, msg); - - ret = vega10_wait_for_response(hwmgr); - if (ret != 1) - pr_err("Failed to send message: 0x%x, ret value: 0x%x\n", msg, ret); - - return 0; -} - -/* - * Send a message to the SMC with parameter - * @param hwmgr: the address of the powerplay hardware manager. - * @param msg: the message to send. - * @param parameter: the parameter to send - * @return Always return 0. - */ -static int vega10_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, - uint16_t msg, uint32_t parameter) -{ - struct amdgpu_device *adev = hwmgr->adev; - uint32_t ret; - - vega10_wait_for_response(hwmgr); - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0); - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter); - - vega10_send_msg_to_smc_without_waiting(hwmgr, msg); - - ret = vega10_wait_for_response(hwmgr); - if (ret != 1) - pr_err("Failed message: 0x%x, input parameter: 0x%x, error code: 0x%x\n", msg, parameter, ret); - - return 0; -} - -static int vega10_get_argument(struct pp_hwmgr *hwmgr) -{ - struct amdgpu_device *adev = hwmgr->adev; - - return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82); -} - static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr, uint8_t *table, int16_t table_id) { @@ -175,13 +44,13 @@ static int vega10_copy_table_from_smc(struct pp_hwmgr *hwmgr, "Invalid SMU Table version!", return -EINVAL); PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0, "Invalid SMU Table Length!", return -EINVAL); - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrHigh, upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)); - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrLow, lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)); - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_TransferTableSmu2Dram, priv->smu_tables.entry[table_id].table_id); @@ -206,13 +75,13 @@ static int vega10_copy_table_to_smc(struct pp_hwmgr *hwmgr, memcpy(priv->smu_tables.entry[table_id].table, table, priv->smu_tables.entry[table_id].size); - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrHigh, upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)); - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrLow, lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)); - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_TransferTableDram2Smu, priv->smu_tables.entry[table_id].table_id); @@ -225,8 +94,8 @@ static int vega10_get_smc_features(struct pp_hwmgr *hwmgr, if (features_enabled == NULL) return -EINVAL; - vega10_send_msg_to_smc(hwmgr, PPSMC_MSG_GetEnabledSmuFeatures); - *features_enabled = vega10_get_argument(hwmgr); + smu9_send_msg_to_smc(hwmgr, PPSMC_MSG_GetEnabledSmuFeatures); + *features_enabled = smu9_get_argument(hwmgr); return 0; } @@ -248,10 +117,10 @@ static int vega10_set_tools_address(struct pp_hwmgr *hwmgr) struct vega10_smumgr *priv = hwmgr->smu_backend; if (priv->smu_tables.entry[TOOLSTABLE].mc_addr) { - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetToolsDramAddrHigh, upper_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr)); - vega10_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetToolsDramAddrLow, lower_32_bits(priv->smu_tables.entry[TOOLSTABLE].mc_addr)); } @@ -265,11 +134,11 @@ static int vega10_verify_smc_interface(struct pp_hwmgr *hwmgr) uint32_t dev_id; uint32_t rev_id; - PP_ASSERT_WITH_CODE(!vega10_send_msg_to_smc(hwmgr, + PP_ASSERT_WITH_CODE(!smu9_send_msg_to_smc(hwmgr, PPSMC_MSG_GetDriverIfVersion), "Attempt to get SMC IF Version Number Failed!", return -EINVAL); - smc_driver_if_version = vega10_get_argument(hwmgr); + smc_driver_if_version = smu9_get_argument(hwmgr); dev_id = adev->pdev->device; rev_id = adev->pdev->revision; @@ -441,7 +310,7 @@ static int vega10_smu_fini(struct pp_hwmgr *hwmgr) static int vega10_start_smu(struct pp_hwmgr *hwmgr) { - if (!vega10_is_smc_ram_running(hwmgr)) + if (!smu9_is_smc_ram_running(hwmgr)) return -EINVAL; PP_ASSERT_WITH_CODE(!vega10_verify_smc_interface(hwmgr), @@ -453,7 +322,8 @@ static int vega10_start_smu(struct pp_hwmgr *hwmgr) return 0; } -static int vega10_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw) +static int vega10_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, + uint16_t table_id, bool rw) { int ret; @@ -470,11 +340,11 @@ const struct pp_smumgr_func vega10_smu_funcs = { .smu_fini = &vega10_smu_fini, .start_smu = &vega10_start_smu, .request_smu_load_specific_fw = NULL, - .send_msg_to_smc = &vega10_send_msg_to_smc, - .send_msg_to_smc_with_parameter = &vega10_send_msg_to_smc_with_parameter, + .send_msg_to_smc = &smu9_send_msg_to_smc, + .send_msg_to_smc_with_parameter = &smu9_send_msg_to_smc_with_parameter, .download_pptable_settings = NULL, .upload_pptable_settings = NULL, .is_dpm_running = vega10_is_dpm_running, - .get_argument = vega10_get_argument, + .get_argument = smu9_get_argument, .smc_table_manager = vega10_smc_table_manager, }; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c index 7d9b40e8b1bf053b3cd3e8920b8118a53d804d04..7f0e2109f40d7f46641dd81f2440e9dff2932b9a 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c @@ -24,157 +24,14 @@ #include "smumgr.h" #include "vega12_inc.h" #include "soc15_common.h" +#include "smu9_smumgr.h" #include "vega12_smumgr.h" #include "vega12_ppsmc.h" #include "vega12/smu9_driver_if.h" - #include "ppatomctrl.h" #include "pp_debug.h" -/* MP Apertures */ -#define MP0_Public 0x03800000 -#define MP0_SRAM 0x03900000 -#define MP1_Public 0x03b00000 -#define MP1_SRAM 0x03c00004 - -#define smnMP1_FIRMWARE_FLAGS 0x3010028 -#define smnMP0_FW_INTF 0x3010104 -#define smnMP1_PUB_CTRL 0x3010b14 - -static bool vega12_is_smc_ram_running(struct pp_hwmgr *hwmgr) -{ - struct amdgpu_device *adev = hwmgr->adev; - uint32_t mp1_fw_flags; - - WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2, - (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); - - mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2); - - if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> - MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) - return true; - - return false; -} - -/* - * Check if SMC has responded to previous message. - * - * @param smumgr the address of the powerplay hardware manager. - * @return TRUE SMC has responded, FALSE otherwise. - */ -static uint32_t vega12_wait_for_response(struct pp_hwmgr *hwmgr) -{ - struct amdgpu_device *adev = hwmgr->adev; - uint32_t reg; - - reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); - - phm_wait_for_register_unequal(hwmgr, reg, - 0, MP1_C2PMSG_90__CONTENT_MASK); - - return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90); -} - -/* - * Send a message to the SMC, and do not wait for its response. - * @param smumgr the address of the powerplay hardware manager. - * @param msg the message to send. - * @return Always return 0. - */ -int vega12_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr, - uint16_t msg) -{ - struct amdgpu_device *adev = hwmgr->adev; - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg); - - return 0; -} - -/* - * Send a message to the SMC, and wait for its response. - * @param hwmgr the address of the powerplay hardware manager. - * @param msg the message to send. - * @return Always return 0. - */ -int vega12_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg) -{ - struct amdgpu_device *adev = hwmgr->adev; - - vega12_wait_for_response(hwmgr); - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0); - - vega12_send_msg_to_smc_without_waiting(hwmgr, msg); - - if (vega12_wait_for_response(hwmgr) != 1) - pr_err("Failed to send message: 0x%x\n", msg); - - return 0; -} - -/* - * Send a message to the SMC with parameter - * @param hwmgr: the address of the powerplay hardware manager. - * @param msg: the message to send. - * @param parameter: the parameter to send - * @return Always return 0. - */ -int vega12_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr, - uint16_t msg, uint32_t parameter) -{ - struct amdgpu_device *adev = hwmgr->adev; - - vega12_wait_for_response(hwmgr); - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0); - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter); - - vega12_send_msg_to_smc_without_waiting(hwmgr, msg); - - if (vega12_wait_for_response(hwmgr) != 1) - pr_err("Failed to send message: 0x%x\n", msg); - - return 0; -} - - -/* - * Send a message to the SMC with parameter, do not wait for response - * @param hwmgr: the address of the powerplay hardware manager. - * @param msg: the message to send. - * @param parameter: the parameter to send - * @return The response that came from the SMC. - */ -int vega12_send_msg_to_smc_with_parameter_without_waiting( - struct pp_hwmgr *hwmgr, uint16_t msg, uint32_t parameter) -{ - struct amdgpu_device *adev = hwmgr->adev; - - WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, parameter); - - return vega12_send_msg_to_smc_without_waiting(hwmgr, msg); -} - -/* - * Retrieve an argument from SMC. - * @param hwmgr the address of the powerplay hardware manager. - * @param arg pointer to store the argument from SMC. - * @return Always return 0. - */ -int vega12_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg) -{ - struct amdgpu_device *adev = hwmgr->adev; - - *arg = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82); - - return 0; -} - /* * Copy table from SMC into driver FB * @param hwmgr the address of the HW manager @@ -192,16 +49,16 @@ int vega12_copy_table_from_smc(struct pp_hwmgr *hwmgr, "Invalid SMU Table version!", return -EINVAL); PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0, "Invalid SMU Table Length!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrHigh, upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0, "[CopyTableFromSMC] Attempt to Set Dram Addr High Failed!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrLow, lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0, "[CopyTableFromSMC] Attempt to Set Dram Addr Low Failed!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_TransferTableSmu2Dram, table_id) == 0, "[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!", @@ -234,17 +91,17 @@ int vega12_copy_table_to_smc(struct pp_hwmgr *hwmgr, memcpy(priv->smu_tables.entry[table_id].table, table, priv->smu_tables.entry[table_id].size); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrHigh, upper_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0, "[CopyTableToSMC] Attempt to Set Dram Addr High Failed!", return -EINVAL;); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetDriverDramAddrLow, lower_32_bits(priv->smu_tables.entry[table_id].mc_addr)) == 0, "[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_TransferTableDram2Smu, table_id) == 0, "[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!", @@ -262,20 +119,20 @@ int vega12_enable_smc_features(struct pp_hwmgr *hwmgr, smu_features_high = (uint32_t)((feature_mask & SMU_FEATURES_HIGH_MASK) >> SMU_FEATURES_HIGH_SHIFT); if (enable) { - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low) == 0, "[EnableDisableSMCFeatures] Attemp to enable SMU features Low failed!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high) == 0, "[EnableDisableSMCFeatures] Attemp to enable SMU features High failed!", return -EINVAL); } else { - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low) == 0, "[EnableDisableSMCFeatures] Attemp to disable SMU features Low failed!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc_with_parameter(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high) == 0, "[EnableDisableSMCFeatures] Attemp to disable SMU features High failed!", return -EINVAL); @@ -292,22 +149,17 @@ int vega12_get_enabled_smc_features(struct pp_hwmgr *hwmgr, if (features_enabled == NULL) return -EINVAL; - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc(hwmgr, + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr, PPSMC_MSG_GetEnabledSmuFeaturesLow) == 0, "[GetEnabledSMCFeatures] Attemp to get SMU features Low failed!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_read_arg_from_smc(hwmgr, - &smc_features_low) == 0, - "[GetEnabledSMCFeatures] Attemp to read SMU features Low argument failed!", - return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_send_msg_to_smc(hwmgr, + smc_features_low = smu9_get_argument(hwmgr); + + PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr, PPSMC_MSG_GetEnabledSmuFeaturesHigh) == 0, "[GetEnabledSMCFeatures] Attemp to get SMU features High failed!", return -EINVAL); - PP_ASSERT_WITH_CODE(vega12_read_arg_from_smc(hwmgr, - &smc_features_high) == 0, - "[GetEnabledSMCFeatures] Attemp to read SMU features High argument failed!", - return -EINVAL); + smc_features_high = smu9_get_argument(hwmgr); *features_enabled = ((((uint64_t)smc_features_low << SMU_FEATURES_LOW_SHIFT) & SMU_FEATURES_LOW_MASK) | (((uint64_t)smc_features_high << SMU_FEATURES_HIGH_SHIFT) & SMU_FEATURES_HIGH_MASK)); @@ -333,39 +185,16 @@ static int vega12_set_tools_address(struct pp_hwmgr *hwmgr) (struct vega12_smumgr *)(hwmgr->smu_backend); if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr) { - if (!vega12_send_msg_to_smc_with_parameter(hwmgr, + if (!smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetToolsDramAddrHigh, upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr))) - vega12_send_msg_to_smc_with_parameter(hwmgr, + smu9_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetToolsDramAddrLow, lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr)); } return 0; } -#if 0 /* tentatively remove */ -static int vega12_verify_smc_interface(struct pp_hwmgr *hwmgr) -{ - uint32_t smc_driver_if_version; - - PP_ASSERT_WITH_CODE(!vega12_send_msg_to_smc(hwmgr, - PPSMC_MSG_GetDriverIfVersion), - "Attempt to get SMC IF Version Number Failed!", - return -EINVAL); - vega12_read_arg_from_smc(hwmgr, &smc_driver_if_version); - - if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) { - pr_err("Your firmware(0x%x) doesn't match \ - SMU9_DRIVER_IF_VERSION(0x%x). \ - Please update your firmware!\n", - smc_driver_if_version, SMU9_DRIVER_IF_VERSION); - return -EINVAL; - } - - return 0; -} -#endif - static int vega12_smu_init(struct pp_hwmgr *hwmgr) { struct vega12_smumgr *priv; @@ -513,16 +342,10 @@ static int vega12_smu_fini(struct pp_hwmgr *hwmgr) static int vega12_start_smu(struct pp_hwmgr *hwmgr) { - PP_ASSERT_WITH_CODE(vega12_is_smc_ram_running(hwmgr), + PP_ASSERT_WITH_CODE(smu9_is_smc_ram_running(hwmgr), "SMC is not running!", return -EINVAL); -#if 0 /* tentatively remove */ - PP_ASSERT_WITH_CODE(!vega12_verify_smc_interface(hwmgr), - "Failed to verify SMC interface!", - return -EINVAL); -#endif - vega12_set_tools_address(hwmgr); return 0; @@ -533,9 +356,10 @@ const struct pp_smumgr_func vega12_smu_funcs = { .smu_fini = &vega12_smu_fini, .start_smu = &vega12_start_smu, .request_smu_load_specific_fw = NULL, - .send_msg_to_smc = &vega12_send_msg_to_smc, - .send_msg_to_smc_with_parameter = &vega12_send_msg_to_smc_with_parameter, + .send_msg_to_smc = &smu9_send_msg_to_smc, + .send_msg_to_smc_with_parameter = &smu9_send_msg_to_smc_with_parameter, .download_pptable_settings = NULL, .upload_pptable_settings = NULL, .is_dpm_running = vega12_is_dpm_running, + .get_argument = smu9_get_argument, }; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.h index 2810d387b611cab83d0472498cdf75ef7c82b8cb..b285cbc04019cd78464657cd000d206d73ac50e3 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.h @@ -48,7 +48,6 @@ struct vega12_smumgr { #define SMU_FEATURES_HIGH_MASK 0xFFFFFFFF00000000 #define SMU_FEATURES_HIGH_SHIFT 32 -int vega12_read_arg_from_smc(struct pp_hwmgr *hwmgr, uint32_t *arg); int vega12_copy_table_from_smc(struct pp_hwmgr *hwmgr, uint8_t *table, int16_t table_id); int vega12_copy_table_to_smc(struct pp_hwmgr *hwmgr, diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 45bfdf4cc1078465d6c630f572fd7e012e3dc8c7..36414ba56b226bca034fae42160f308b38b7180a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -49,12 +49,12 @@ static int etnaviv_open(struct drm_device *dev, struct drm_file *file) for (i = 0; i < ETNA_MAX_PIPES; i++) { struct etnaviv_gpu *gpu = priv->gpu[i]; + struct drm_sched_rq *rq; if (gpu) { - drm_sched_entity_init(&gpu->sched, - &ctx->sched_entity[i], - &gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL], - NULL); + rq = &gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; + drm_sched_entity_init(&ctx->sched_entity[i], + &rq, 1, NULL); } } diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c index 7d2560699b84e7d9bc9cca21c2746307cff81923..dac71e3b4514c8a9c22dec752df35dd674af21b0 100644 --- a/drivers/gpu/drm/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c @@ -69,11 +69,13 @@ static void drm_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb); * * Initializes a scheduler runqueue. */ -static void drm_sched_rq_init(struct drm_sched_rq *rq) +static void drm_sched_rq_init(struct drm_gpu_scheduler *sched, + struct drm_sched_rq *rq) { spin_lock_init(&rq->lock); INIT_LIST_HEAD(&rq->entities); rq->current_entity = NULL; + rq->sched = sched; } /** @@ -160,26 +162,30 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq) * drm_sched_entity_init - Init a context entity used by scheduler when * submit to HW ring. * - * @sched: scheduler instance * @entity: scheduler entity to init - * @rq: the run queue this entity belongs + * @rq_list: the list of run queue on which jobs from this + * entity can be submitted + * @num_rq_list: number of run queue in rq_list * @guilty: atomic_t set to 1 when a job on this queue * is found to be guilty causing a timeout * + * Note: the rq_list should have atleast one element to schedule + * the entity + * * Returns 0 on success or a negative error code on failure. */ -int drm_sched_entity_init(struct drm_gpu_scheduler *sched, - struct drm_sched_entity *entity, - struct drm_sched_rq *rq, +int drm_sched_entity_init(struct drm_sched_entity *entity, + struct drm_sched_rq **rq_list, + unsigned int num_rq_list, atomic_t *guilty) { - if (!(sched && entity && rq)) + if (!(entity && rq_list && num_rq_list > 0 && rq_list[0])) return -EINVAL; memset(entity, 0, sizeof(struct drm_sched_entity)); INIT_LIST_HEAD(&entity->list); - entity->rq = rq; - entity->sched = sched; + entity->rq = rq_list[0]; + entity->sched = rq_list[0]->sched; entity->guilty = guilty; entity->last_scheduled = NULL; @@ -541,6 +547,11 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job, if (first) { /* Add the entity to the run queue */ spin_lock(&entity->rq_lock); + if (!entity->rq) { + DRM_ERROR("Trying to push to a killed entity\n"); + spin_unlock(&entity->rq_lock); + return; + } drm_sched_rq_add_entity(entity->rq, entity); spin_unlock(&entity->rq_lock); drm_sched_wakeup(sched); @@ -926,7 +937,7 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, sched->timeout = timeout; sched->hang_limit = hang_limit; for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_MAX; i++) - drm_sched_rq_init(&sched->sched_rq[i]); + drm_sched_rq_init(sched, &sched->sched_rq[i]); init_waitqueue_head(&sched->wake_up_worker); init_waitqueue_head(&sched->job_scheduled); diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 5d8688e522d1a6cd4db1a0401048e6ff4088686b..7c484729f9b21ad9f7bcf99b810261e8b5d8f68b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -287,12 +287,9 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, if (ret) { if (bdev->driver->move_notify) { - struct ttm_mem_reg tmp_mem = *mem; - *mem = bo->mem; - bo->mem = tmp_mem; + swap(*mem, bo->mem); bdev->driver->move_notify(bo, false, mem); - bo->mem = *mem; - *mem = tmp_mem; + swap(*mem, bo->mem); } goto out_err; @@ -590,12 +587,18 @@ static void ttm_bo_release(struct kref *kref) kref_put(&bo->list_kref, ttm_bo_release_list); } +void ttm_bo_put(struct ttm_buffer_object *bo) +{ + kref_put(&bo->kref, ttm_bo_release); +} +EXPORT_SYMBOL(ttm_bo_put); + void ttm_bo_unref(struct ttm_buffer_object **p_bo) { struct ttm_buffer_object *bo = *p_bo; *p_bo = NULL; - kref_put(&bo->kref, ttm_bo_release); + ttm_bo_put(bo); } EXPORT_SYMBOL(ttm_bo_unref); @@ -1201,7 +1204,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, if (!resv) ttm_bo_unreserve(bo); - ttm_bo_unref(&bo); + ttm_bo_put(bo); return ret; } diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index f2c167702eef57bdc3b624ec5d2d7075b0e0b313..046a6dda690a268df98159e5a8014b6826a739c9 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -463,7 +463,7 @@ static void ttm_transfered_destroy(struct ttm_buffer_object *bo) struct ttm_transfer_obj *fbo; fbo = container_of(bo, struct ttm_transfer_obj, base); - ttm_bo_unref(&fbo->bo); + ttm_bo_put(fbo->bo); kfree(fbo); } @@ -492,8 +492,9 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, if (!fbo) return -ENOMEM; + ttm_bo_get(bo); fbo->base = *bo; - fbo->bo = ttm_bo_reference(bo); + fbo->bo = bo; /** * Fix up members that we shouldn't copy directly: @@ -730,7 +731,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, bo->ttm = NULL; ttm_bo_unreserve(ghost_obj); - ttm_bo_unref(&ghost_obj); + ttm_bo_put(ghost_obj); } *old_mem = *new_mem; @@ -786,7 +787,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, bo->ttm = NULL; ttm_bo_unreserve(ghost_obj); - ttm_bo_unref(&ghost_obj); + ttm_bo_put(ghost_obj); } else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) { @@ -851,7 +852,7 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo) bo->ttm = NULL; ttm_bo_unreserve(ghost); - ttm_bo_unref(&ghost); + ttm_bo_put(ghost); return 0; } diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 0ca0ec47334e21b6decfdc0acaa36b1c5d041bae..6fe91c1b692d6fd547fcfff08b1633c229e77b0a 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -68,11 +68,11 @@ static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT) goto out_unlock; - ttm_bo_reference(bo); + ttm_bo_get(bo); up_read(&vmf->vma->vm_mm->mmap_sem); (void) dma_fence_wait(bo->moving, true); ttm_bo_unreserve(bo); - ttm_bo_unref(&bo); + ttm_bo_put(bo); goto out_unlock; } @@ -138,10 +138,10 @@ static vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) { if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) { - ttm_bo_reference(bo); + ttm_bo_get(bo); up_read(&vmf->vma->vm_mm->mmap_sem); (void) ttm_bo_wait_unreserved(bo); - ttm_bo_unref(&bo); + ttm_bo_put(bo); } return VM_FAULT_RETRY; @@ -302,14 +302,14 @@ static void ttm_bo_vm_open(struct vm_area_struct *vma) WARN_ON(bo->bdev->dev_mapping != vma->vm_file->f_mapping); - (void)ttm_bo_reference(bo); + ttm_bo_get(bo); } static void ttm_bo_vm_close(struct vm_area_struct *vma) { struct ttm_buffer_object *bo = (struct ttm_buffer_object *)vma->vm_private_data; - ttm_bo_unref(&bo); + ttm_bo_put(bo); vma->vm_private_data = NULL; } @@ -461,7 +461,7 @@ int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; return 0; out_unref: - ttm_bo_unref(&bo); + ttm_bo_put(bo); return ret; } EXPORT_SYMBOL(ttm_bo_mmap); @@ -471,8 +471,10 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo) if (vma->vm_pgoff != 0) return -EACCES; + ttm_bo_get(bo); + vma->vm_ops = &ttm_bo_vm_ops; - vma->vm_private_data = ttm_bo_reference(bo); + vma->vm_private_data = bo; vma->vm_flags |= VM_MIXEDMAP; vma->vm_flags |= VM_IO | VM_DONTEXPAND; return 0; diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 567f7d46d912d4de6ea31ad5440f9b62b0f4859f..1dceba2b42fd6975d293af6da7dbc0872752bc54 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -123,6 +123,7 @@ v3d_open(struct drm_device *dev, struct drm_file *file) { struct v3d_dev *v3d = to_v3d_dev(dev); struct v3d_file_priv *v3d_priv; + struct drm_sched_rq *rq; int i; v3d_priv = kzalloc(sizeof(*v3d_priv), GFP_KERNEL); @@ -132,10 +133,8 @@ v3d_open(struct drm_device *dev, struct drm_file *file) v3d_priv->v3d = v3d; for (i = 0; i < V3D_MAX_QUEUES; i++) { - drm_sched_entity_init(&v3d->queue[i].sched, - &v3d_priv->sched_entity[i], - &v3d->queue[i].sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL], - NULL); + rq = &v3d->queue[i].sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; + drm_sched_entity_init(&v3d_priv->sched_entity[i], &rq, 1, NULL); } file->driver_priv = v3d_priv; diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 4214ceb71c054d0748303e95f8155fe71c0ca403..2205e89722f6b32e851b035a38d64e14ebc53c95 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -93,6 +93,7 @@ struct drm_sched_entity { * struct drm_sched_rq - queue of entities to be scheduled. * * @lock: to modify the entities list. + * @sched: the scheduler to which this rq belongs to. * @entities: list of the entities to be scheduled. * @current_entity: the entity which is to be scheduled. * @@ -102,6 +103,7 @@ struct drm_sched_entity { */ struct drm_sched_rq { spinlock_t lock; + struct drm_gpu_scheduler *sched; struct list_head entities; struct drm_sched_entity *current_entity; }; @@ -280,9 +282,9 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, const char *name); void drm_sched_fini(struct drm_gpu_scheduler *sched); -int drm_sched_entity_init(struct drm_gpu_scheduler *sched, - struct drm_sched_entity *entity, - struct drm_sched_rq *rq, +int drm_sched_entity_init(struct drm_sched_entity *entity, + struct drm_sched_rq **rq_list, + unsigned int num_rq_list, atomic_t *guilty); long drm_sched_entity_flush(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity, long timeout); diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index c67977aa1a0eb6d3f83441869c3689e95d64508e..a01ba2032f0ef7042653e08f7563c89518c475ed 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -283,18 +283,30 @@ struct ttm_operation_ctx { /* when serving page fault or suspend, allow alloc anyway */ #define TTM_OPT_FLAG_FORCE_ALLOC 0x2 +/** + * ttm_bo_get - reference a struct ttm_buffer_object + * + * @bo: The buffer object. + */ +static inline void ttm_bo_get(struct ttm_buffer_object *bo) +{ + kref_get(&bo->kref); +} + /** * ttm_bo_reference - reference a struct ttm_buffer_object * * @bo: The buffer object. * * Returns a refcounted pointer to a buffer object. + * + * This function is deprecated. Use @ttm_bo_get instead. */ static inline struct ttm_buffer_object * ttm_bo_reference(struct ttm_buffer_object *bo) { - kref_get(&bo->kref); + ttm_bo_get(bo); return bo; } @@ -345,12 +357,23 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_operation_ctx *ctx); +/** + * ttm_bo_put + * + * @bo: The buffer object. + * + * Unreference a buffer object. + */ +void ttm_bo_put(struct ttm_buffer_object *bo); + /** * ttm_bo_unref * * @bo: The buffer object. * * Unreference and clear a pointer to a buffer object. + * + * This function is deprecated. Use @ttm_bo_put instead. */ void ttm_bo_unref(struct ttm_buffer_object **bo); diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 784b0fe470eea7bfbce484f4133e86a12bf90e40..1ceec56de0157671c6a42af07322ffb7fb8e1731 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -516,6 +516,7 @@ struct drm_amdgpu_gem_va { #define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03 #define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05 +#define AMDGPU_CHUNK_ID_BO_HANDLES 0x06 struct drm_amdgpu_cs_chunk { __u32 chunk_id;