aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-10-27 20:35:59 -0400
committerDave Airlie <airlied@redhat.com>2016-10-27 20:35:59 -0400
commita1873c62710b23e9afbd2faeed5f28649cbe4739 (patch)
treefd07fb6b1dc0c61a15ba563cad3ef2e46687f45c /drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
parent5481e27f6fd06b7cb902072e81d6b083db8155eb (diff)
parent3495a103579380288a130dc1862488cd8a4293f5 (diff)
Merge branch 'drm-next-4.10' of git://people.freedesktop.org/~agd5f/linux into drm-next
First new feature pull for 4.10. Highlights: - Support for multple virtual displays in the virtual dce component - New VM mgr to support non-contiguous vram buffers - Support for UVD powergating on additional asics - Power management improvements - lots of code cleanup and bug fixes * 'drm-next-4.10' of git://people.freedesktop.org/~agd5f/linux: (107 commits) drm/amdgpu: turn on/off uvd clock when dpm enable/disable on CI drm/amdgpu: disable dpm before turn off clock when vce idle. drm/amdgpu: enable uvd bypass mode for CI/VI. drm/amdgpu: just not load smc firmware if smu is already running drm/amdgpu: when suspend, set boot state instand of disable dpm. drm/amdgpu: use failed label to handle context init failure drm/amdgpu: add amdgpu_ttm_bo_eviction_valuable callback drm/ttm: make eviction decision a driver callback v2 drm/ttm: fix coding style in ttm_bo_driver.h drm/radeon/pm: autoswitch power state when in balanced mode drm/amd/powerplay: fix spelling mistake and add KERN_WARNING to printks drm/amdgpu:new ids flag for preempt drm/amdgpu: mark symbols static where possible drm/amdgpu: change function declarations and add missing header dependencies drm/amdgpu: s/amdgpuCrtc/amdgpu_crtc/ in pageflip code drm/amdgpu/atom: remove a bunch of unused functions drm/amdgpu: consolidate atom scratch reg handling for hangs drm/amdgpu: use amdgpu_bo_[create|free]_kernel for wb drm/amdgpu: add VCE VM session tracking drm/amdgpu: improve parse_cs handling a bit ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c41
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
242static 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
239int amdgpu_ucode_init_bo(struct amdgpu_device *adev) 267int 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 }