mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/amdgpu: Add init levels
Add init levels to define the level to which device needs to be initialized. Signed-off-by: Lijo Lazar <lijo.lazar@amd.com> Acked-by: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com> Tested-by: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									8a84d2a472
								
							
						
					
					
						commit
						14f2fe34f5
					
				
					 2 changed files with 88 additions and 0 deletions
				
			
		| 
						 | 
					@ -823,6 +823,24 @@ struct amdgpu_mqd {
 | 
				
			||||||
			struct amdgpu_mqd_prop *p);
 | 
								struct amdgpu_mqd_prop *p);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Custom Init levels could be defined for different situations where a full
 | 
				
			||||||
 | 
					 * initialization of all hardware blocks are not expected. Sample cases are
 | 
				
			||||||
 | 
					 * custom init sequences after resume after S0i3/S3, reset on initialization,
 | 
				
			||||||
 | 
					 * partial reset of blocks etc. Presently, this defines only two levels. Levels
 | 
				
			||||||
 | 
					 * are described in corresponding struct definitions - amdgpu_init_default,
 | 
				
			||||||
 | 
					 * amdgpu_init_minimal_xgmi.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum amdgpu_init_lvl_id {
 | 
				
			||||||
 | 
						AMDGPU_INIT_LEVEL_DEFAULT,
 | 
				
			||||||
 | 
						AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct amdgpu_init_level {
 | 
				
			||||||
 | 
						enum amdgpu_init_lvl_id level;
 | 
				
			||||||
 | 
						uint32_t hwini_ip_block_mask;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define AMDGPU_RESET_MAGIC_NUM 64
 | 
					#define AMDGPU_RESET_MAGIC_NUM 64
 | 
				
			||||||
#define AMDGPU_MAX_DF_PERFMONS 4
 | 
					#define AMDGPU_MAX_DF_PERFMONS 4
 | 
				
			||||||
struct amdgpu_reset_domain;
 | 
					struct amdgpu_reset_domain;
 | 
				
			||||||
| 
						 | 
					@ -1168,6 +1186,8 @@ struct amdgpu_device {
 | 
				
			||||||
	bool				enforce_isolation[MAX_XCP];
 | 
						bool				enforce_isolation[MAX_XCP];
 | 
				
			||||||
	/* Added this mutex for cleaner shader isolation between GFX and compute processes */
 | 
						/* Added this mutex for cleaner shader isolation between GFX and compute processes */
 | 
				
			||||||
	struct mutex                    enforce_isolation_mutex;
 | 
						struct mutex                    enforce_isolation_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct amdgpu_init_level *init_lvl;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
 | 
					static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
 | 
				
			||||||
| 
						 | 
					@ -1621,4 +1641,6 @@ extern const struct attribute_group amdgpu_vram_mgr_attr_group;
 | 
				
			||||||
extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
 | 
					extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
 | 
				
			||||||
extern const struct attribute_group amdgpu_flash_attr_group;
 | 
					extern const struct attribute_group amdgpu_flash_attr_group;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_set_init_level(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
								   enum amdgpu_init_lvl_id lvl);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,6 +144,50 @@ const char *amdgpu_asic_name[] = {
 | 
				
			||||||
	"LAST",
 | 
						"LAST",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM - 1, 0)
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Default init level where all blocks are expected to be initialized. This is
 | 
				
			||||||
 | 
					 * the level of initialization expected by default and also after a full reset
 | 
				
			||||||
 | 
					 * of the device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct amdgpu_init_level amdgpu_init_default = {
 | 
				
			||||||
 | 
						.level = AMDGPU_INIT_LEVEL_DEFAULT,
 | 
				
			||||||
 | 
						.hwini_ip_block_mask = AMDGPU_IP_BLK_MASK_ALL,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Minimal blocks needed to be initialized before a XGMI hive can be reset. This
 | 
				
			||||||
 | 
					 * is used for cases like reset on initialization where the entire hive needs to
 | 
				
			||||||
 | 
					 * be reset before first use.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct amdgpu_init_level amdgpu_init_minimal_xgmi = {
 | 
				
			||||||
 | 
						.level = AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
 | 
				
			||||||
 | 
						.hwini_ip_block_mask =
 | 
				
			||||||
 | 
							BIT(AMD_IP_BLOCK_TYPE_GMC) | BIT(AMD_IP_BLOCK_TYPE_SMC) |
 | 
				
			||||||
 | 
							BIT(AMD_IP_BLOCK_TYPE_COMMON) | BIT(AMD_IP_BLOCK_TYPE_IH)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool amdgpu_ip_member_of_hwini(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
										     enum amd_ip_block_type block)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (adev->init_lvl->hwini_ip_block_mask & (1U << block)) != 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void amdgpu_set_init_level(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
								   enum amdgpu_init_lvl_id lvl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (lvl) {
 | 
				
			||||||
 | 
						case AMDGPU_INIT_LEVEL_MINIMAL_XGMI:
 | 
				
			||||||
 | 
							adev->init_lvl = &amdgpu_init_minimal_xgmi;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case AMDGPU_INIT_LEVEL_DEFAULT:
 | 
				
			||||||
 | 
							fallthrough;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							adev->init_lvl = &amdgpu_init_default;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev);
 | 
					static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -2655,6 +2699,9 @@ static int amdgpu_device_ip_hw_init_phase1(struct amdgpu_device *adev)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (adev->ip_blocks[i].status.hw)
 | 
							if (adev->ip_blocks[i].status.hw)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
							if (!amdgpu_ip_member_of_hwini(
 | 
				
			||||||
 | 
								    adev, adev->ip_blocks[i].version->type))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
		if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
 | 
							if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
 | 
				
			||||||
		    (amdgpu_sriov_vf(adev) && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)) ||
 | 
							    (amdgpu_sriov_vf(adev) && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)) ||
 | 
				
			||||||
		    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
 | 
							    adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_IH) {
 | 
				
			||||||
| 
						 | 
					@ -2680,6 +2727,9 @@ static int amdgpu_device_ip_hw_init_phase2(struct amdgpu_device *adev)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (adev->ip_blocks[i].status.hw)
 | 
							if (adev->ip_blocks[i].status.hw)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
							if (!amdgpu_ip_member_of_hwini(
 | 
				
			||||||
 | 
								    adev, adev->ip_blocks[i].version->type))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
		r = adev->ip_blocks[i].version->funcs->hw_init(adev);
 | 
							r = adev->ip_blocks[i].version->funcs->hw_init(adev);
 | 
				
			||||||
		if (r) {
 | 
							if (r) {
 | 
				
			||||||
			DRM_ERROR("hw_init of IP block <%s> failed %d\n",
 | 
								DRM_ERROR("hw_init of IP block <%s> failed %d\n",
 | 
				
			||||||
| 
						 | 
					@ -2703,6 +2753,10 @@ static int amdgpu_device_fw_loading(struct amdgpu_device *adev)
 | 
				
			||||||
			if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_PSP)
 | 
								if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_PSP)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!amdgpu_ip_member_of_hwini(adev,
 | 
				
			||||||
 | 
											       AMD_IP_BLOCK_TYPE_PSP))
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!adev->ip_blocks[i].status.sw)
 | 
								if (!adev->ip_blocks[i].status.sw)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2825,6 +2879,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		adev->ip_blocks[i].status.sw = true;
 | 
							adev->ip_blocks[i].status.sw = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!amdgpu_ip_member_of_hwini(
 | 
				
			||||||
 | 
								    adev, adev->ip_blocks[i].version->type))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
 | 
							if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
 | 
				
			||||||
			/* need to do common hw init early so everything is set up for gmc */
 | 
								/* need to do common hw init early so everything is set up for gmc */
 | 
				
			||||||
			r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
 | 
								r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
 | 
				
			||||||
| 
						 | 
					@ -4215,6 +4273,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	amdgpu_device_set_mcbp(adev);
 | 
						amdgpu_device_set_mcbp(adev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * By default, use default mode where all blocks are expected to be
 | 
				
			||||||
 | 
						 * initialized. At present a 'swinit' of blocks is required to be
 | 
				
			||||||
 | 
						 * completed before the need for a different level is detected.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						amdgpu_set_init_level(adev, AMDGPU_INIT_LEVEL_DEFAULT);
 | 
				
			||||||
	/* early init functions */
 | 
						/* early init functions */
 | 
				
			||||||
	r = amdgpu_device_ip_early_init(adev);
 | 
						r = amdgpu_device_ip_early_init(adev);
 | 
				
			||||||
	if (r)
 | 
						if (r)
 | 
				
			||||||
| 
						 | 
					@ -5414,6 +5478,8 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
 | 
						list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
 | 
				
			||||||
 | 
							/* After reset, it's default init level */
 | 
				
			||||||
 | 
							amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_DEFAULT);
 | 
				
			||||||
		if (need_full_reset) {
 | 
							if (need_full_reset) {
 | 
				
			||||||
			/* post card */
 | 
								/* post card */
 | 
				
			||||||
			amdgpu_ras_set_fed(tmp_adev, false);
 | 
								amdgpu_ras_set_fed(tmp_adev, false);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue