diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
52 files changed, 564 insertions, 449 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 668939a14206..0d13e6368b96 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -82,6 +82,7 @@ extern int amdgpu_vm_block_size;  extern int amdgpu_enable_scheduler;  extern int amdgpu_sched_jobs;  extern int amdgpu_sched_hw_submission; +extern int amdgpu_enable_semaphores;  #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS	        3000  #define AMDGPU_MAX_USEC_TIMEOUT			100000	/* 100 ms */ @@ -432,7 +433,7 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev);  void amdgpu_fence_driver_fini(struct amdgpu_device *adev);  void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev); -void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring); +int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);  int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,  				   struct amdgpu_irq_src *irq_src,  				   unsigned irq_type); @@ -890,7 +891,7 @@ struct amdgpu_ring {  	struct amdgpu_device		*adev;  	const struct amdgpu_ring_funcs	*funcs;  	struct amdgpu_fence_driver	fence_drv; -	struct amd_gpu_scheduler 	*scheduler; +	struct amd_gpu_scheduler 	sched;  	spinlock_t              fence_lock;  	struct mutex		*ring_lock; @@ -1201,8 +1202,6 @@ struct amdgpu_gfx {  	struct amdgpu_irq_src		priv_inst_irq;  	/* gfx status */  	uint32_t gfx_current_status; -	/* sync signal for const engine */ -	unsigned ce_sync_offs;  	/* ce ram size*/  	unsigned ce_ram_size;  }; @@ -1274,8 +1273,10 @@ struct amdgpu_job {  	uint32_t		num_ibs;  	struct mutex            job_lock;  	struct amdgpu_user_fence uf; -	int (*free_job)(struct amdgpu_job *sched_job); +	int (*free_job)(struct amdgpu_job *job);  }; +#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)  { @@ -1653,6 +1654,7 @@ struct amdgpu_pm {  	u8                      fan_max_rpm;  	/* dpm */  	bool                    dpm_enabled; +	bool                    sysfs_initialized;  	struct amdgpu_dpm       dpm;  	const struct firmware	*fw;	/* SMC firmware */  	uint32_t                fw_version; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 496ed2192eba..84d68d658f8a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -183,7 +183,7 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,  		return -ENOMEM;  	r = amdgpu_bo_create(rdev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_GTT, -			AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, &(*mem)->bo); +			     AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, NULL, &(*mem)->bo);  	if (r) {  		dev_err(rdev->dev,  			"failed to allocate BO for amdkfd (%d)\n", r); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 77f1d7c6ea3a..9416e0f5c1db 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -672,8 +672,12 @@ int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev)  		/* disp clock */  		adev->clock.default_dispclk =  			le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); -		if (adev->clock.default_dispclk == 0) -			adev->clock.default_dispclk = 54000; /* 540 Mhz */ +		/* set a reasonable default for DP */ +		if (adev->clock.default_dispclk < 53900) { +			DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n", +				 adev->clock.default_dispclk / 100); +			adev->clock.default_dispclk = 60000; +		}  		adev->clock.dp_extclk =  			le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);  		adev->clock.current_dispclk = adev->clock.default_dispclk; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c index 98d59ee640ce..cd639c362df3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c @@ -79,7 +79,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,  	int time;  	n = AMDGPU_BENCHMARK_ITERATIONS; -	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL, &sobj); +	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL, +			     NULL, &sobj);  	if (r) {  		goto out_cleanup;  	} @@ -91,7 +92,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,  	if (r) {  		goto out_cleanup;  	} -	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL, &dobj); +	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL, +			     NULL, &dobj);  	if (r) {  		goto out_cleanup;  	} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 6b1243f9f86d..8e995148f56e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -86,7 +86,7 @@ static int amdgpu_cgs_gmap_kmem(void *cgs_device, void *kmem,  	struct sg_table *sg = drm_prime_pages_to_sg(&kmem_page, npages);  	ret = amdgpu_bo_create(adev, size, PAGE_SIZE, false, -			       AMDGPU_GEM_DOMAIN_GTT, 0, sg, &bo); +			       AMDGPU_GEM_DOMAIN_GTT, 0, sg, NULL, &bo);  	if (ret)  		return ret;  	ret = amdgpu_bo_reserve(bo, false); @@ -197,7 +197,8 @@ static int amdgpu_cgs_alloc_gpu_mem(void *cgs_device,  	ret = amdgpu_bo_create_restricted(adev, size, PAGE_SIZE,  					  true, domain, flags, -					  NULL, &placement, &obj); +					  NULL, &placement, NULL, +					  &obj);  	if (ret) {  		DRM_ERROR("(%d) bo create failed\n", ret);  		return ret; @@ -207,44 +208,6 @@ static int amdgpu_cgs_alloc_gpu_mem(void *cgs_device,  	return ret;  } -static int amdgpu_cgs_import_gpu_mem(void *cgs_device, int dmabuf_fd, -				     cgs_handle_t *handle) -{ -	CGS_FUNC_ADEV; -	int r; -	uint32_t dma_handle; -	struct drm_gem_object *obj; -	struct amdgpu_bo *bo; -	struct drm_device *dev = adev->ddev; -	struct drm_file *file_priv = NULL, *priv; - -	mutex_lock(&dev->struct_mutex); -	list_for_each_entry(priv, &dev->filelist, lhead) { -		rcu_read_lock(); -		if (priv->pid == get_pid(task_pid(current))) -			file_priv = priv; -		rcu_read_unlock(); -		if (file_priv) -			break; -	} -	mutex_unlock(&dev->struct_mutex); -	r = dev->driver->prime_fd_to_handle(dev, -					    file_priv, dmabuf_fd, -					    &dma_handle); -	spin_lock(&file_priv->table_lock); - -	/* Check if we currently have a reference on the object */ -	obj = idr_find(&file_priv->object_idr, dma_handle); -	if (obj == NULL) { -		spin_unlock(&file_priv->table_lock); -		return -EINVAL; -	} -	spin_unlock(&file_priv->table_lock); -	bo = gem_to_amdgpu_bo(obj); -	*handle = (cgs_handle_t)bo; -	return 0; -} -  static int amdgpu_cgs_free_gpu_mem(void *cgs_device, cgs_handle_t handle)  {  	struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; @@ -809,7 +772,6 @@ static const struct cgs_ops amdgpu_cgs_ops = {  };  static const struct cgs_os_ops amdgpu_cgs_os_ops = { -	amdgpu_cgs_import_gpu_mem,  	amdgpu_cgs_add_irq_source,  	amdgpu_cgs_irq_get,  	amdgpu_cgs_irq_put diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 3b355aeb62fd..fd16652aa277 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -154,42 +154,42 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)  {  	union drm_amdgpu_cs *cs = data;  	uint64_t *chunk_array_user; -	uint64_t *chunk_array = NULL; +	uint64_t *chunk_array;  	struct amdgpu_fpriv *fpriv = p->filp->driver_priv; -	unsigned size, i; -	int r = 0; +	unsigned size; +	int i; +	int ret; -	if (!cs->in.num_chunks) -		goto out; +	if (cs->in.num_chunks == 0) +		return 0; + +	chunk_array = kmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL); +	if (!chunk_array) +		return -ENOMEM;  	p->ctx = amdgpu_ctx_get(fpriv, cs->in.ctx_id);  	if (!p->ctx) { -		r = -EINVAL; -		goto out; +		ret = -EINVAL; +		goto free_chunk;  	} +  	p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle);  	/* get chunks */  	INIT_LIST_HEAD(&p->validated); -	chunk_array = kmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL); -	if (chunk_array == NULL) { -		r = -ENOMEM; -		goto out; -	} - -	chunk_array_user = (uint64_t __user *)(cs->in.chunks); +	chunk_array_user = (uint64_t __user *)(unsigned long)(cs->in.chunks);  	if (copy_from_user(chunk_array, chunk_array_user,  			   sizeof(uint64_t)*cs->in.num_chunks)) { -		r = -EFAULT; -		goto out; +		ret = -EFAULT; +		goto put_bo_list;  	}  	p->nchunks = cs->in.num_chunks;  	p->chunks = kmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk),  			    GFP_KERNEL); -	if (p->chunks == NULL) { -		r = -ENOMEM; -		goto out; +	if (!p->chunks) { +		ret = -ENOMEM; +		goto put_bo_list;  	}  	for (i = 0; i < p->nchunks; i++) { @@ -197,28 +197,30 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)  		struct drm_amdgpu_cs_chunk user_chunk;  		uint32_t __user *cdata; -		chunk_ptr = (void __user *)chunk_array[i]; +		chunk_ptr = (void __user *)(unsigned long)chunk_array[i];  		if (copy_from_user(&user_chunk, chunk_ptr,  				       sizeof(struct drm_amdgpu_cs_chunk))) { -			r = -EFAULT; -			goto out; +			ret = -EFAULT; +			i--; +			goto free_partial_kdata;  		}  		p->chunks[i].chunk_id = user_chunk.chunk_id;  		p->chunks[i].length_dw = user_chunk.length_dw;  		size = p->chunks[i].length_dw; -		cdata = (void __user *)user_chunk.chunk_data; +		cdata = (void __user *)(unsigned long)user_chunk.chunk_data;  		p->chunks[i].user_ptr = cdata;  		p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));  		if (p->chunks[i].kdata == NULL) { -			r = -ENOMEM; -			goto out; +			ret = -ENOMEM; +			i--; +			goto free_partial_kdata;  		}  		size *= sizeof(uint32_t);  		if (copy_from_user(p->chunks[i].kdata, cdata, size)) { -			r = -EFAULT; -			goto out; +			ret = -EFAULT; +			goto free_partial_kdata;  		}  		switch (p->chunks[i].chunk_id) { @@ -238,15 +240,15 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)  				gobj = drm_gem_object_lookup(p->adev->ddev,  							     p->filp, handle);  				if (gobj == NULL) { -					r = -EINVAL; -					goto out; +					ret = -EINVAL; +					goto free_partial_kdata;  				}  				p->uf.bo = gem_to_amdgpu_bo(gobj);  				p->uf.offset = fence_data->offset;  			} else { -				r = -EINVAL; -				goto out; +				ret = -EINVAL; +				goto free_partial_kdata;  			}  			break; @@ -254,19 +256,35 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)  			break;  		default: -			r = -EINVAL; -			goto out; +			ret = -EINVAL; +			goto free_partial_kdata;  		}  	}  	p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL); -	if (!p->ibs) -		r = -ENOMEM; +	if (!p->ibs) { +		ret = -ENOMEM; +		goto free_all_kdata; +	} -out:  	kfree(chunk_array); -	return r; +	return 0; + +free_all_kdata: +	i = p->nchunks - 1; +free_partial_kdata: +	for (; i >= 0; i--) +		drm_free_large(p->chunks[i].kdata); +	kfree(p->chunks); +put_bo_list: +	if (p->bo_list) +		amdgpu_bo_list_put(p->bo_list); +	amdgpu_ctx_put(p->ctx); +free_chunk: +	kfree(chunk_array); + +	return ret;  }  /* Returns how many bytes TTM can move per IB. @@ -321,25 +339,17 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)  	return max(bytes_moved_threshold, 1024*1024ull);  } -int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p) +int amdgpu_cs_list_validate(struct amdgpu_device *adev, +			    struct amdgpu_vm *vm, +			    struct list_head *validated)  { -	struct amdgpu_fpriv *fpriv = p->filp->driver_priv; -	struct amdgpu_vm *vm = &fpriv->vm; -	struct amdgpu_device *adev = p->adev;  	struct amdgpu_bo_list_entry *lobj; -	struct list_head duplicates;  	struct amdgpu_bo *bo;  	u64 bytes_moved = 0, initial_bytes_moved;  	u64 bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(adev);  	int r; -	INIT_LIST_HEAD(&duplicates); -	r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates); -	if (unlikely(r != 0)) { -		return r; -	} - -	list_for_each_entry(lobj, &p->validated, tv.head) { +	list_for_each_entry(lobj, validated, tv.head) {  		bo = lobj->robj;  		if (!bo->pin_count) {  			u32 domain = lobj->prefered_domains; @@ -373,7 +383,6 @@ int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p)  					domain = lobj->allowed_domains;  					goto retry;  				} -				ttm_eu_backoff_reservation(&p->ticket, &p->validated);  				return r;  			}  		} @@ -386,6 +395,7 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)  {  	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;  	struct amdgpu_cs_buckets buckets; +	struct list_head duplicates;  	bool need_mmap_lock = false;  	int i, r; @@ -405,8 +415,22 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)  	if (need_mmap_lock)  		down_read(¤t->mm->mmap_sem); -	r = amdgpu_cs_list_validate(p); +	INIT_LIST_HEAD(&duplicates); +	r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates); +	if (unlikely(r != 0)) +		goto error_reserve; + +	r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated); +	if (r) +		goto error_validate; + +	r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &duplicates); + +error_validate: +	if (r) +		ttm_eu_backoff_reservation(&p->ticket, &p->validated); +error_reserve:  	if (need_mmap_lock)  		up_read(¤t->mm->mmap_sem); @@ -772,15 +796,15 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,  	return 0;  } -static int amdgpu_cs_free_job(struct amdgpu_job *sched_job) +static int amdgpu_cs_free_job(struct amdgpu_job *job)  {  	int i; -	if (sched_job->ibs) -		for (i = 0; i < sched_job->num_ibs; i++) -			amdgpu_ib_free(sched_job->adev, &sched_job->ibs[i]); -	kfree(sched_job->ibs); -	if (sched_job->uf.bo) -		drm_gem_object_unreference_unlocked(&sched_job->uf.bo->gem_base); +	if (job->ibs) +		for (i = 0; i < job->num_ibs; i++) +			amdgpu_ib_free(job->adev, &job->ibs[i]); +	kfree(job->ibs); +	if (job->uf.bo) +		drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base);  	return 0;  } @@ -804,7 +828,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  	r = amdgpu_cs_parser_init(parser, data);  	if (r) {  		DRM_ERROR("Failed to initialize parser !\n"); -		amdgpu_cs_parser_fini(parser, r, false); +		kfree(parser);  		up_read(&adev->exclusive_lock);  		r = amdgpu_cs_handle_lockup(adev, r);  		return r; @@ -842,7 +866,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  		job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);  		if (!job)  			return -ENOMEM; -		job->base.sched = ring->scheduler; +		job->base.sched = &ring->sched;  		job->base.s_entity = &parser->ctx->rings[ring->idx].entity;  		job->adev = parser->adev;  		job->ibs = parser->ibs; @@ -857,7 +881,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  		job->free_job = amdgpu_cs_free_job;  		mutex_lock(&job->job_lock); -		r = amd_sched_entity_push_job((struct amd_sched_job *)job); +		r = amd_sched_entity_push_job(&job->base);  		if (r) {  			mutex_unlock(&job->job_lock);  			amdgpu_cs_free_job(job); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 20cbc4eb5a6f..e0b80ccdfe8a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -43,10 +43,10 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,  		for (i = 0; i < adev->num_rings; i++) {  			struct amd_sched_rq *rq;  			if (kernel) -				rq = &adev->rings[i]->scheduler->kernel_rq; +				rq = &adev->rings[i]->sched.kernel_rq;  			else -				rq = &adev->rings[i]->scheduler->sched_rq; -			r = amd_sched_entity_init(adev->rings[i]->scheduler, +				rq = &adev->rings[i]->sched.sched_rq; +			r = amd_sched_entity_init(&adev->rings[i]->sched,  						  &ctx->rings[i].entity,  						  rq, amdgpu_sched_jobs);  			if (r) @@ -55,7 +55,7 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, bool kernel,  		if (i < adev->num_rings) {  			for (j = 0; j < i; j++) -				amd_sched_entity_fini(adev->rings[j]->scheduler, +				amd_sched_entity_fini(&adev->rings[j]->sched,  						      &ctx->rings[j].entity);  			kfree(ctx);  			return r; @@ -75,7 +75,7 @@ void amdgpu_ctx_fini(struct amdgpu_ctx *ctx)  	if (amdgpu_enable_scheduler) {  		for (i = 0; i < adev->num_rings; i++) -			amd_sched_entity_fini(adev->rings[i]->scheduler, +			amd_sched_entity_fini(&adev->rings[i]->sched,  					      &ctx->rings[i].entity);  	}  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 6ff6ae945794..6068d8207d10 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -246,7 +246,7 @@ static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)  		r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,  				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,  				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -				     NULL, &adev->vram_scratch.robj); +				     NULL, NULL, &adev->vram_scratch.robj);  		if (r) {  			return r;  		} @@ -449,7 +449,8 @@ static int amdgpu_wb_init(struct amdgpu_device *adev)  	if (adev->wb.wb_obj == NULL) {  		r = amdgpu_bo_create(adev, AMDGPU_MAX_WB * 4, PAGE_SIZE, true, -				     AMDGPU_GEM_DOMAIN_GTT, 0,  NULL, &adev->wb.wb_obj); +				     AMDGPU_GEM_DOMAIN_GTT, 0,  NULL, NULL, +				     &adev->wb.wb_obj);  		if (r) {  			dev_warn(adev->dev, "(%d) create WB bo failed\n", r);  			return r; @@ -1650,9 +1651,11 @@ int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)  	drm_kms_helper_poll_disable(dev);  	/* turn off display hw */ +	drm_modeset_lock_all(dev);  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {  		drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);  	} +	drm_modeset_unlock_all(dev);  	/* unpin the front buffers */  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -1747,9 +1750,11 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon)  	if (fbcon) {  		drm_helper_resume_force_mode(dev);  		/* turn on display hw */ +		drm_modeset_lock_all(dev);  		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {  			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);  		} +		drm_modeset_unlock_all(dev);  	}  	drm_kms_helper_poll_enable(dev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e3d70772b531..6c9e0902a414 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -85,8 +85,6 @@ static void amdgpu_flip_work_func(struct work_struct *__work)  	/* We borrow the event spin lock for protecting flip_status */  	spin_lock_irqsave(&crtc->dev->event_lock, flags); -	/* set the proper interrupt */ -	amdgpu_irq_get(adev, &adev->pageflip_irq, work->crtc_id);  	/* do the flip (mmio) */  	adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);  	/* set the flip status */ @@ -186,10 +184,6 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,  		goto cleanup;  	} -	fence_get(work->excl); -	for (i = 0; i < work->shared_count; ++i) -		fence_get(work->shared[i]); -  	amdgpu_bo_get_tiling_flags(new_rbo, &tiling_flags);  	amdgpu_bo_unreserve(new_rbo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 0fcc0bd1622c..b190c2a83680 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -79,6 +79,7 @@ int amdgpu_exp_hw_support = 0;  int amdgpu_enable_scheduler = 0;  int amdgpu_sched_jobs = 16;  int amdgpu_sched_hw_submission = 2; +int amdgpu_enable_semaphores = 1;  MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");  module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); @@ -152,6 +153,9 @@ module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444);  MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default 2)");  module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); +MODULE_PARM_DESC(enable_semaphores, "Enable semaphores (1 = enable (default), 0 = disable)"); +module_param_named(enable_semaphores, amdgpu_enable_semaphores, int, 0644); +  static struct pci_device_id pciidlist[] = {  #ifdef CONFIG_DRM_AMDGPU_CIK  	/* Kaveri */ @@ -238,11 +242,11 @@ static struct pci_device_id pciidlist[] = {  	{0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|AMD_IS_MOBILITY|AMD_IS_APU},  #endif  	/* topaz */ -	{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, -	{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, -	{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, -	{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, -	{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ}, +	{0x1002, 0x6900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, +	{0x1002, 0x6901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, +	{0x1002, 0x6902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, +	{0x1002, 0x6903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT}, +	{0x1002, 0x6907, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TOPAZ|AMD_EXP_HW_SUPPORT},  	/* tonga */  	{0x1002, 0x6920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA},  	{0x1002, 0x6921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TONGA}, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 8a122b1b7786..96290d9cddca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -402,3 +402,19 @@ bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)  		return true;  	return false;  } + +void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev) +{ +	struct amdgpu_fbdev *afbdev = adev->mode_info.rfbdev; +	struct drm_fb_helper *fb_helper; +	int ret; + +	if (!afbdev) +		return; + +	fb_helper = &afbdev->helper; + +	ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); +	if (ret) +		DRM_DEBUG("failed to restore crtc mode\n"); +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 1be2bd6d07ea..b3fc26c59787 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -609,9 +609,9 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,   * Init the fence driver for the requested ring (all asics).   * Helper function for amdgpu_fence_driver_init().   */ -void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring) +int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring)  { -	int i; +	int i, r;  	ring->fence_drv.cpu_addr = NULL;  	ring->fence_drv.gpu_addr = 0; @@ -625,15 +625,19 @@ void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring)  			amdgpu_fence_check_lockup);  	ring->fence_drv.ring = ring; +	init_waitqueue_head(&ring->fence_drv.fence_queue); +  	if (amdgpu_enable_scheduler) { -		ring->scheduler = amd_sched_create(&amdgpu_sched_ops, -						   ring->idx, -						   amdgpu_sched_hw_submission, -						   (void *)ring->adev); -		if (!ring->scheduler) -			DRM_ERROR("Failed to create scheduler on ring %d.\n", -				  ring->idx); +		r = amd_sched_init(&ring->sched, &amdgpu_sched_ops, +				   amdgpu_sched_hw_submission, ring->name); +		if (r) { +			DRM_ERROR("Failed to create scheduler on ring %s.\n", +				  ring->name); +			return r; +		}  	} + +	return 0;  }  /** @@ -681,8 +685,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)  		wake_up_all(&ring->fence_drv.fence_queue);  		amdgpu_irq_put(adev, ring->fence_drv.irq_src,  			       ring->fence_drv.irq_type); -		if (ring->scheduler) -			amd_sched_destroy(ring->scheduler); +		amd_sched_fini(&ring->sched);  		ring->fence_drv.initialized = false;  	}  	mutex_unlock(&adev->ring_lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index cbd3a486c5c2..7312d729d300 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -127,7 +127,7 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)  		r = amdgpu_bo_create(adev, adev->gart.table_size,  				     PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,  				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -				     NULL, &adev->gart.robj); +				     NULL, NULL, &adev->gart.robj);  		if (r) {  			return r;  		} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 5839fab374bf..7297ca3a0ba7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -69,7 +69,8 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,  		}  	}  retry: -	r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, flags, NULL, &robj); +	r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, +			     flags, NULL, NULL, &robj);  	if (r) {  		if (r != -ERESTARTSYS) {  			if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { @@ -426,6 +427,10 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,  					   &args->data.data_size_bytes,  					   &args->data.flags);  	} else if (args->op == AMDGPU_GEM_METADATA_OP_SET_METADATA) { +		if (args->data.data_size_bytes > sizeof(args->data.data)) { +			r = -EINVAL; +			goto unreserve; +		}  		r = amdgpu_bo_set_tiling_flags(robj, args->data.tiling_info);  		if (!r)  			r = amdgpu_bo_set_metadata(robj, args->data.data, @@ -433,6 +438,7 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,  						   args->data.flags);  	} +unreserve:  	amdgpu_bo_unreserve(robj);  out:  	drm_gem_object_unreference_unlocked(gobj); @@ -454,11 +460,12 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,  	struct ttm_validate_buffer tv, *entry;  	struct amdgpu_bo_list_entry *vm_bos;  	struct ww_acquire_ctx ticket; -	struct list_head list; +	struct list_head list, duplicates;  	unsigned domain;  	int r;  	INIT_LIST_HEAD(&list); +	INIT_LIST_HEAD(&duplicates);  	tv.bo = &bo_va->bo->tbo;  	tv.shared = true; @@ -468,7 +475,8 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,  	if (!vm_bos)  		return; -	r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); +	/* Provide duplicates to avoid -EALREADY */ +	r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);  	if (r)  		goto error_free; @@ -651,7 +659,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,  	int r;  	args->pitch = amdgpu_align_pitch(adev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); -	args->size = args->pitch * args->height; +	args->size = (u64)args->pitch * args->height;  	args->size = ALIGN(args->size, PAGE_SIZE);  	r = amdgpu_gem_object_create(adev, args->size, 0, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 5c8a803acedc..534fc04e80fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -43,7 +43,7 @@ static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev)  		r = amdgpu_bo_create(adev, adev->irq.ih.ring_size,  				     PAGE_SIZE, true,  				     AMDGPU_GEM_DOMAIN_GTT, 0, -				     NULL, &adev->irq.ih.ring_obj); +				     NULL, NULL, &adev->irq.ih.ring_obj);  		if (r) {  			DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r);  			return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 0aba8e9bc8a0..7c42ff670080 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -140,7 +140,7 @@ void amdgpu_irq_preinstall(struct drm_device *dev)   */  int amdgpu_irq_postinstall(struct drm_device *dev)  { -	dev->max_vblank_count = 0x001fffff; +	dev->max_vblank_count = 0x00ffffff;  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 22367939ebf1..5d11e798230c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -390,7 +390,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  				    min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0;  	}  	case AMDGPU_INFO_READ_MMR_REG: { -		unsigned n, alloc_size = info->read_mmr_reg.count * 4; +		unsigned n, alloc_size;  		uint32_t *regs;  		unsigned se_num = (info->read_mmr_reg.instance >>  				   AMDGPU_INFO_MMR_SE_INDEX_SHIFT) & @@ -406,9 +406,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  		if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)  			sh_num = 0xffffffff; -		regs = kmalloc(alloc_size, GFP_KERNEL); +		regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL);  		if (!regs)  			return -ENOMEM; +		alloc_size = info->read_mmr_reg.count * sizeof(*regs);  		for (i = 0; i < info->read_mmr_reg.count; i++)  			if (amdgpu_asic_read_register(adev, se_num, sh_num, @@ -484,7 +485,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file   * Outdated mess for old drm with Xorg being in charge (void function now).   */  /** - * amdgpu_driver_firstopen_kms - drm callback for last close + * amdgpu_driver_lastclose_kms - drm callback for last close   *   * @dev: drm dev pointer   * @@ -492,6 +493,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file   */  void amdgpu_driver_lastclose_kms(struct drm_device *dev)  { +	struct amdgpu_device *adev = dev->dev_private; + +	amdgpu_fbdev_restore_mode(adev);  	vga_switcheroo_process_delayed_switch();  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 64efe5b52e65..7bd470d9ac30 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -567,6 +567,7 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev);  void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state);  int amdgpu_fbdev_total_size(struct amdgpu_device *adev);  bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj); +void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev);  void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 08b09d55b96f..1a7708f365f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -215,6 +215,7 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,  				bool kernel, u32 domain, u64 flags,  				struct sg_table *sg,  				struct ttm_placement *placement, +				struct reservation_object *resv,  				struct amdgpu_bo **bo_ptr)  {  	struct amdgpu_bo *bo; @@ -261,7 +262,7 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,  	/* Kernel allocation are uninterruptible */  	r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type,  			&bo->placement, page_align, !kernel, NULL, -			acc_size, sg, NULL, &amdgpu_ttm_bo_destroy); +			acc_size, sg, resv, &amdgpu_ttm_bo_destroy);  	if (unlikely(r != 0)) {  		return r;  	} @@ -275,7 +276,9 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,  int amdgpu_bo_create(struct amdgpu_device *adev,  		     unsigned long size, int byte_align,  		     bool kernel, u32 domain, u64 flags, -		     struct sg_table *sg, struct amdgpu_bo **bo_ptr) +		     struct sg_table *sg, +		     struct reservation_object *resv, +		     struct amdgpu_bo **bo_ptr)  {  	struct ttm_placement placement = {0};  	struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; @@ -286,11 +289,9 @@ int amdgpu_bo_create(struct amdgpu_device *adev,  	amdgpu_ttm_placement_init(adev, &placement,  				  placements, domain, flags); -	return amdgpu_bo_create_restricted(adev, size, byte_align, -					   kernel, domain, flags, -					   sg, -					   &placement, -					   bo_ptr); +	return amdgpu_bo_create_restricted(adev, size, byte_align, kernel, +					   domain, flags, sg, &placement, +					   resv, bo_ptr);  }  int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) @@ -535,12 +536,10 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata,  	if (metadata == NULL)  		return -EINVAL; -	buffer = kzalloc(metadata_size, GFP_KERNEL); +	buffer = kmemdup(metadata, metadata_size, GFP_KERNEL);  	if (buffer == NULL)  		return -ENOMEM; -	memcpy(buffer, metadata, metadata_size); -  	kfree(bo->metadata);  	bo->metadata_flags = flags;  	bo->metadata = buffer; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 6ea18dcec561..3c2ff4567798 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -129,12 +129,14 @@ int amdgpu_bo_create(struct amdgpu_device *adev,  			    unsigned long size, int byte_align,  			    bool kernel, u32 domain, u64 flags,  			    struct sg_table *sg, +			    struct reservation_object *resv,  			    struct amdgpu_bo **bo_ptr);  int amdgpu_bo_create_restricted(struct amdgpu_device *adev,  				unsigned long size, int byte_align,  				bool kernel, u32 domain, u64 flags,  				struct sg_table *sg,  				struct ttm_placement *placement, +			        struct reservation_object *resv,  				struct amdgpu_bo **bo_ptr);  int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr);  void amdgpu_bo_kunmap(struct amdgpu_bo *bo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index efed11509f4a..22a8c7d3a3ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -294,10 +294,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,  	struct amdgpu_device *adev = dev_get_drvdata(dev);  	umode_t effective_mode = attr->mode; -	/* Skip limit attributes if DPM is not enabled */ +	/* Skip attributes if DPM is not enabled */  	if (!adev->pm.dpm_enabled &&  	    (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr || -	     attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr)) +	     attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr || +	     attr == &sensor_dev_attr_pwm1.dev_attr.attr || +	     attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr || +	     attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || +	     attr == &sensor_dev_attr_pwm1_min.dev_attr.attr))  		return 0;  	/* Skip fan attributes if fan is not present */ @@ -691,6 +695,9 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)  {  	int ret; +	if (adev->pm.sysfs_initialized) +		return 0; +  	if (adev->pm.funcs->get_temperature == NULL)  		return 0;  	adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, @@ -719,6 +726,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)  		return ret;  	} +	adev->pm.sysfs_initialized = true; +  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index d9652fe32d6a..59f735a933a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -61,12 +61,15 @@ struct drm_gem_object *amdgpu_gem_prime_import_sg_table(struct drm_device *dev,  							struct dma_buf_attachment *attach,  							struct sg_table *sg)  { +	struct reservation_object *resv = attach->dmabuf->resv;  	struct amdgpu_device *adev = dev->dev_private;  	struct amdgpu_bo *bo;  	int ret; +	ww_mutex_lock(&resv->lock, NULL);  	ret = amdgpu_bo_create(adev, attach->dmabuf->size, PAGE_SIZE, false, -			       AMDGPU_GEM_DOMAIN_GTT, 0, sg, &bo); +			       AMDGPU_GEM_DOMAIN_GTT, 0, sg, resv, &bo); +	ww_mutex_unlock(&resv->lock);  	if (ret)  		return ERR_PTR(ret); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 9bec91484c24..30dce235ddeb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -357,11 +357,11 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,  		ring->adev = adev;  		ring->idx = adev->num_rings++;  		adev->rings[ring->idx] = ring; -		amdgpu_fence_driver_init_ring(ring); +		r = amdgpu_fence_driver_init_ring(ring); +		if (r) +			return r;  	} -	init_waitqueue_head(&ring->fence_drv.fence_queue); -  	r = amdgpu_wb_get(adev, &ring->rptr_offs);  	if (r) {  		dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r); @@ -407,7 +407,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,  	if (ring->ring_obj == NULL) {  		r = amdgpu_bo_create(adev, ring->ring_size, PAGE_SIZE, true,  				     AMDGPU_GEM_DOMAIN_GTT, 0, -				     NULL, &ring->ring_obj); +				     NULL, NULL, &ring->ring_obj);  		if (r) {  			dev_err(adev->dev, "(%d) ring create failed\n", r);  			return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 74dad270362c..e90712443fe9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c @@ -64,8 +64,8 @@ int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev,  		INIT_LIST_HEAD(&sa_manager->flist[i]);  	} -	r = amdgpu_bo_create(adev, size, align, true, -			     domain, 0, NULL, &sa_manager->bo); +	r = amdgpu_bo_create(adev, size, align, true, domain, +			     0, NULL, NULL, &sa_manager->bo);  	if (r) {  		dev_err(adev->dev, "(%d) failed to allocate bo for manager\n", r);  		return r; @@ -145,8 +145,13 @@ static uint32_t amdgpu_sa_get_ring_from_fence(struct fence *f)  	struct amd_sched_fence *s_fence;  	s_fence = to_amd_sched_fence(f); -	if (s_fence) -		return s_fence->scheduler->ring_id; +	if (s_fence) { +		struct amdgpu_ring *ring; + +		ring = container_of(s_fence->sched, struct amdgpu_ring, sched); +		return ring->idx; +	} +  	a_fence = to_amdgpu_fence(f);  	if (a_fence)  		return a_fence->ring->idx; @@ -412,6 +417,26 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo,  }  #if defined(CONFIG_DEBUG_FS) + +static void amdgpu_sa_bo_dump_fence(struct fence *fence, struct seq_file *m) +{ +	struct amdgpu_fence *a_fence = to_amdgpu_fence(fence); +	struct amd_sched_fence *s_fence = to_amd_sched_fence(fence); + +	if (a_fence) +		seq_printf(m, " protected by 0x%016llx on ring %d", +			   a_fence->seq, a_fence->ring->idx); + +	if (s_fence) { +		struct amdgpu_ring *ring; + + +		ring = container_of(s_fence->sched, struct amdgpu_ring, sched); +		seq_printf(m, " protected by 0x%016x on ring %d", +			   s_fence->base.seqno, ring->idx); +	} +} +  void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,  				  struct seq_file *m)  { @@ -428,18 +453,8 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,  		}  		seq_printf(m, "[0x%010llx 0x%010llx] size %8lld",  			   soffset, eoffset, eoffset - soffset); -		if (i->fence) { -			struct amdgpu_fence *a_fence = to_amdgpu_fence(i->fence); -			struct amd_sched_fence *s_fence = to_amd_sched_fence(i->fence); -			if (a_fence) -				seq_printf(m, " protected by 0x%016llx on ring %d", -					   a_fence->seq, a_fence->ring->idx); -			if (s_fence) -				seq_printf(m, " protected by 0x%016x on ring %d", -					   s_fence->base.seqno, -					   s_fence->scheduler->ring_id); - -		} +		if (i->fence) +			amdgpu_sa_bo_dump_fence(i->fence, m);  		seq_printf(m, "\n");  	}  	spin_unlock(&sa_manager->wq.lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index de98fbd2971e..2e946b2cad88 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -27,63 +27,48 @@  #include <drm/drmP.h>  #include "amdgpu.h" -static struct fence *amdgpu_sched_dependency(struct amd_sched_job *job) +static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job)  { -	struct amdgpu_job *sched_job = (struct amdgpu_job *)job; -	return amdgpu_sync_get_fence(&sched_job->ibs->sync); +	struct amdgpu_job *job = to_amdgpu_job(sched_job); +	return amdgpu_sync_get_fence(&job->ibs->sync);  } -static struct fence *amdgpu_sched_run_job(struct amd_sched_job *job) +static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job)  { -	struct amdgpu_job *sched_job; -	struct amdgpu_fence *fence; +	struct amdgpu_fence *fence = NULL; +	struct amdgpu_job *job;  	int r; -	if (!job) { +	if (!sched_job) {  		DRM_ERROR("job is null\n");  		return NULL;  	} -	sched_job = (struct amdgpu_job *)job; -	mutex_lock(&sched_job->job_lock); -	r = amdgpu_ib_schedule(sched_job->adev, -			       sched_job->num_ibs, -			       sched_job->ibs, -			       sched_job->base.owner); -	if (r) +	job = to_amdgpu_job(sched_job); +	mutex_lock(&job->job_lock); +	r = amdgpu_ib_schedule(job->adev, +			       job->num_ibs, +			       job->ibs, +			       job->base.owner); +	if (r) { +		DRM_ERROR("Error scheduling IBs (%d)\n", r);  		goto err; -	fence = amdgpu_fence_ref(sched_job->ibs[sched_job->num_ibs - 1].fence); - -	if (sched_job->free_job) -		sched_job->free_job(sched_job); +	} -	mutex_unlock(&sched_job->job_lock); -	return &fence->base; +	fence = amdgpu_fence_ref(job->ibs[job->num_ibs - 1].fence);  err: -	DRM_ERROR("Run job error\n"); -	mutex_unlock(&sched_job->job_lock); -	job->sched->ops->process_job(job); -	return NULL; -} +	if (job->free_job) +		job->free_job(job); -static void amdgpu_sched_process_job(struct amd_sched_job *job) -{ -	struct amdgpu_job *sched_job; - -	if (!job) { -		DRM_ERROR("job is null\n"); -		return; -	} -	sched_job = (struct amdgpu_job *)job; -	/* after processing job, free memory */ -	fence_put(&sched_job->base.s_fence->base); -	kfree(sched_job); +	mutex_unlock(&job->job_lock); +	fence_put(&job->base.s_fence->base); +	kfree(job); +	return fence ? &fence->base : NULL;  }  struct amd_sched_backend_ops amdgpu_sched_ops = {  	.dependency = amdgpu_sched_dependency,  	.run_job = amdgpu_sched_run_job, -	.process_job = amdgpu_sched_process_job  };  int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, @@ -100,7 +85,7 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,  			kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);  		if (!job)  			return -ENOMEM; -		job->base.sched = ring->scheduler; +		job->base.sched = &ring->sched;  		job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity;  		job->adev = adev;  		job->ibs = ibs; @@ -109,7 +94,7 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev,  		mutex_init(&job->job_lock);  		job->free_job = free_job;  		mutex_lock(&job->job_lock); -		r = amd_sched_entity_push_job((struct amd_sched_job *)job); +		r = amd_sched_entity_push_job(&job->base);  		if (r) {  			mutex_unlock(&job->job_lock);  			kfree(job); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index 068aeaff7183..4921de15b451 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -65,8 +65,14 @@ static bool amdgpu_sync_same_dev(struct amdgpu_device *adev, struct fence *f)  	if (a_fence)  		return a_fence->ring->adev == adev; -	if (s_fence) -		return (struct amdgpu_device *)s_fence->scheduler->priv == adev; + +	if (s_fence) { +		struct amdgpu_ring *ring; + +		ring = container_of(s_fence->sched, struct amdgpu_ring, sched); +		return ring->adev == adev; +	} +  	return false;  } @@ -251,6 +257,20 @@ int amdgpu_sync_wait(struct amdgpu_sync *sync)  		fence_put(e->fence);  		kfree(e);  	} + +	if (amdgpu_enable_semaphores) +		return 0; + +	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { +		struct amdgpu_fence *fence = sync->sync_to[i]; +		if (!fence) +			continue; + +		r = fence_wait(&fence->base, false); +		if (r) +			return r; +	} +  	return 0;  } @@ -285,7 +305,8 @@ int amdgpu_sync_rings(struct amdgpu_sync *sync,  			return -EINVAL;  		} -		if (amdgpu_enable_scheduler || (count >= AMDGPU_NUM_SYNCS)) { +		if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores || +		    (count >= AMDGPU_NUM_SYNCS)) {  			/* not enough room, wait manually */  			r = fence_wait(&fence->base, false);  			if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c index f80b1a43be8a..4865615e9c06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c @@ -59,8 +59,9 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)  		goto out_cleanup;  	} -	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, 0, -			     NULL, &vram_obj); +	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, +			     AMDGPU_GEM_DOMAIN_VRAM, 0, +			     NULL, NULL, &vram_obj);  	if (r) {  		DRM_ERROR("Failed to create VRAM object\n");  		goto out_cleanup; @@ -80,7 +81,8 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)  		struct fence *fence = NULL;  		r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, -				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, gtt_obj + i); +				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, +				     NULL, gtt_obj + i);  		if (r) {  			DRM_ERROR("Failed to create GTT object %d\n", i);  			goto out_lclean; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index b5abd5cde413..364cbe975332 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -861,7 +861,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)  	r = amdgpu_bo_create(adev, 256 * 1024, PAGE_SIZE, true,  			     AMDGPU_GEM_DOMAIN_VRAM,  			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			     NULL, &adev->stollen_vga_memory); +			     NULL, NULL, &adev->stollen_vga_memory);  	if (r) {  		return r;  	} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 482e66797ae6..5cc95f1a7dab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -247,7 +247,7 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)  	const struct common_firmware_header *header = NULL;  	err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true, -			AMDGPU_GEM_DOMAIN_GTT, 0, NULL, bo); +			AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, bo);  	if (err) {  		dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err);  		err = -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 2cf6c6b06e3b..d0312364d950 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -156,7 +156,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)  	r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true,  			     AMDGPU_GEM_DOMAIN_VRAM,  			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			     NULL, &adev->uvd.vcpu_bo); +			     NULL, NULL, &adev->uvd.vcpu_bo);  	if (r) {  		dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r);  		return r; @@ -543,46 +543,60 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,  		return -EINVAL;  	} -	if (msg_type == 1) { +	switch (msg_type) { +	case 0: +		/* it's a create msg, calc image size (width * height) */ +		amdgpu_bo_kunmap(bo); + +		/* try to alloc a new handle */ +		for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { +			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.handles[i], 0, handle)) { +				adev->uvd.filp[i] = ctx->parser->filp; +				return 0; +			} +		} + +		DRM_ERROR("No more free UVD handles!\n"); +		return -EINVAL; + +	case 1:  		/* it's a decode msg, calc buffer sizes */  		r = amdgpu_uvd_cs_msg_decode(msg, ctx->buf_sizes);  		amdgpu_bo_kunmap(bo);  		if (r)  			return r; -	} else if (msg_type == 2) { +		/* validate the handle */ +		for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { +			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 handle 0x%x!\n", handle); +		return -ENOENT; + +	case 2:  		/* it's a destroy msg, free the handle */  		for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i)  			atomic_cmpxchg(&adev->uvd.handles[i], handle, 0);  		amdgpu_bo_kunmap(bo);  		return 0; -	} else { -		/* it's a create msg */ -		amdgpu_bo_kunmap(bo); - -		if (msg_type != 0) { -			DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); -			return -EINVAL; -		} - -		/* it's a create msg, no special handling needed */ -	} - -	/* create or decode, validate the handle */ -	for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { -		if (atomic_read(&adev->uvd.handles[i]) == handle) -			return 0; -	} -	/* handle not found try to alloc a new one */ -	for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { -		if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) { -			adev->uvd.filp[i] = ctx->parser->filp; -			return 0; -		} +	default: +		DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); +		return -EINVAL;  	} - -	DRM_ERROR("No more free UVD handles!\n"); +	BUG();  	return -EINVAL;  } @@ -805,10 +819,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)  }  static int amdgpu_uvd_free_job( -	struct amdgpu_job *sched_job) +	struct amdgpu_job *job)  { -	amdgpu_ib_free(sched_job->adev, sched_job->ibs); -	kfree(sched_job->ibs); +	amdgpu_ib_free(job->adev, job->ibs); +	kfree(job->ibs);  	return 0;  } @@ -905,7 +919,7 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,  	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,  			     AMDGPU_GEM_DOMAIN_VRAM,  			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			     NULL, &bo); +			     NULL, NULL, &bo);  	if (r)  		return r; @@ -954,7 +968,7 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,  	r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true,  			     AMDGPU_GEM_DOMAIN_VRAM,  			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			     NULL, &bo); +			     NULL, NULL, &bo);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 3cab96c42aa8..74f2038ac747 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -143,7 +143,7 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)  	r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,  			     AMDGPU_GEM_DOMAIN_VRAM,  			     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			     NULL, &adev->vce.vcpu_bo); +			     NULL, NULL, &adev->vce.vcpu_bo);  	if (r) {  		dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);  		return r; @@ -342,10 +342,10 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)  }  static int amdgpu_vce_free_job( -	struct amdgpu_job *sched_job) +	struct amdgpu_job *job)  { -	amdgpu_ib_free(sched_job->adev, sched_job->ibs); -	kfree(sched_job->ibs); +	amdgpu_ib_free(job->adev, job->ibs); +	kfree(job->ibs);  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index f68b7cdc370a..53d551f2d839 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -316,12 +316,12 @@ static void amdgpu_vm_update_pages(struct amdgpu_device *adev,  	}  } -int amdgpu_vm_free_job(struct amdgpu_job *sched_job) +int amdgpu_vm_free_job(struct amdgpu_job *job)  {  	int i; -	for (i = 0; i < sched_job->num_ibs; i++) -		amdgpu_ib_free(sched_job->adev, &sched_job->ibs[i]); -	kfree(sched_job->ibs); +	for (i = 0; i < job->num_ibs; i++) +		amdgpu_ib_free(job->adev, &job->ibs[i]); +	kfree(job->ibs);  	return 0;  } @@ -455,8 +455,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,  		return -ENOMEM;  	r = amdgpu_ib_get(ring, NULL, ndw * 4, ib); -	if (r) +	if (r) { +		kfree(ib);  		return r; +	}  	ib->length_dw = 0;  	/* walk over the address space and update the page directory */ @@ -686,31 +688,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev,  }  /** - * amdgpu_vm_fence_pts - fence page tables after an update - * - * @vm: requested vm - * @start: start of GPU address range - * @end: end of GPU address range - * @fence: fence to use - * - * Fence the page tables in the range @start - @end (cayman+). - * - * Global and local mutex must be locked! - */ -static void amdgpu_vm_fence_pts(struct amdgpu_vm *vm, -				uint64_t start, uint64_t end, -				struct fence *fence) -{ -	unsigned i; - -	start >>= amdgpu_vm_block_size; -	end >>= amdgpu_vm_block_size; - -	for (i = start; i <= end; ++i) -		amdgpu_bo_fence(vm->page_tables[i].bo, fence, true); -} - -/**   * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table   *   * @adev: amdgpu_device pointer @@ -813,8 +790,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,  	if (r)  		goto error_free; -	amdgpu_vm_fence_pts(vm, mapping->it.start, -			    mapping->it.last + 1, f); +	amdgpu_bo_fence(vm->page_directory, f, true);  	if (fence) {  		fence_put(*fence);  		*fence = fence_get(f); @@ -855,7 +831,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,  	int r;  	if (mem) { -		addr = mem->start << PAGE_SHIFT; +		addr = (u64)mem->start << PAGE_SHIFT;  		if (mem->mem_type != TTM_PL_TT)  			addr += adev->vm_manager.vram_base_offset;  	} else { @@ -1089,6 +1065,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,  	/* walk over the address space and allocate the page tables */  	for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) { +		struct reservation_object *resv = vm->page_directory->tbo.resv;  		struct amdgpu_bo *pt;  		if (vm->page_tables[pt_idx].bo) @@ -1097,11 +1074,13 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,  		/* drop mutex to allocate and clear page table */  		mutex_unlock(&vm->mutex); +		ww_mutex_lock(&resv->lock, NULL);  		r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8,  				     AMDGPU_GPU_PAGE_SIZE, true,  				     AMDGPU_GEM_DOMAIN_VRAM,  				     AMDGPU_GEM_CREATE_NO_CPU_ACCESS, -				     NULL, &pt); +				     NULL, resv, &pt); +		ww_mutex_unlock(&resv->lock);  		if (r)  			goto error_free; @@ -1303,7 +1282,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)  	r = amdgpu_bo_create(adev, pd_size, align, true,  			     AMDGPU_GEM_DOMAIN_VRAM,  			     AMDGPU_GEM_CREATE_NO_CPU_ACCESS, -			     NULL, &vm->page_directory); +			     NULL, NULL, &vm->page_directory);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c index cd6edc40c9cd..1e0bba29e167 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -1279,8 +1279,7 @@ amdgpu_atombios_encoder_setup_dig(struct drm_encoder *encoder, int action)  			amdgpu_atombios_encoder_setup_dig_encoder(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);  		}  		if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) -			amdgpu_atombios_encoder_setup_dig_transmitter(encoder, -							       ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); +			amdgpu_atombios_encoder_set_backlight_level(amdgpu_encoder, dig->backlight_level);  		if (ext_encoder)  			amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder, ATOM_ENABLE);  	} else { diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 82e8d0730517..a1a35a5df8e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -6185,6 +6185,11 @@ static int ci_dpm_late_init(void *handle)  	if (!amdgpu_dpm)  		return 0; +	/* init the sysfs and debugfs files late */ +	ret = amdgpu_pm_sysfs_init(adev); +	if (ret) +		return ret; +  	ret = ci_set_temperature_range(adev);  	if (ret)  		return ret; @@ -6232,9 +6237,6 @@ static int ci_dpm_sw_init(void *handle)  	adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;  	if (amdgpu_dpm == 1)  		amdgpu_pm_print_power_states(adev); -	ret = amdgpu_pm_sysfs_init(adev); -	if (ret) -		goto dpm_failed;  	mutex_unlock(&adev->pm.mutex);  	DRM_INFO("amdgpu: dpm initialized\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 4b6ce74753cd..484710cfdf82 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -1567,6 +1567,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)  	int ret, i;  	u16 tmp16; +	if (pci_is_root_bus(adev->pdev->bus)) +		return; +  	if (amdgpu_pcie_gen2 == 0)  		return; diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 44fa96ad4709..2e3373ed4c94 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c @@ -596,6 +596,12 @@ static int cz_dpm_late_init(void *handle)  	struct amdgpu_device *adev = (struct amdgpu_device *)handle;  	if (amdgpu_dpm) { +		int ret; +		/* init the sysfs and debugfs files late */ +		ret = amdgpu_pm_sysfs_init(adev); +		if (ret) +			return ret; +  		/* powerdown unused blocks for now */  		cz_dpm_powergate_uvd(adev, true);  		cz_dpm_powergate_vce(adev, true); @@ -632,10 +638,6 @@ static int cz_dpm_sw_init(void *handle)  	if (amdgpu_dpm == 1)  		amdgpu_pm_print_power_states(adev); -	ret = amdgpu_pm_sysfs_init(adev); -	if (ret) -		goto dpm_init_failed; -  	mutex_unlock(&adev->pm.mutex);  	DRM_INFO("amdgpu: dpm initialized\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/cz_smc.c b/drivers/gpu/drm/amd/amdgpu/cz_smc.c index a72ffc7d6c26..e33180d3314a 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_smc.c @@ -814,7 +814,8 @@ int cz_smu_init(struct amdgpu_device *adev)  	* 3. map kernel virtual address  	*/  	ret = amdgpu_bo_create(adev, priv->toc_buffer.data_size, PAGE_SIZE, -				true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, toc_buf); +			       true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, +			       toc_buf);  	if (ret) {  		dev_err(adev->dev, "(%d) SMC TOC buffer allocation failed\n", ret); @@ -822,7 +823,8 @@ int cz_smu_init(struct amdgpu_device *adev)  	}  	ret = amdgpu_bo_create(adev, priv->smu_buffer.data_size, PAGE_SIZE, -				true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, smu_buf); +			       true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, +			       smu_buf);  	if (ret) {  		dev_err(adev->dev, "(%d) SMC Internal buffer allocation failed\n", ret); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index e4d101b1252a..d4c82b625727 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -255,6 +255,24 @@ static u32 dce_v10_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)  		return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);  } +static void dce_v10_0_pageflip_interrupt_init(struct amdgpu_device *adev) +{ +	unsigned i; + +	/* Enable pflip interrupts */ +	for (i = 0; i < adev->mode_info.num_crtc; i++) +		amdgpu_irq_get(adev, &adev->pageflip_irq, i); +} + +static void dce_v10_0_pageflip_interrupt_fini(struct amdgpu_device *adev) +{ +	unsigned i; + +	/* Disable pflip interrupts */ +	for (i = 0; i < adev->mode_info.num_crtc; i++) +		amdgpu_irq_put(adev, &adev->pageflip_irq, i); +} +  /**   * dce_v10_0_page_flip - pageflip callback.   * @@ -2663,9 +2681,10 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode)  		dce_v10_0_vga_enable(crtc, true);  		amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);  		dce_v10_0_vga_enable(crtc, false); -		/* Make sure VBLANK interrupt is still enabled */ +		/* Make sure VBLANK and PFLIP interrupts are still enabled */  		type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);  		amdgpu_irq_update(adev, &adev->crtc_irq, type); +		amdgpu_irq_update(adev, &adev->pageflip_irq, type);  		drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);  		dce_v10_0_crtc_load_lut(crtc);  		break; @@ -3025,6 +3044,8 @@ static int dce_v10_0_hw_init(void *handle)  		dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);  	} +	dce_v10_0_pageflip_interrupt_init(adev); +  	return 0;  } @@ -3039,6 +3060,8 @@ static int dce_v10_0_hw_fini(void *handle)  		dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);  	} +	dce_v10_0_pageflip_interrupt_fini(adev); +  	return 0;  } @@ -3050,6 +3073,8 @@ static int dce_v10_0_suspend(void *handle)  	dce_v10_0_hpd_fini(adev); +	dce_v10_0_pageflip_interrupt_fini(adev); +  	return 0;  } @@ -3075,6 +3100,8 @@ static int dce_v10_0_resume(void *handle)  	/* initialize hpd */  	dce_v10_0_hpd_init(adev); +	dce_v10_0_pageflip_interrupt_init(adev); +  	return 0;  } @@ -3369,7 +3396,6 @@ static int dce_v10_0_pageflip_irq(struct amdgpu_device *adev,  	spin_unlock_irqrestore(&adev->ddev->event_lock, flags);  	drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); -	amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);  	queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);  	return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 6411e8244671..7e1cf5e4eebf 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -233,6 +233,24 @@ static u32 dce_v11_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)  		return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);  } +static void dce_v11_0_pageflip_interrupt_init(struct amdgpu_device *adev) +{ +	unsigned i; + +	/* Enable pflip interrupts */ +	for (i = 0; i < adev->mode_info.num_crtc; i++) +		amdgpu_irq_get(adev, &adev->pageflip_irq, i); +} + +static void dce_v11_0_pageflip_interrupt_fini(struct amdgpu_device *adev) +{ +	unsigned i; + +	/* Disable pflip interrupts */ +	for (i = 0; i < adev->mode_info.num_crtc; i++) +		amdgpu_irq_put(adev, &adev->pageflip_irq, i); +} +  /**   * dce_v11_0_page_flip - pageflip callback.   * @@ -2640,9 +2658,10 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode)  		dce_v11_0_vga_enable(crtc, true);  		amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);  		dce_v11_0_vga_enable(crtc, false); -		/* Make sure VBLANK interrupt is still enabled */ +		/* Make sure VBLANK and PFLIP interrupts are still enabled */  		type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);  		amdgpu_irq_update(adev, &adev->crtc_irq, type); +		amdgpu_irq_update(adev, &adev->pageflip_irq, type);  		drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);  		dce_v11_0_crtc_load_lut(crtc);  		break; @@ -2888,7 +2907,7 @@ static int dce_v11_0_early_init(void *handle)  	switch (adev->asic_type) {  	case CHIP_CARRIZO: -		adev->mode_info.num_crtc = 4; +		adev->mode_info.num_crtc = 3;  		adev->mode_info.num_hpd = 6;  		adev->mode_info.num_dig = 9;  		break; @@ -3000,6 +3019,8 @@ static int dce_v11_0_hw_init(void *handle)  		dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);  	} +	dce_v11_0_pageflip_interrupt_init(adev); +  	return 0;  } @@ -3014,6 +3035,8 @@ static int dce_v11_0_hw_fini(void *handle)  		dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);  	} +	dce_v11_0_pageflip_interrupt_fini(adev); +  	return 0;  } @@ -3025,6 +3048,8 @@ static int dce_v11_0_suspend(void *handle)  	dce_v11_0_hpd_fini(adev); +	dce_v11_0_pageflip_interrupt_fini(adev); +  	return 0;  } @@ -3051,6 +3076,8 @@ static int dce_v11_0_resume(void *handle)  	/* initialize hpd */  	dce_v11_0_hpd_init(adev); +	dce_v11_0_pageflip_interrupt_init(adev); +  	return 0;  } @@ -3345,7 +3372,6 @@ static int dce_v11_0_pageflip_irq(struct amdgpu_device *adev,  	spin_unlock_irqrestore(&adev->ddev->event_lock, flags);  	drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); -	amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);  	queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);  	return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index c86911c2ea2a..34b9c2a9d8d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -204,6 +204,24 @@ static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc)  		return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);  } +static void dce_v8_0_pageflip_interrupt_init(struct amdgpu_device *adev) +{ +	unsigned i; + +	/* Enable pflip interrupts */ +	for (i = 0; i < adev->mode_info.num_crtc; i++) +		amdgpu_irq_get(adev, &adev->pageflip_irq, i); +} + +static void dce_v8_0_pageflip_interrupt_fini(struct amdgpu_device *adev) +{ +	unsigned i; + +	/* Disable pflip interrupts */ +	for (i = 0; i < adev->mode_info.num_crtc; i++) +		amdgpu_irq_put(adev, &adev->pageflip_irq, i); +} +  /**   * dce_v8_0_page_flip - pageflip callback.   * @@ -2575,9 +2593,10 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode)  		dce_v8_0_vga_enable(crtc, true);  		amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE);  		dce_v8_0_vga_enable(crtc, false); -		/* Make sure VBLANK interrupt is still enabled */ +		/* Make sure VBLANK and PFLIP interrupts are still enabled */  		type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id);  		amdgpu_irq_update(adev, &adev->crtc_irq, type); +		amdgpu_irq_update(adev, &adev->pageflip_irq, type);  		drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id);  		dce_v8_0_crtc_load_lut(crtc);  		break; @@ -2933,6 +2952,8 @@ static int dce_v8_0_hw_init(void *handle)  		dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);  	} +	dce_v8_0_pageflip_interrupt_init(adev); +  	return 0;  } @@ -2947,6 +2968,8 @@ static int dce_v8_0_hw_fini(void *handle)  		dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);  	} +	dce_v8_0_pageflip_interrupt_fini(adev); +  	return 0;  } @@ -2958,6 +2981,8 @@ static int dce_v8_0_suspend(void *handle)  	dce_v8_0_hpd_fini(adev); +	dce_v8_0_pageflip_interrupt_fini(adev); +  	return 0;  } @@ -2981,6 +3006,8 @@ static int dce_v8_0_resume(void *handle)  	/* initialize hpd */  	dce_v8_0_hpd_init(adev); +	dce_v8_0_pageflip_interrupt_init(adev); +  	return 0;  } @@ -3376,7 +3403,6 @@ static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev,  	spin_unlock_irqrestore(&adev->ddev->event_lock, flags);  	drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); -	amdgpu_irq_put(adev, &adev->pageflip_irq, crtc_id);  	queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work);  	return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c index 322edea65857..bda1249eb871 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c @@ -764,7 +764,7 @@ int fiji_smu_init(struct amdgpu_device *adev)  	ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,  			       true, AMDGPU_GEM_DOMAIN_VRAM,  			       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			       NULL, toc_buf); +			       NULL, NULL, toc_buf);  	if (ret) {  		DRM_ERROR("Failed to allocate memory for TOC buffer\n");  		return -ENOMEM; @@ -774,7 +774,7 @@ int fiji_smu_init(struct amdgpu_device *adev)  	ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE,  			       true, AMDGPU_GEM_DOMAIN_VRAM,  			       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			       NULL, smu_buf); +			       NULL, NULL, smu_buf);  	if (ret) {  		DRM_ERROR("Failed to allocate memory for SMU internal buffer\n");  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 4bd1e5cf65ca..e992bf2ff66c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -3206,7 +3206,7 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev)  		r = amdgpu_bo_create(adev,  				     adev->gfx.mec.num_mec *adev->gfx.mec.num_pipe * MEC_HPD_SIZE * 2,  				     PAGE_SIZE, true, -				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, +				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,  				     &adev->gfx.mec.hpd_eop_obj);  		if (r) {  			dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r); @@ -3373,7 +3373,7 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev)  			r = amdgpu_bo_create(adev,  					     sizeof(struct bonaire_mqd),  					     PAGE_SIZE, true, -					     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, +					     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,  					     &ring->mqd_obj);  			if (r) {  				dev_warn(adev->dev, "(%d) create MQD bo failed\n", r); @@ -3610,41 +3610,6 @@ static int gfx_v7_0_cp_resume(struct amdgpu_device *adev)  	return 0;  } -static void gfx_v7_0_ce_sync_me(struct amdgpu_ring *ring) -{ -	struct amdgpu_device *adev = ring->adev; -	u64 gpu_addr = adev->wb.gpu_addr + adev->gfx.ce_sync_offs * 4; - -	/* instruct DE to set a magic number */ -	amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); -	amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | -							 WRITE_DATA_DST_SEL(5))); -	amdgpu_ring_write(ring, gpu_addr & 0xfffffffc); -	amdgpu_ring_write(ring, upper_32_bits(gpu_addr) & 0xffffffff); -	amdgpu_ring_write(ring, 1); - -	/* let CE wait till condition satisfied */ -	amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); -	amdgpu_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */ -							 WAIT_REG_MEM_MEM_SPACE(1) | /* memory */ -							 WAIT_REG_MEM_FUNCTION(3) |  /* == */ -							 WAIT_REG_MEM_ENGINE(2)));   /* ce */ -	amdgpu_ring_write(ring, gpu_addr & 0xfffffffc); -	amdgpu_ring_write(ring, upper_32_bits(gpu_addr) & 0xffffffff); -	amdgpu_ring_write(ring, 1); -	amdgpu_ring_write(ring, 0xffffffff); -	amdgpu_ring_write(ring, 4); /* poll interval */ - -	/* instruct CE to reset wb of ce_sync to zero */ -	amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); -	amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(2) | -							 WRITE_DATA_DST_SEL(5) | -							 WR_CONFIRM)); -	amdgpu_ring_write(ring, gpu_addr & 0xfffffffc); -	amdgpu_ring_write(ring, upper_32_bits(gpu_addr) & 0xffffffff); -	amdgpu_ring_write(ring, 0); -} -  /*   * vm   * VMID 0 is the physical GPU addresses as used by the kernel. @@ -3663,6 +3628,13 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,  					unsigned vm_id, uint64_t pd_addr)  {  	int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX); +	if (usepfp) { +		/* synce CE with ME to prevent CE fetch CEIB before context switch done */ +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0); +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0); +	}  	amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));  	amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | @@ -3703,7 +3675,10 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,  		amdgpu_ring_write(ring, 0x0);  		/* synce CE with ME to prevent CE fetch CEIB before context switch done */ -		gfx_v7_0_ce_sync_me(ring); +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0); +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0);  	}  } @@ -3788,7 +3763,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,  					     AMDGPU_GEM_DOMAIN_VRAM,  					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -					     NULL, &adev->gfx.rlc.save_restore_obj); +					     NULL, NULL, +					     &adev->gfx.rlc.save_restore_obj);  			if (r) {  				dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", r);  				return r; @@ -3831,7 +3807,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)  			r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,  					     AMDGPU_GEM_DOMAIN_VRAM,  					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -					     NULL, &adev->gfx.rlc.clear_state_obj); +					     NULL, NULL, +					     &adev->gfx.rlc.clear_state_obj);  			if (r) {  				dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);  				gfx_v7_0_rlc_fini(adev); @@ -3870,7 +3847,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)  			r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,  					     AMDGPU_GEM_DOMAIN_VRAM,  					     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -					     NULL, &adev->gfx.rlc.cp_table_obj); +					     NULL, NULL, +					     &adev->gfx.rlc.cp_table_obj);  			if (r) {  				dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);  				gfx_v7_0_rlc_fini(adev); @@ -4802,12 +4780,6 @@ static int gfx_v7_0_sw_init(void *handle)  		return r;  	} -	r = amdgpu_wb_get(adev, &adev->gfx.ce_sync_offs); -	if (r) { -		DRM_ERROR("(%d) gfx.ce_sync_offs wb alloc failed\n", r); -		return r; -	} -  	for (i = 0; i < adev->gfx.num_gfx_rings; i++) {  		ring = &adev->gfx.gfx_ring[i];  		ring->ring_obj = NULL; @@ -4851,21 +4823,21 @@ static int gfx_v7_0_sw_init(void *handle)  	r = amdgpu_bo_create(adev, adev->gds.mem.gfx_partition_size,  			PAGE_SIZE, true,  			AMDGPU_GEM_DOMAIN_GDS, 0, -			NULL, &adev->gds.gds_gfx_bo); +			NULL, NULL, &adev->gds.gds_gfx_bo);  	if (r)  		return r;  	r = amdgpu_bo_create(adev, adev->gds.gws.gfx_partition_size,  		PAGE_SIZE, true,  		AMDGPU_GEM_DOMAIN_GWS, 0, -		NULL, &adev->gds.gws_gfx_bo); +		NULL, NULL, &adev->gds.gws_gfx_bo);  	if (r)  		return r;  	r = amdgpu_bo_create(adev, adev->gds.oa.gfx_partition_size,  			PAGE_SIZE, true,  			AMDGPU_GEM_DOMAIN_OA, 0, -			NULL, &adev->gds.oa_gfx_bo); +			NULL, NULL, &adev->gds.oa_gfx_bo);  	if (r)  		return r; @@ -4886,8 +4858,6 @@ static int gfx_v7_0_sw_fini(void *handle)  	for (i = 0; i < adev->gfx.num_compute_rings; i++)  		amdgpu_ring_fini(&adev->gfx.compute_ring[i]); -	amdgpu_wb_free(adev, adev->gfx.ce_sync_offs); -  	gfx_v7_0_cp_compute_fini(adev);  	gfx_v7_0_rlc_fini(adev);  	gfx_v7_0_mec_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 53f07439a512..cb4f68f53f24 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -868,7 +868,7 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev)  		r = amdgpu_bo_create(adev,  				     adev->gfx.mec.num_mec *adev->gfx.mec.num_pipe * MEC_HPD_SIZE * 2,  				     PAGE_SIZE, true, -				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, +				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,  				     &adev->gfx.mec.hpd_eop_obj);  		if (r) {  			dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r); @@ -940,12 +940,6 @@ static int gfx_v8_0_sw_init(void *handle)  		return r;  	} -	r = amdgpu_wb_get(adev, &adev->gfx.ce_sync_offs); -	if (r) { -		DRM_ERROR("(%d) gfx.ce_sync_offs wb alloc failed\n", r); -		return r; -	} -  	/* set up the gfx ring */  	for (i = 0; i < adev->gfx.num_gfx_rings; i++) {  		ring = &adev->gfx.gfx_ring[i]; @@ -995,21 +989,21 @@ static int gfx_v8_0_sw_init(void *handle)  	/* reserve GDS, GWS and OA resource for gfx */  	r = amdgpu_bo_create(adev, adev->gds.mem.gfx_partition_size,  			PAGE_SIZE, true, -			AMDGPU_GEM_DOMAIN_GDS, 0, +			AMDGPU_GEM_DOMAIN_GDS, 0, NULL,  			NULL, &adev->gds.gds_gfx_bo);  	if (r)  		return r;  	r = amdgpu_bo_create(adev, adev->gds.gws.gfx_partition_size,  		PAGE_SIZE, true, -		AMDGPU_GEM_DOMAIN_GWS, 0, +		AMDGPU_GEM_DOMAIN_GWS, 0, NULL,  		NULL, &adev->gds.gws_gfx_bo);  	if (r)  		return r;  	r = amdgpu_bo_create(adev, adev->gds.oa.gfx_partition_size,  			PAGE_SIZE, true, -			AMDGPU_GEM_DOMAIN_OA, 0, +			AMDGPU_GEM_DOMAIN_OA, 0, NULL,  			NULL, &adev->gds.oa_gfx_bo);  	if (r)  		return r; @@ -1033,8 +1027,6 @@ static int gfx_v8_0_sw_fini(void *handle)  	for (i = 0; i < adev->gfx.num_compute_rings; i++)  		amdgpu_ring_fini(&adev->gfx.compute_ring[i]); -	amdgpu_wb_free(adev, adev->gfx.ce_sync_offs); -  	gfx_v8_0_mec_fini(adev);  	return 0; @@ -3106,7 +3098,7 @@ static int gfx_v8_0_cp_compute_resume(struct amdgpu_device *adev)  					     sizeof(struct vi_mqd),  					     PAGE_SIZE, true,  					     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, -					     &ring->mqd_obj); +					     NULL, &ring->mqd_obj);  			if (r) {  				dev_warn(adev->dev, "(%d) create MQD bo failed\n", r);  				return r; @@ -3965,6 +3957,7 @@ static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr,  			  DATA_SEL(write64bit ? 2 : 1) | INT_SEL(int_sel ? 2 : 0));  	amdgpu_ring_write(ring, lower_32_bits(seq));  	amdgpu_ring_write(ring, upper_32_bits(seq)); +  }  /** @@ -4005,49 +3998,34 @@ static bool gfx_v8_0_ring_emit_semaphore(struct amdgpu_ring *ring,  	return true;  } -static void gfx_v8_0_ce_sync_me(struct amdgpu_ring *ring) +static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring, +					unsigned vm_id, uint64_t pd_addr)  { -	struct amdgpu_device *adev = ring->adev; -	u64 gpu_addr = adev->wb.gpu_addr + adev->gfx.ce_sync_offs * 4; - -	/* instruct DE to set a magic number */ -	amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); -	amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | -							 WRITE_DATA_DST_SEL(5))); -	amdgpu_ring_write(ring, gpu_addr & 0xfffffffc); -	amdgpu_ring_write(ring, upper_32_bits(gpu_addr) & 0xffffffff); -	amdgpu_ring_write(ring, 1); +	int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX); +	uint32_t seq = ring->fence_drv.sync_seq[ring->idx]; +	uint64_t addr = ring->fence_drv.gpu_addr; -	/* let CE wait till condition satisfied */  	amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); -	amdgpu_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */ -							 WAIT_REG_MEM_MEM_SPACE(1) | /* memory */ -							 WAIT_REG_MEM_FUNCTION(3) |  /* == */ -							 WAIT_REG_MEM_ENGINE(2)));   /* ce */ -	amdgpu_ring_write(ring, gpu_addr & 0xfffffffc); -	amdgpu_ring_write(ring, upper_32_bits(gpu_addr) & 0xffffffff); -	amdgpu_ring_write(ring, 1); +	amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */ +		 WAIT_REG_MEM_FUNCTION(3))); /* equal */ +	amdgpu_ring_write(ring, addr & 0xfffffffc); +	amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff); +	amdgpu_ring_write(ring, seq);  	amdgpu_ring_write(ring, 0xffffffff);  	amdgpu_ring_write(ring, 4); /* poll interval */ -	/* instruct CE to reset wb of ce_sync to zero */ -	amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); -	amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(2) | -							 WRITE_DATA_DST_SEL(5) | -							 WR_CONFIRM)); -	amdgpu_ring_write(ring, gpu_addr & 0xfffffffc); -	amdgpu_ring_write(ring, upper_32_bits(gpu_addr) & 0xffffffff); -	amdgpu_ring_write(ring, 0); -} - -static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring, -					unsigned vm_id, uint64_t pd_addr) -{ -	int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX); +	if (usepfp) { +		/* synce CE with ME to prevent CE fetch CEIB before context switch done */ +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0); +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0); +	}  	amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));  	amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | -				 WRITE_DATA_DST_SEL(0))); +				 WRITE_DATA_DST_SEL(0)) | +				 WR_CONFIRM);  	if (vm_id < 8) {  		amdgpu_ring_write(ring,  				  (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id)); @@ -4083,9 +4061,10 @@ static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring,  		/* sync PFP to ME, otherwise we might get invalid PFP reads */  		amdgpu_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));  		amdgpu_ring_write(ring, 0x0); - -		/* synce CE with ME to prevent CE fetch CEIB before context switch done */ -		gfx_v8_0_ce_sync_me(ring); +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0); +		amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); +		amdgpu_ring_write(ring, 0);  	}  } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 774528ab8704..fab5471d25d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1262,6 +1262,12 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev,  	addr = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_ADDR);  	status = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS);  	mc_client = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_MCCLIENT); +	/* reset addr and status */ +	WREG32_P(mmVM_CONTEXT1_CNTL2, 1, ~1); + +	if (!addr && !status) +		return 0; +  	dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n",  		entry->src_id, entry->src_data);  	dev_err(adev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n", @@ -1269,8 +1275,6 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev,  	dev_err(adev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",  		status);  	gmc_v7_0_vm_decode_fault(adev, status, addr, mc_client); -	/* reset addr and status */ -	WREG32_P(mmVM_CONTEXT1_CNTL2, 1, ~1);  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 9a07742620d0..7bc9e9fcf3d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1262,6 +1262,12 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,  	addr = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_ADDR);  	status = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS);  	mc_client = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_MCCLIENT); +	/* reset addr and status */ +	WREG32_P(mmVM_CONTEXT1_CNTL2, 1, ~1); + +	if (!addr && !status) +		return 0; +  	dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n",  		entry->src_id, entry->src_data);  	dev_err(adev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n", @@ -1269,8 +1275,6 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,  	dev_err(adev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",  		status);  	gmc_v8_0_vm_decode_fault(adev, status, addr, mc_client); -	/* reset addr and status */ -	WREG32_P(mmVM_CONTEXT1_CNTL2, 1, ~1);  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c index c900aa942ade..966d4b2ed9da 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c @@ -625,7 +625,7 @@ int iceland_smu_init(struct amdgpu_device *adev)  	ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,  			       true, AMDGPU_GEM_DOMAIN_VRAM,  			       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			       NULL, toc_buf); +			       NULL, NULL, toc_buf);  	if (ret) {  		DRM_ERROR("Failed to allocate memory for TOC buffer\n");  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index 94ec04a9c4d5..7e9154c7f1db 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -2995,6 +2995,15 @@ static int kv_dpm_late_init(void *handle)  {  	/* powerdown unused blocks for now */  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	int ret; + +	if (!amdgpu_dpm) +		return 0; + +	/* init the sysfs and debugfs files late */ +	ret = amdgpu_pm_sysfs_init(adev); +	if (ret) +		return ret;  	kv_dpm_powergate_acp(adev, true);  	kv_dpm_powergate_samu(adev, true); @@ -3038,9 +3047,6 @@ static int kv_dpm_sw_init(void *handle)  	adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;  	if (amdgpu_dpm == 1)  		amdgpu_pm_print_power_states(adev); -	ret = amdgpu_pm_sysfs_init(adev); -	if (ret) -		goto dpm_failed;  	mutex_unlock(&adev->pm.mutex);  	DRM_INFO("amdgpu: dpm initialized\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c index 1f5ac941a610..5421309c1862 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c @@ -763,7 +763,7 @@ int tonga_smu_init(struct amdgpu_device *adev)  	ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,  			       true, AMDGPU_GEM_DOMAIN_VRAM,  			       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			       NULL, toc_buf); +			       NULL, NULL, toc_buf);  	if (ret) {  		DRM_ERROR("Failed to allocate memory for TOC buffer\n");  		return -ENOMEM; @@ -773,7 +773,7 @@ int tonga_smu_init(struct amdgpu_device *adev)  	ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE,  			       true, AMDGPU_GEM_DOMAIN_VRAM,  			       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, -			       NULL, smu_buf); +			       NULL, NULL, smu_buf);  	if (ret) {  		DRM_ERROR("Failed to allocate memory for SMU internal buffer\n");  		return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 5fac5da694f0..ed50dd725788 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle)  	int r;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	r = uvd_v4_2_hw_fini(adev); +	r = amdgpu_uvd_suspend(adev);  	if (r)  		return r; -	r = amdgpu_uvd_suspend(adev); +	r = uvd_v4_2_hw_fini(adev);  	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 2d5c59c318af..9ad8b9906c0b 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle)  	int r;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	r = uvd_v5_0_hw_fini(adev); +	r = amdgpu_uvd_suspend(adev);  	if (r)  		return r; -	r = amdgpu_uvd_suspend(adev); +	r = uvd_v5_0_hw_fini(adev);  	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 d9f553fce531..7e9934fa4193 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -214,14 +214,16 @@ static int uvd_v6_0_suspend(void *handle)  	int r;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	/* Skip this for APU for now */ +	if (!(adev->flags & AMD_IS_APU)) { +		r = amdgpu_uvd_suspend(adev); +		if (r) +			return r; +	}  	r = uvd_v6_0_hw_fini(adev);  	if (r)  		return r; -	r = amdgpu_uvd_suspend(adev); -	if (r) -		return r; -  	return r;  } @@ -230,10 +232,12 @@ static int uvd_v6_0_resume(void *handle)  	int r;  	struct amdgpu_device *adev = (struct amdgpu_device *)handle; -	r = amdgpu_uvd_resume(adev); -	if (r) -		return r; - +	/* Skip this for APU for now */ +	if (!(adev->flags & AMD_IS_APU)) { +		r = amdgpu_uvd_resume(adev); +		if (r) +			return r; +	}  	r = uvd_v6_0_hw_init(adev);  	if (r)  		return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 552d9e75ad1b..0bac8702e934 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -1005,6 +1005,9 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev)  	u32 mask;  	int ret; +	if (pci_is_root_bus(adev->pdev->bus)) +		return; +  	if (amdgpu_pcie_gen2 == 0)  		return; @@ -1400,7 +1403,8 @@ static int vi_common_early_init(void *handle)  	case CHIP_CARRIZO:  		adev->has_uvd = true;  		adev->cg_flags = 0; -		adev->pg_flags = AMDGPU_PG_SUPPORT_UVD | AMDGPU_PG_SUPPORT_VCE; +		/* Disable UVD pg */ +		adev->pg_flags = /* AMDGPU_PG_SUPPORT_UVD | */AMDGPU_PG_SUPPORT_VCE;  		adev->external_rev_id = adev->rev_id + 0x1;  		if (amdgpu_smc_load_fw && smc_enabled)  			adev->firmware.smu_load = true;  | 

