diff options
| author | Mark Brown <broonie@kernel.org> | 2016-11-04 21:16:38 +0300 | 
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2016-11-04 21:16:38 +0300 | 
| commit | cc9b94029e9ef51787af908e9856b1eed314bc00 (patch) | |
| tree | 9675310b89d0f6fb1f7bd9423f0638c4ee5226fd /drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |
| parent | 13bed58ce8748d430a26e353a09b89f9d613a71f (diff) | |
| parent | 1b5b42216469b05ef4b5916cb40b127dfab1da88 (diff) | |
| download | linux-cc9b94029e9ef51787af908e9856b1eed314bc00.tar.xz | |
Merge branch 'topic/error' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into regulator-fixed
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 297 | 
1 files changed, 225 insertions, 72 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 40a23704a981..c2c7fb140338 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -60,7 +60,10 @@ int amdgpu_driver_unload_kms(struct drm_device *dev)  	if (adev->rmmio == NULL)  		goto done_free; -	pm_runtime_get_sync(dev->dev); +	if (amdgpu_device_is_px(dev)) { +		pm_runtime_get_sync(dev->dev); +		pm_runtime_forbid(dev->dev); +	}  	amdgpu_amdkfd_device_fini(adev); @@ -135,13 +138,75 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)  	}  out: -	if (r) +	if (r) { +		/* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */ +		if (adev->rmmio && amdgpu_device_is_px(dev)) +			pm_runtime_put_noidle(dev->dev);  		amdgpu_driver_unload_kms(dev); - +	}  	return r;  } +static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, +				struct drm_amdgpu_query_fw *query_fw, +				struct amdgpu_device *adev) +{ +	switch (query_fw->fw_type) { +	case AMDGPU_INFO_FW_VCE: +		fw_info->ver = adev->vce.fw_version; +		fw_info->feature = adev->vce.fb_version; +		break; +	case AMDGPU_INFO_FW_UVD: +		fw_info->ver = adev->uvd.fw_version; +		fw_info->feature = 0; +		break; +	case AMDGPU_INFO_FW_GMC: +		fw_info->ver = adev->mc.fw_version; +		fw_info->feature = 0; +		break; +	case AMDGPU_INFO_FW_GFX_ME: +		fw_info->ver = adev->gfx.me_fw_version; +		fw_info->feature = adev->gfx.me_feature_version; +		break; +	case AMDGPU_INFO_FW_GFX_PFP: +		fw_info->ver = adev->gfx.pfp_fw_version; +		fw_info->feature = adev->gfx.pfp_feature_version; +		break; +	case AMDGPU_INFO_FW_GFX_CE: +		fw_info->ver = adev->gfx.ce_fw_version; +		fw_info->feature = adev->gfx.ce_feature_version; +		break; +	case AMDGPU_INFO_FW_GFX_RLC: +		fw_info->ver = adev->gfx.rlc_fw_version; +		fw_info->feature = adev->gfx.rlc_feature_version; +		break; +	case AMDGPU_INFO_FW_GFX_MEC: +		if (query_fw->index == 0) { +			fw_info->ver = adev->gfx.mec_fw_version; +			fw_info->feature = adev->gfx.mec_feature_version; +		} else if (query_fw->index == 1) { +			fw_info->ver = adev->gfx.mec2_fw_version; +			fw_info->feature = adev->gfx.mec2_feature_version; +		} else +			return -EINVAL; +		break; +	case AMDGPU_INFO_FW_SMC: +		fw_info->ver = adev->pm.fw_version; +		fw_info->feature = 0; +		break; +	case AMDGPU_INFO_FW_SDMA: +		if (query_fw->index >= adev->sdma.num_instances) +			return -EINVAL; +		fw_info->ver = adev->sdma.instance[query_fw->index].fw_version; +		fw_info->feature = adev->sdma.instance[query_fw->index].feature_version; +		break; +	default: +		return -EINVAL; +	} +	return 0; +} +  /*   * Userspace get information ioctl   */ @@ -227,14 +292,14 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  			type = AMD_IP_BLOCK_TYPE_UVD;  			ring_mask = adev->uvd.ring.ready ? 1 : 0;  			ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; -			ib_size_alignment = 8; +			ib_size_alignment = 16;  			break;  		case AMDGPU_HW_IP_VCE:  			type = AMD_IP_BLOCK_TYPE_VCE; -			for (i = 0; i < AMDGPU_MAX_VCE_RINGS; i++) +			for (i = 0; i < adev->vce.num_rings; i++)  				ring_mask |= ((adev->vce.ring[i].ready ? 1 : 0) << i);  			ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; -			ib_size_alignment = 8; +			ib_size_alignment = 1;  			break;  		default:  			return -EINVAL; @@ -288,73 +353,29 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  		return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0;  	}  	case AMDGPU_INFO_TIMESTAMP: -		ui64 = amdgpu_asic_get_gpu_clock_counter(adev); +		ui64 = amdgpu_gfx_get_gpu_clock_counter(adev);  		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;  	case AMDGPU_INFO_FW_VERSION: {  		struct drm_amdgpu_info_firmware fw_info; +		int ret;  		/* We only support one instance of each IP block right now. */  		if (info->query_fw.ip_instance != 0)  			return -EINVAL; -		switch (info->query_fw.fw_type) { -		case AMDGPU_INFO_FW_VCE: -			fw_info.ver = adev->vce.fw_version; -			fw_info.feature = adev->vce.fb_version; -			break; -		case AMDGPU_INFO_FW_UVD: -			fw_info.ver = adev->uvd.fw_version; -			fw_info.feature = 0; -			break; -		case AMDGPU_INFO_FW_GMC: -			fw_info.ver = adev->mc.fw_version; -			fw_info.feature = 0; -			break; -		case AMDGPU_INFO_FW_GFX_ME: -			fw_info.ver = adev->gfx.me_fw_version; -			fw_info.feature = adev->gfx.me_feature_version; -			break; -		case AMDGPU_INFO_FW_GFX_PFP: -			fw_info.ver = adev->gfx.pfp_fw_version; -			fw_info.feature = adev->gfx.pfp_feature_version; -			break; -		case AMDGPU_INFO_FW_GFX_CE: -			fw_info.ver = adev->gfx.ce_fw_version; -			fw_info.feature = adev->gfx.ce_feature_version; -			break; -		case AMDGPU_INFO_FW_GFX_RLC: -			fw_info.ver = adev->gfx.rlc_fw_version; -			fw_info.feature = adev->gfx.rlc_feature_version; -			break; -		case AMDGPU_INFO_FW_GFX_MEC: -			if (info->query_fw.index == 0) { -				fw_info.ver = adev->gfx.mec_fw_version; -				fw_info.feature = adev->gfx.mec_feature_version; -			} else if (info->query_fw.index == 1) { -				fw_info.ver = adev->gfx.mec2_fw_version; -				fw_info.feature = adev->gfx.mec2_feature_version; -			} else -				return -EINVAL; -			break; -		case AMDGPU_INFO_FW_SMC: -			fw_info.ver = adev->pm.fw_version; -			fw_info.feature = 0; -			break; -		case AMDGPU_INFO_FW_SDMA: -			if (info->query_fw.index >= adev->sdma.num_instances) -				return -EINVAL; -			fw_info.ver = adev->sdma.instance[info->query_fw.index].fw_version; -			fw_info.feature = adev->sdma.instance[info->query_fw.index].feature_version; -			break; -		default: -			return -EINVAL; -		} +		ret = amdgpu_firmware_info(&fw_info, &info->query_fw, adev); +		if (ret) +			return ret; +  		return copy_to_user(out, &fw_info,  				    min((size_t)size, sizeof(fw_info))) ? -EFAULT : 0;  	}  	case AMDGPU_INFO_NUM_BYTES_MOVED:  		ui64 = atomic64_read(&adev->num_bytes_moved);  		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; +	case AMDGPU_INFO_NUM_EVICTIONS: +		ui64 = atomic64_read(&adev->num_evictions); +		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;  	case AMDGPU_INFO_VRAM_USAGE:  		ui64 = atomic64_read(&adev->vram_usage);  		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; @@ -447,7 +468,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  			dev_info.max_memory_clock = adev->pm.default_mclk * 10;  		}  		dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask; -		dev_info.num_rb_pipes = adev->gfx.config.num_rbs; +		dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se * +			adev->gfx.config.max_shader_engines;  		dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts;  		dev_info._pad = 0;  		dev_info.ids_flags = 0; @@ -520,12 +542,16 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)  		return r;  	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); -	if (unlikely(!fpriv)) -		return -ENOMEM; +	if (unlikely(!fpriv)) { +		r = -ENOMEM; +		goto out_suspend; +	}  	r = amdgpu_vm_init(adev, &fpriv->vm); -	if (r) -		goto error_free; +	if (r) { +		kfree(fpriv); +		goto out_suspend; +	}  	mutex_init(&fpriv->bo_list_lock);  	idr_init(&fpriv->bo_list_handles); @@ -534,12 +560,9 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)  	file_priv->driver_priv = fpriv; +out_suspend:  	pm_runtime_mark_last_busy(dev->dev);  	pm_runtime_put_autosuspend(dev->dev); -	return 0; - -error_free: -	kfree(fpriv);  	return r;  } @@ -565,6 +588,9 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,  	amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr); +	amdgpu_uvd_free_handles(adev, file_priv); +	amdgpu_vce_free_handles(adev, file_priv); +  	amdgpu_vm_fini(adev, &fpriv->vm);  	idr_for_each_entry(&fpriv->bo_list_handles, list, handle) @@ -575,6 +601,9 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,  	kfree(fpriv);  	file_priv->driver_priv = NULL; + +	pm_runtime_mark_last_busy(dev->dev); +	pm_runtime_put_autosuspend(dev->dev);  }  /** @@ -589,10 +618,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,  void amdgpu_driver_preclose_kms(struct drm_device *dev,  				struct drm_file *file_priv)  { -	struct amdgpu_device *adev = dev->dev_private; - -	amdgpu_uvd_free_handles(adev, file_priv); -	amdgpu_vce_free_handles(adev, file_priv); +	pm_runtime_get_sync(dev->dev);  }  /* @@ -755,3 +781,130 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {  	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),  };  const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms); + +/* + * Debugfs info + */ +#if defined(CONFIG_DEBUG_FS) + +static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data) +{ +	struct drm_info_node *node = (struct drm_info_node *) m->private; +	struct drm_device *dev = node->minor->dev; +	struct amdgpu_device *adev = dev->dev_private; +	struct drm_amdgpu_info_firmware fw_info; +	struct drm_amdgpu_query_fw query_fw; +	int ret, i; + +	/* VCE */ +	query_fw.fw_type = AMDGPU_INFO_FW_VCE; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "VCE feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* UVD */ +	query_fw.fw_type = AMDGPU_INFO_FW_UVD; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "UVD feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* GMC */ +	query_fw.fw_type = AMDGPU_INFO_FW_GMC; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "MC feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* ME */ +	query_fw.fw_type = AMDGPU_INFO_FW_GFX_ME; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "ME feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* PFP */ +	query_fw.fw_type = AMDGPU_INFO_FW_GFX_PFP; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "PFP feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* CE */ +	query_fw.fw_type = AMDGPU_INFO_FW_GFX_CE; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "CE feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* RLC */ +	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* MEC */ +	query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC; +	query_fw.index = 0; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "MEC feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* MEC2 */ +	if (adev->asic_type == CHIP_KAVERI || +	    (adev->asic_type > CHIP_TOPAZ && adev->asic_type != CHIP_STONEY)) { +		query_fw.index = 1; +		ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +		if (ret) +			return ret; +		seq_printf(m, "MEC2 feature version: %u, firmware version: 0x%08x\n", +			   fw_info.feature, fw_info.ver); +	} + +	/* SMC */ +	query_fw.fw_type = AMDGPU_INFO_FW_SMC; +	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +	if (ret) +		return ret; +	seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x\n", +		   fw_info.feature, fw_info.ver); + +	/* SDMA */ +	query_fw.fw_type = AMDGPU_INFO_FW_SDMA; +	for (i = 0; i < adev->sdma.num_instances; i++) { +		query_fw.index = i; +		ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); +		if (ret) +			return ret; +		seq_printf(m, "SDMA%d feature version: %u, firmware version: 0x%08x\n", +			   i, fw_info.feature, fw_info.ver); +	} + +	return 0; +} + +static const struct drm_info_list amdgpu_firmware_info_list[] = { +	{"amdgpu_firmware_info", amdgpu_debugfs_firmware_info, 0, NULL}, +}; +#endif + +int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev) +{ +#if defined(CONFIG_DEBUG_FS) +	return amdgpu_debugfs_add_files(adev, amdgpu_firmware_info_list, +					ARRAY_SIZE(amdgpu_firmware_info_list)); +#else +	return 0; +#endif +}  | 
