Skip to content

Commit f8e487c

Browse files
John Clementsalexdeucher
authored andcommitted
drm/amdgpu: Added latest PSP FW header
Improved handling for scalling PSP FW binaries Signed-off-by: John Clements <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent b84d029 commit f8e487c

File tree

2 files changed

+116
-21
lines changed

2 files changed

+116
-21
lines changed

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

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,6 +3024,64 @@ int psp_init_toc_microcode(struct psp_context *psp,
30243024
return err;
30253025
}
30263026

3027+
static int parse_sos_bin_descriptor(struct psp_context *psp,
3028+
const struct psp_fw_bin_desc *desc,
3029+
const struct psp_firmware_header_v2_0 *sos_hdr)
3030+
{
3031+
uint8_t *ucode_start_addr = NULL;
3032+
3033+
if (!psp || !desc || !sos_hdr)
3034+
return -EINVAL;
3035+
3036+
ucode_start_addr = (uint8_t *)sos_hdr +
3037+
le32_to_cpu(desc->offset_bytes) +
3038+
le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes);
3039+
3040+
switch (desc->fw_type) {
3041+
case PSP_FW_TYPE_PSP_SOS:
3042+
psp->sos.fw_version = le32_to_cpu(desc->fw_version);
3043+
psp->sos.feature_version = le32_to_cpu(desc->fw_version);
3044+
psp->sos.size_bytes = le32_to_cpu(desc->size_bytes);
3045+
psp->sos.start_addr = ucode_start_addr;
3046+
break;
3047+
case PSP_FW_TYPE_PSP_SYS_DRV:
3048+
psp->sys.fw_version = le32_to_cpu(desc->fw_version);
3049+
psp->sys.feature_version = le32_to_cpu(desc->fw_version);
3050+
psp->sys.size_bytes = le32_to_cpu(desc->size_bytes);
3051+
psp->sys.start_addr = ucode_start_addr;
3052+
break;
3053+
case PSP_FW_TYPE_PSP_KDB:
3054+
psp->kdb.fw_version = le32_to_cpu(desc->fw_version);
3055+
psp->kdb.feature_version = le32_to_cpu(desc->fw_version);
3056+
psp->kdb.size_bytes = le32_to_cpu(desc->size_bytes);
3057+
psp->kdb.start_addr = ucode_start_addr;
3058+
break;
3059+
case PSP_FW_TYPE_PSP_TOC:
3060+
psp->toc.fw_version = le32_to_cpu(desc->fw_version);
3061+
psp->toc.feature_version = le32_to_cpu(desc->fw_version);
3062+
psp->toc.size_bytes = le32_to_cpu(desc->size_bytes);
3063+
psp->toc.start_addr = ucode_start_addr;
3064+
break;
3065+
case PSP_FW_TYPE_PSP_SPL:
3066+
psp->spl.fw_version = le32_to_cpu(desc->fw_version);
3067+
psp->spl.feature_version = le32_to_cpu(desc->fw_version);
3068+
psp->spl.size_bytes = le32_to_cpu(desc->size_bytes);
3069+
psp->spl.start_addr = ucode_start_addr;
3070+
break;
3071+
case PSP_FW_TYPE_PSP_RL:
3072+
psp->rl.fw_version = le32_to_cpu(desc->fw_version);
3073+
psp->rl.feature_version = le32_to_cpu(desc->fw_version);
3074+
psp->rl.size_bytes = le32_to_cpu(desc->size_bytes);
3075+
psp->rl.start_addr = ucode_start_addr;
3076+
break;
3077+
default:
3078+
dev_warn(psp->adev->dev, "Unsupported PSP FW type: %d\n", desc->fw_type);
3079+
break;
3080+
}
3081+
3082+
return 0;
3083+
}
3084+
30273085
static int psp_init_sos_base_fw(struct amdgpu_device *adev)
30283086
{
30293087
const struct psp_firmware_header_v1_0 *sos_hdr;
@@ -3077,8 +3135,10 @@ int psp_init_sos_microcode(struct psp_context *psp,
30773135
const struct psp_firmware_header_v1_1 *sos_hdr_v1_1;
30783136
const struct psp_firmware_header_v1_2 *sos_hdr_v1_2;
30793137
const struct psp_firmware_header_v1_3 *sos_hdr_v1_3;
3138+
const struct psp_firmware_header_v2_0 *sos_hdr_v2_0;
30803139
int err = 0;
30813140
uint8_t *ucode_array_start_addr;
3141+
int fw_index = 0;
30823142

30833143
if (!chip_name) {
30843144
dev_err(adev->dev, "invalid chip name for sos microcode\n");
@@ -3136,6 +3196,23 @@ int psp_init_sos_microcode(struct psp_context *psp,
31363196
le32_to_cpu(sos_hdr_v1_3->rl.offset_bytes);
31373197
}
31383198
break;
3199+
case 2:
3200+
sos_hdr_v2_0 = (const struct psp_firmware_header_v2_0 *)adev->psp.sos_fw->data;
3201+
3202+
if (le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count) >= UCODE_MAX_PSP_PACKAGING) {
3203+
dev_err(adev->dev, "packed SOS count exceeds maximum limit\n");
3204+
err = -EINVAL;
3205+
goto out;
3206+
}
3207+
3208+
for (fw_index = 0; fw_index < le32_to_cpu(sos_hdr_v2_0->psp_fw_bin_count); fw_index++) {
3209+
err = parse_sos_bin_descriptor(psp,
3210+
&sos_hdr_v2_0->psp_fw_bin[fw_index],
3211+
sos_hdr_v2_0);
3212+
if (err)
3213+
goto out;
3214+
}
3215+
break;
31393216
default:
31403217
dev_err(adev->dev,
31413218
"unsupported psp sos firmware\n");
@@ -3154,7 +3231,7 @@ int psp_init_sos_microcode(struct psp_context *psp,
31543231
}
31553232

31563233
static int parse_ta_bin_descriptor(struct psp_context *psp,
3157-
const struct ta_fw_bin_desc *desc,
3234+
const struct psp_fw_bin_desc *desc,
31583235
const struct ta_firmware_header_v2_0 *ta_hdr)
31593236
{
31603237
uint8_t *ucode_start_addr = NULL;
@@ -3242,7 +3319,7 @@ int psp_init_ta_microcode(struct psp_context *psp,
32423319
goto out;
32433320
}
32443321

3245-
if (le32_to_cpu(ta_hdr->ta_fw_bin_count) >= UCODE_MAX_TA_PACKAGING) {
3322+
if (le32_to_cpu(ta_hdr->ta_fw_bin_count) >= UCODE_MAX_PSP_PACKAGING) {
32463323
dev_err(adev->dev, "packed TA count exceeds maximum limit\n");
32473324
err = -EINVAL;
32483325
goto out;

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

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct smc_firmware_header_v2_1 {
7171
uint32_t pptable_entry_offset;
7272
};
7373

74-
struct psp_fw_bin_desc {
74+
struct psp_fw_legacy_bin_desc {
7575
uint32_t fw_version;
7676
uint32_t offset_bytes;
7777
uint32_t size_bytes;
@@ -80,30 +80,54 @@ struct psp_fw_bin_desc {
8080
/* version_major=1, version_minor=0 */
8181
struct psp_firmware_header_v1_0 {
8282
struct common_firmware_header header;
83-
struct psp_fw_bin_desc sos;
83+
struct psp_fw_legacy_bin_desc sos;
8484
};
8585

8686
/* version_major=1, version_minor=1 */
8787
struct psp_firmware_header_v1_1 {
8888
struct psp_firmware_header_v1_0 v1_0;
89-
struct psp_fw_bin_desc toc;
90-
struct psp_fw_bin_desc kdb;
89+
struct psp_fw_legacy_bin_desc toc;
90+
struct psp_fw_legacy_bin_desc kdb;
9191
};
9292

9393
/* version_major=1, version_minor=2 */
9494
struct psp_firmware_header_v1_2 {
9595
struct psp_firmware_header_v1_0 v1_0;
96-
struct psp_fw_bin_desc res;
97-
struct psp_fw_bin_desc kdb;
96+
struct psp_fw_legacy_bin_desc res;
97+
struct psp_fw_legacy_bin_desc kdb;
9898
};
9999

100100
/* version_major=1, version_minor=3 */
101101
struct psp_firmware_header_v1_3 {
102102
struct psp_firmware_header_v1_1 v1_1;
103-
struct psp_fw_bin_desc spl;
104-
struct psp_fw_bin_desc rl;
105-
struct psp_fw_bin_desc sys_drv_aux;
106-
struct psp_fw_bin_desc sos_aux;
103+
struct psp_fw_legacy_bin_desc spl;
104+
struct psp_fw_legacy_bin_desc rl;
105+
struct psp_fw_legacy_bin_desc sys_drv_aux;
106+
struct psp_fw_legacy_bin_desc sos_aux;
107+
};
108+
109+
struct psp_fw_bin_desc {
110+
uint32_t fw_type;
111+
uint32_t fw_version;
112+
uint32_t offset_bytes;
113+
uint32_t size_bytes;
114+
};
115+
116+
enum psp_fw_type {
117+
PSP_FW_TYPE_UNKOWN,
118+
PSP_FW_TYPE_PSP_SOS,
119+
PSP_FW_TYPE_PSP_SYS_DRV,
120+
PSP_FW_TYPE_PSP_KDB,
121+
PSP_FW_TYPE_PSP_TOC,
122+
PSP_FW_TYPE_PSP_SPL,
123+
PSP_FW_TYPE_PSP_RL,
124+
};
125+
126+
/* version_major=2, version_minor=0 */
127+
struct psp_firmware_header_v2_0 {
128+
struct common_firmware_header header;
129+
uint32_t psp_fw_bin_count;
130+
struct psp_fw_bin_desc psp_fw_bin[];
107131
};
108132

109133
/* version_major=1, version_minor=0 */
@@ -138,18 +162,11 @@ enum ta_fw_type {
138162
TA_FW_TYPE_MAX_INDEX,
139163
};
140164

141-
struct ta_fw_bin_desc {
142-
uint32_t fw_type;
143-
uint32_t fw_version;
144-
uint32_t offset_bytes;
145-
uint32_t size_bytes;
146-
};
147-
148165
/* version_major=2, version_minor=0 */
149166
struct ta_firmware_header_v2_0 {
150167
struct common_firmware_header header;
151168
uint32_t ta_fw_bin_count;
152-
struct ta_fw_bin_desc ta_fw_bin[];
169+
struct psp_fw_bin_desc ta_fw_bin[];
153170
};
154171

155172
/* version_major=1, version_minor=0 */
@@ -312,6 +329,7 @@ union amdgpu_firmware_header {
312329
struct psp_firmware_header_v1_0 psp;
313330
struct psp_firmware_header_v1_1 psp_v1_1;
314331
struct psp_firmware_header_v1_3 psp_v1_3;
332+
struct psp_firmware_header_v2_0 psp_v2_0;
315333
struct ta_firmware_header_v1_0 ta;
316334
struct ta_firmware_header_v2_0 ta_v2_0;
317335
struct gfx_firmware_header_v1_0 gfx;
@@ -326,7 +344,7 @@ union amdgpu_firmware_header {
326344
uint8_t raw[0x100];
327345
};
328346

329-
#define UCODE_MAX_TA_PACKAGING ((sizeof(union amdgpu_firmware_header) - sizeof(struct common_firmware_header) - 4) / sizeof(struct ta_fw_bin_desc))
347+
#define UCODE_MAX_PSP_PACKAGING ((sizeof(union amdgpu_firmware_header) - sizeof(struct common_firmware_header) - 4) / sizeof(struct psp_fw_bin_desc))
330348

331349
/*
332350
* fw loading support

0 commit comments

Comments
 (0)