diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 96 | 
1 files changed, 94 insertions, 2 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 9ddbf1494326..da48b6da0107 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -98,6 +98,26 @@ static int amdgpu_mes_doorbell_init(struct amdgpu_device *adev)  	return 0;  } +static int amdgpu_mes_event_log_init(struct amdgpu_device *adev) +{ +	int r; + +	r = amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE, +				    AMDGPU_GEM_DOMAIN_GTT, +				    &adev->mes.event_log_gpu_obj, +				    &adev->mes.event_log_gpu_addr, +				    &adev->mes.event_log_cpu_addr); +	if (r) { +		dev_warn(adev->dev, "failed to create MES event log buffer (%d)", r); +		return r; +	} + +	memset(adev->mes.event_log_cpu_addr, 0, PAGE_SIZE); + +	return  0; + +} +  static void amdgpu_mes_doorbell_free(struct amdgpu_device *adev)  {  	bitmap_free(adev->mes.doorbell_bitmap); @@ -182,8 +202,14 @@ int amdgpu_mes_init(struct amdgpu_device *adev)  	if (r)  		goto error; +	r = amdgpu_mes_event_log_init(adev); +	if (r) +		goto error_doorbell; +  	return 0; +error_doorbell: +	amdgpu_mes_doorbell_free(adev);  error:  	amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);  	amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs); @@ -199,6 +225,10 @@ error_ids:  void amdgpu_mes_fini(struct amdgpu_device *adev)  { +	amdgpu_bo_free_kernel(&adev->mes.event_log_gpu_obj, +			      &adev->mes.event_log_gpu_addr, +			      &adev->mes.event_log_cpu_addr); +  	amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);  	amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);  	amdgpu_device_wb_free(adev, adev->mes.read_val_offs); @@ -886,6 +916,11 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,  	op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER;  	op_input.set_shader_debugger.process_context_addr = process_context_addr;  	op_input.set_shader_debugger.flags.u32all = flags; + +	/* use amdgpu mes_flush_shader_debugger instead */ +	if (op_input.set_shader_debugger.flags.process_ctx_flush) +		return -EINVAL; +  	op_input.set_shader_debugger.spi_gdbg_per_vmid_cntl = spi_gdbg_per_vmid_cntl;  	memcpy(op_input.set_shader_debugger.tcp_watch_cntl, tcp_watch_cntl,  			sizeof(op_input.set_shader_debugger.tcp_watch_cntl)); @@ -905,6 +940,32 @@ int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev,  	return r;  } +int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, +				     uint64_t process_context_addr) +{ +	struct mes_misc_op_input op_input = {0}; +	int r; + +	if (!adev->mes.funcs->misc_op) { +		DRM_ERROR("mes flush shader debugger is not supported!\n"); +		return -EINVAL; +	} + +	op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; +	op_input.set_shader_debugger.process_context_addr = process_context_addr; +	op_input.set_shader_debugger.flags.process_ctx_flush = true; + +	amdgpu_mes_lock(&adev->mes); + +	r = adev->mes.funcs->misc_op(&adev->mes, &op_input); +	if (r) +		DRM_ERROR("failed to set_shader_debugger\n"); + +	amdgpu_mes_unlock(&adev->mes); + +	return r; +} +  static void  amdgpu_mes_ring_to_queue_props(struct amdgpu_device *adev,  			       struct amdgpu_ring *ring, @@ -1122,7 +1183,7 @@ int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev,  	amdgpu_sync_create(&sync); -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	drm_exec_until_all_locked(&exec) {  		r = drm_exec_lock_obj(&exec,  				      &ctx_data->meta_data_obj->tbo.base); @@ -1193,7 +1254,7 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,  	struct drm_exec exec;  	long r; -	drm_exec_init(&exec, 0); +	drm_exec_init(&exec, 0, 0);  	drm_exec_until_all_locked(&exec) {  		r = drm_exec_lock_obj(&exec,  				      &ctx_data->meta_data_obj->tbo.base); @@ -1479,3 +1540,34 @@ out:  	amdgpu_ucode_release(&adev->mes.fw[pipe]);  	return r;  } + +#if defined(CONFIG_DEBUG_FS) + +static int amdgpu_debugfs_mes_event_log_show(struct seq_file *m, void *unused) +{ +	struct amdgpu_device *adev = m->private; +	uint32_t *mem = (uint32_t *)(adev->mes.event_log_cpu_addr); + +	seq_hex_dump(m, "", DUMP_PREFIX_OFFSET, 32, 4, +		     mem, PAGE_SIZE, false); + +	return 0; +} + + +DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_mes_event_log); + +#endif + +void amdgpu_debugfs_mes_event_log_init(struct amdgpu_device *adev) +{ + +#if defined(CONFIG_DEBUG_FS) +	struct drm_minor *minor = adev_to_drm(adev)->primary; +	struct dentry *root = minor->debugfs_root; + +	debugfs_create_file("amdgpu_mes_event_log", 0444, root, +			    adev, &amdgpu_debugfs_mes_event_log_fops); + +#endif +} | 
