Skip to content

Commit 14f2fe3

Browse files
Lijo Lazaralexdeucher
authored andcommitted
drm/amdgpu: Add init levels
Add init levels to define the level to which device needs to be initialized. Signed-off-by: Lijo Lazar <[email protected]> Acked-by: Rajneesh Bhardwaj <[email protected]> Tested-by: Rajneesh Bhardwaj <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 8a84d2a commit 14f2fe3

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,24 @@ struct amdgpu_mqd {
823823
struct amdgpu_mqd_prop *p);
824824
};
825825

826+
/*
827+
* Custom Init levels could be defined for different situations where a full
828+
* initialization of all hardware blocks are not expected. Sample cases are
829+
* custom init sequences after resume after S0i3/S3, reset on initialization,
830+
* partial reset of blocks etc. Presently, this defines only two levels. Levels
831+
* are described in corresponding struct definitions - amdgpu_init_default,
832+
* amdgpu_init_minimal_xgmi.
833+
*/
834+
enum amdgpu_init_lvl_id {
835+
AMDGPU_INIT_LEVEL_DEFAULT,
836+
AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
837+
};
838+
839+
struct amdgpu_init_level {
840+
enum amdgpu_init_lvl_id level;
841+
uint32_t hwini_ip_block_mask;
842+
};
843+
826844
#define AMDGPU_RESET_MAGIC_NUM 64
827845
#define AMDGPU_MAX_DF_PERFMONS 4
828846
struct amdgpu_reset_domain;
@@ -1168,6 +1186,8 @@ struct amdgpu_device {
11681186
bool enforce_isolation[MAX_XCP];
11691187
/* Added this mutex for cleaner shader isolation between GFX and compute processes */
11701188
struct mutex enforce_isolation_mutex;
1189+
1190+
struct amdgpu_init_level *init_lvl;
11711191
};
11721192

11731193
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;
16211641
extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
16221642
extern const struct attribute_group amdgpu_flash_attr_group;
16231643

1644+
void amdgpu_set_init_level(struct amdgpu_device *adev,
1645+
enum amdgpu_init_lvl_id lvl);
16241646
#endif

drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,50 @@ const char *amdgpu_asic_name[] = {
144144
"LAST",
145145
};
146146

147+
#define AMDGPU_IP_BLK_MASK_ALL GENMASK(AMDGPU_MAX_IP_NUM - 1, 0)
148+
/*
149+
* Default init level where all blocks are expected to be initialized. This is
150+
* the level of initialization expected by default and also after a full reset
151+
* of the device.
152+
*/
153+
struct amdgpu_init_level amdgpu_init_default = {
154+
.level = AMDGPU_INIT_LEVEL_DEFAULT,
155+
.hwini_ip_block_mask = AMDGPU_IP_BLK_MASK_ALL,
156+
};
157+
158+
/*
159+
* Minimal blocks needed to be initialized before a XGMI hive can be reset. This
160+
* is used for cases like reset on initialization where the entire hive needs to
161+
* be reset before first use.
162+
*/
163+
struct amdgpu_init_level amdgpu_init_minimal_xgmi = {
164+
.level = AMDGPU_INIT_LEVEL_MINIMAL_XGMI,
165+
.hwini_ip_block_mask =
166+
BIT(AMD_IP_BLOCK_TYPE_GMC) | BIT(AMD_IP_BLOCK_TYPE_SMC) |
167+
BIT(AMD_IP_BLOCK_TYPE_COMMON) | BIT(AMD_IP_BLOCK_TYPE_IH)
168+
};
169+
170+
static inline bool amdgpu_ip_member_of_hwini(struct amdgpu_device *adev,
171+
enum amd_ip_block_type block)
172+
{
173+
return (adev->init_lvl->hwini_ip_block_mask & (1U << block)) != 0;
174+
}
175+
176+
void amdgpu_set_init_level(struct amdgpu_device *adev,
177+
enum amdgpu_init_lvl_id lvl)
178+
{
179+
switch (lvl) {
180+
case AMDGPU_INIT_LEVEL_MINIMAL_XGMI:
181+
adev->init_lvl = &amdgpu_init_minimal_xgmi;
182+
break;
183+
case AMDGPU_INIT_LEVEL_DEFAULT:
184+
fallthrough;
185+
default:
186+
adev->init_lvl = &amdgpu_init_default;
187+
break;
188+
}
189+
}
190+
147191
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev);
148192

149193
/**
@@ -2655,6 +2699,9 @@ static int amdgpu_device_ip_hw_init_phase1(struct amdgpu_device *adev)
26552699
continue;
26562700
if (adev->ip_blocks[i].status.hw)
26572701
continue;
2702+
if (!amdgpu_ip_member_of_hwini(
2703+
adev, adev->ip_blocks[i].version->type))
2704+
continue;
26582705
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON ||
26592706
(amdgpu_sriov_vf(adev) && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP)) ||
26602707
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)
26802727
continue;
26812728
if (adev->ip_blocks[i].status.hw)
26822729
continue;
2730+
if (!amdgpu_ip_member_of_hwini(
2731+
adev, adev->ip_blocks[i].version->type))
2732+
continue;
26832733
r = adev->ip_blocks[i].version->funcs->hw_init(adev);
26842734
if (r) {
26852735
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)
27032753
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_PSP)
27042754
continue;
27052755

2756+
if (!amdgpu_ip_member_of_hwini(adev,
2757+
AMD_IP_BLOCK_TYPE_PSP))
2758+
break;
2759+
27062760
if (!adev->ip_blocks[i].status.sw)
27072761
continue;
27082762

@@ -2825,6 +2879,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
28252879
}
28262880
adev->ip_blocks[i].status.sw = true;
28272881

2882+
if (!amdgpu_ip_member_of_hwini(
2883+
adev, adev->ip_blocks[i].version->type))
2884+
continue;
2885+
28282886
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
28292887
/* need to do common hw init early so everything is set up for gmc */
28302888
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
@@ -4215,6 +4273,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
42154273

42164274
amdgpu_device_set_mcbp(adev);
42174275

4276+
/*
4277+
* By default, use default mode where all blocks are expected to be
4278+
* initialized. At present a 'swinit' of blocks is required to be
4279+
* completed before the need for a different level is detected.
4280+
*/
4281+
amdgpu_set_init_level(adev, AMDGPU_INIT_LEVEL_DEFAULT);
42184282
/* early init functions */
42194283
r = amdgpu_device_ip_early_init(adev);
42204284
if (r)
@@ -5414,6 +5478,8 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
54145478
}
54155479

54165480
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
5481+
/* After reset, it's default init level */
5482+
amdgpu_set_init_level(tmp_adev, AMDGPU_INIT_LEVEL_DEFAULT);
54175483
if (need_full_reset) {
54185484
/* post card */
54195485
amdgpu_ras_set_fed(tmp_adev, false);

0 commit comments

Comments
 (0)