diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index cb3d252f3c78..0f0b38191fac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |||
@@ -228,6 +228,9 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_firmware_info *ucode, | |||
228 | ucode->mc_addr = mc_addr; | 228 | ucode->mc_addr = mc_addr; |
229 | ucode->kaddr = kptr; | 229 | ucode->kaddr = kptr; |
230 | 230 | ||
231 | if (ucode->ucode_id == AMDGPU_UCODE_ID_STORAGE) | ||
232 | return 0; | ||
233 | |||
231 | header = (const struct common_firmware_header *)ucode->fw->data; | 234 | header = (const struct common_firmware_header *)ucode->fw->data; |
232 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | 235 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + |
233 | le32_to_cpu(header->ucode_array_offset_bytes)), | 236 | le32_to_cpu(header->ucode_array_offset_bytes)), |
@@ -236,6 +239,31 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_firmware_info *ucode, | |||
236 | return 0; | 239 | return 0; |
237 | } | 240 | } |
238 | 241 | ||
242 | static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, | ||
243 | uint64_t mc_addr, void *kptr) | ||
244 | { | ||
245 | const struct gfx_firmware_header_v1_0 *header = NULL; | ||
246 | const struct common_firmware_header *comm_hdr = NULL; | ||
247 | uint8_t* src_addr = NULL; | ||
248 | uint8_t* dst_addr = NULL; | ||
249 | |||
250 | if (NULL == ucode->fw) | ||
251 | return 0; | ||
252 | |||
253 | comm_hdr = (const struct common_firmware_header *)ucode->fw->data; | ||
254 | header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; | ||
255 | dst_addr = ucode->kaddr + | ||
256 | ALIGN(le32_to_cpu(comm_hdr->ucode_size_bytes), | ||
257 | PAGE_SIZE); | ||
258 | src_addr = (uint8_t *)ucode->fw->data + | ||
259 | le32_to_cpu(comm_hdr->ucode_array_offset_bytes) + | ||
260 | (le32_to_cpu(header->jt_offset) * 4); | ||
261 | memcpy(dst_addr, src_addr, le32_to_cpu(header->jt_size) * 4); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | |||
239 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | 267 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) |
240 | { | 268 | { |
241 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; | 269 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; |
@@ -247,7 +275,8 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
247 | const struct common_firmware_header *header = NULL; | 275 | const struct common_firmware_header *header = NULL; |
248 | 276 | ||
249 | err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true, | 277 | err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true, |
250 | AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, bo); | 278 | amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, |
279 | 0, NULL, NULL, bo); | ||
251 | if (err) { | 280 | if (err) { |
252 | dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err); | 281 | dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err); |
253 | goto failed; | 282 | goto failed; |
@@ -259,7 +288,8 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
259 | goto failed_reserve; | 288 | goto failed_reserve; |
260 | } | 289 | } |
261 | 290 | ||
262 | err = amdgpu_bo_pin(*bo, AMDGPU_GEM_DOMAIN_GTT, &fw_mc_addr); | 291 | err = amdgpu_bo_pin(*bo, amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, |
292 | &fw_mc_addr); | ||
263 | if (err) { | 293 | if (err) { |
264 | dev_err(adev->dev, "(%d) Firmware buffer pin failed\n", err); | 294 | dev_err(adev->dev, "(%d) Firmware buffer pin failed\n", err); |
265 | goto failed_pin; | 295 | goto failed_pin; |
@@ -279,6 +309,13 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
279 | header = (const struct common_firmware_header *)ucode->fw->data; | 309 | header = (const struct common_firmware_header *)ucode->fw->data; |
280 | amdgpu_ucode_init_single_fw(ucode, fw_mc_addr + fw_offset, | 310 | amdgpu_ucode_init_single_fw(ucode, fw_mc_addr + fw_offset, |
281 | fw_buf_ptr + fw_offset); | 311 | fw_buf_ptr + fw_offset); |
312 | if (i == AMDGPU_UCODE_ID_CP_MEC1) { | ||
313 | const struct gfx_firmware_header_v1_0 *cp_hdr; | ||
314 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; | ||
315 | amdgpu_ucode_patch_jt(ucode, fw_mc_addr + fw_offset, | ||
316 | fw_buf_ptr + fw_offset); | ||
317 | fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); | ||
318 | } | ||
282 | fw_offset += ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); | 319 | fw_offset += ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); |
283 | } | 320 | } |
284 | } | 321 | } |