Pull drm fixes from Dave Airlie: "This weeks instalment of fixes: amdgpu: Lots of memory leak and firmware leak fixes nouveau: Collection of display fixes, KASAN fixes vc4: vblank/pageflipping fixes fsl-dcu: Regmap cache fix omap: Unused variable warning fix. Nothing too surprising so far" * tag 'drm-fixes-for-v4.7-rc3' of git://people.freedesktop.org/~airlied/linux: (46 commits) drm/amdgpu: fix warning with powerplay disabled. drm/amd/powerplay: delete useless code as pptable changed in vbios. drm/amd/powerplay: fix bug visit array out of bounds drm/amdgpu: fix smu ucode memleak (v2) drm/amdgpu: add release firmware for cgs drm/amdgpu: fix tonga smu_fini mem leak drm/amdgpu: fix fiji smu fini mem leak drm/amdgpu: fix cik sdma ucode memleak drm/amdgpu: fix sdma24 ucode mem leak drm/amdgpu: fix sdma3 ucode mem leak drm/amdgpu: fix uvd fini mem leak drm/amdgpu: fix gfx 7 ucode mem leak drm/amdgpu: fix gfx8 ucode mem leak drm/amdgpu: fix missing free wb for cond_exec drm/amdgpu: fix memleak in pptable_init drm/amdgpu: fix mem leak in atombios drm/amdgpu: fix mem leak in pplib/hwmgr drm/amdgpu: fix mem leak in smumgr drm/amdgpu: add pipeline sync while vmid switch in same ctx drm/amdgpu: vBIOS post only call when mem_size zero ...
Unified · Split
| @@ -799,6 +799,7 @@ struct amdgpu_ring { · 798 unmodified lines | ||
| 799 | 799 | unsigned cond_exe_offs; |
| 800 | 800 | u64 cond_exe_gpu_addr; |
| 801 | 801 | volatile u32 *cond_exe_cpu_addr; |
| 802 | + int vmid; | |
| 802 | 803 | }; |
| 803 | 804 | |
| 804 | 805 | /* |
| @@ -936,7 +937,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, · 131 unmodified lines | ||
| 936 | 937 | unsigned vm_id, uint64_t pd_addr, |
| 937 | 938 | uint32_t gds_base, uint32_t gds_size, |
| 938 | 939 | uint32_t gws_base, uint32_t gws_size, |
| 939 | − uint32_t oa_base, uint32_t oa_size); | |
| 940 | + uint32_t oa_base, uint32_t oa_size, | |
| 941 | + bool vmid_switch); | |
| 940 | 942 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); |
| 941 | 943 | uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); |
| 942 | 944 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, |
| @@ -696,6 +696,17 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) · 695 unmodified lines | ||
| 696 | 696 | return result; |
| 697 | 697 | } |
| 698 | 698 | |
| 699 | +static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode_id type) | |
| 700 | +{ | |
| 701 | + CGS_FUNC_ADEV; | |
| 702 | + if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) { | |
| 703 | + release_firmware(adev->pm.fw); | |
| 704 | + return 0; | |
| 705 | + } | |
| 706 | + /* cannot release other firmware because they are not created by cgs */ | |
| 707 | + return -EINVAL; | |
| 708 | +} | |
| 709 | + | |
| 699 | 710 | static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, |
| 700 | 711 | enum cgs_ucode_id type, |
| 701 | 712 | struct cgs_firmware_info *info) |
| @@ -1125,6 +1136,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { · 423 unmodified lines | ||
| 1125 | 1136 | amdgpu_cgs_pm_query_clock_limits, |
| 1126 | 1137 | amdgpu_cgs_set_camera_voltages, |
| 1127 | 1138 | amdgpu_cgs_get_firmware_info, |
| 1139 | + amdgpu_cgs_rel_firmware, | |
| 1128 | 1140 | amdgpu_cgs_set_powergating_state, |
| 1129 | 1141 | amdgpu_cgs_set_clockgating_state, |
| 1130 | 1142 | amdgpu_cgs_get_active_displays_info, |
| @@ -827,8 +827,10 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) · 826 unmodified lines | ||
| 827 | 827 | */ |
| 828 | 828 | static void amdgpu_atombios_fini(struct amdgpu_device *adev) |
| 829 | 829 | { |
| 830 | − if (adev->mode_info.atom_context) | |
| 830 | + if (adev->mode_info.atom_context) { | |
| 831 | 831 | kfree(adev->mode_info.atom_context->scratch); |
| 832 | + kfree(adev->mode_info.atom_context->iio); | |
| 833 | + } | |
| 832 | 834 | kfree(adev->mode_info.atom_context); |
| 833 | 835 | adev->mode_info.atom_context = NULL; |
| 834 | 836 | kfree(adev->mode_info.atom_card_info); |
| @@ -1325,6 +1327,11 @@ static int amdgpu_fini(struct amdgpu_device *adev) · 490 unmodified lines | ||
| 1325 | 1327 | adev->ip_block_status[i].valid = false; |
| 1326 | 1328 | } |
| 1327 | 1329 | |
| 1330 | + for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | |
| 1331 | + if (adev->ip_blocks[i].funcs->late_fini) | |
| 1332 | + adev->ip_blocks[i].funcs->late_fini((void *)adev); | |
| 1333 | + } | |
| 1334 | + | |
| 1328 | 1335 | return 0; |
| 1329 | 1336 | } |
| 1330 | 1337 | |
| @@ -1513,8 +1520,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 182 unmodified lines | ||
| 1513 | 1520 | amdgpu_atombios_has_gpu_virtualization_table(adev); |
| 1514 | 1521 | |
| 1515 | 1522 | /* Post card if necessary */ |
| 1516 | − if (!amdgpu_card_posted(adev) || | |
| 1517 | − adev->virtualization.supports_sr_iov) { | |
| 1523 | + if (!amdgpu_card_posted(adev)) { | |
| 1518 | 1524 | if (!adev->bios) { |
| 1519 | 1525 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
| 1520 | 1526 | return -EINVAL; |
| @@ -122,6 +122,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, · 121 unmodified lines | ||
| 122 | 122 | bool skip_preamble, need_ctx_switch; |
| 123 | 123 | unsigned patch_offset = ~0; |
| 124 | 124 | struct amdgpu_vm *vm; |
| 125 | + int vmid = 0, old_vmid = ring->vmid; | |
| 125 | 126 | struct fence *hwf; |
| 126 | 127 | uint64_t ctx; |
| 127 | 128 | |
| @@ -135,9 +136,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, · 7 unmodified lines | ||
| 135 | 136 | if (job) { |
| 136 | 137 | vm = job->vm; |
| 137 | 138 | ctx = job->ctx; |
| 139 | + vmid = job->vm_id; | |
| 138 | 140 | } else { |
| 139 | 141 | vm = NULL; |
| 140 | 142 | ctx = 0; |
| 143 | + vmid = 0; | |
| 141 | 144 | } |
| 142 | 145 | |
| 143 | 146 | if (!ring->ready) { |
| @@ -163,7 +166,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, · 19 unmodified lines | ||
| 163 | 166 | r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, |
| 164 | 167 | job->gds_base, job->gds_size, |
| 165 | 168 | job->gws_base, job->gws_size, |
| 166 | − job->oa_base, job->oa_size); | |
| 169 | + job->oa_base, job->oa_size, | |
| 170 | + (ring->current_ctx == ctx) && (old_vmid != vmid)); | |
| 167 | 171 | if (r) { |
| 168 | 172 | amdgpu_ring_undo(ring); |
| 169 | 173 | return r; |
| @@ -180,7 +184,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, · 10 unmodified lines | ||
| 180 | 184 | need_ctx_switch = ring->current_ctx != ctx; |
| 181 | 185 | for (i = 0; i < num_ibs; ++i) { |
| 182 | 186 | ib = &ibs[i]; |
| 183 | − | |
| 184 | 187 | /* drop preamble IBs if we don't have a context switch */ |
| 185 | 188 | if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble) |
| 186 | 189 | continue; |
| @@ -188,6 +191,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, · 1 unmodified line | ||
| 188 | 191 | amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, |
| 189 | 192 | need_ctx_switch); |
| 190 | 193 | need_ctx_switch = false; |
| 194 | + ring->vmid = vmid; | |
| 191 | 195 | } |
| 192 | 196 | |
| 193 | 197 | if (ring->funcs->emit_hdp_invalidate) |
| @@ -198,6 +202,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, · 4 unmodified lines | ||
| 198 | 202 | dev_err(adev->dev, "failed to emit fence (%d)\n", r); |
| 199 | 203 | if (job && job->vm_id) |
| 200 | 204 | amdgpu_vm_reset_id(adev, job->vm_id); |
| 205 | + ring->vmid = old_vmid; | |
| 201 | 206 | amdgpu_ring_undo(ring); |
| 202 | 207 | return r; |
| 203 | 208 | } |
| @@ -183,13 +183,6 @@ static int amdgpu_pp_sw_fini(void *handle) · 182 unmodified lines | ||
| 183 | 183 | if (ret) |
| 184 | 184 | return ret; |
| 185 | 185 | |
| 186 | −#ifdef CONFIG_DRM_AMD_POWERPLAY | |
| 187 | − if (adev->pp_enabled) { | |
| 188 | − amdgpu_pm_sysfs_fini(adev); | |
| 189 | − amd_powerplay_fini(adev->powerplay.pp_handle); | |
| 190 | − } | |
| 191 | −#endif | |
| 192 | − | |
| 193 | 186 | return ret; |
| 194 | 187 | } |
| 195 | 188 | |
| @@ -223,6 +216,22 @@ static int amdgpu_pp_hw_fini(void *handle) · 27 unmodified lines | ||
| 223 | 216 | return ret; |
| 224 | 217 | } |
| 225 | 218 | |
| 219 | +static void amdgpu_pp_late_fini(void *handle) | |
| 220 | +{ | |
| 221 | +#ifdef CONFIG_DRM_AMD_POWERPLAY | |
| 222 | + struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
| 223 | + | |
| 224 | + if (adev->pp_enabled) { | |
| 225 | + amdgpu_pm_sysfs_fini(adev); | |
| 226 | + amd_powerplay_fini(adev->powerplay.pp_handle); | |
| 227 | + } | |
| 228 | + | |
| 229 | + if (adev->powerplay.ip_funcs->late_fini) | |
| 230 | + adev->powerplay.ip_funcs->late_fini( | |
| 231 | + adev->powerplay.pp_handle); | |
| 232 | +#endif | |
| 233 | +} | |
| 234 | + | |
| 226 | 235 | static int amdgpu_pp_suspend(void *handle) |
| 227 | 236 | { |
| 228 | 237 | int ret = 0; |
| @@ -311,6 +320,7 @@ const struct amd_ip_funcs amdgpu_pp_ip_funcs = { · 82 unmodified lines | ||
| 311 | 320 | .sw_fini = amdgpu_pp_sw_fini, |
| 312 | 321 | .hw_init = amdgpu_pp_hw_init, |
| 313 | 322 | .hw_fini = amdgpu_pp_hw_fini, |
| 323 | + .late_fini = amdgpu_pp_late_fini, | |
| 314 | 324 | .suspend = amdgpu_pp_suspend, |
| 315 | 325 | .resume = amdgpu_pp_resume, |
| 316 | 326 | .is_idle = amdgpu_pp_is_idle, |
| @@ -343,6 +343,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) · 342 unmodified lines | ||
| 343 | 343 | ring->ring = NULL; |
| 344 | 344 | ring->ring_obj = NULL; |
| 345 | 345 | |
| 346 | + amdgpu_wb_free(ring->adev, ring->cond_exe_offs); | |
| 346 | 347 | amdgpu_wb_free(ring->adev, ring->fence_offs); |
| 347 | 348 | amdgpu_wb_free(ring->adev, ring->rptr_offs); |
| 348 | 349 | amdgpu_wb_free(ring->adev, ring->wptr_offs); |
| @@ -115,6 +115,7 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev, · 114 unmodified lines | ||
| 115 | 115 | return r; |
| 116 | 116 | } |
| 117 | 117 | r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); |
| 118 | + memset(sa_manager->cpu_ptr, 0, sa_manager->size); | |
| 118 | 119 | amdgpu_bo_unreserve(sa_manager->bo); |
| 119 | 120 | return r; |
| 120 | 121 | } |
| @@ -253,19 +253,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) · 252 unmodified lines | ||
| 253 | 253 | { |
| 254 | 254 | int r; |
| 255 | 255 | |
| 256 | − if (adev->uvd.vcpu_bo == NULL) | |
| 257 | − return 0; | |
| 256 | + kfree(adev->uvd.saved_bo); | |
| 258 | 257 | |
| 259 | 258 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); |
| 260 | 259 | |
| 261 | − r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); | |
| 262 | − if (!r) { | |
| 263 | − amdgpu_bo_kunmap(adev->uvd.vcpu_bo); | |
| 264 | − amdgpu_bo_unpin(adev->uvd.vcpu_bo); | |
| 265 | − amdgpu_bo_unreserve(adev->uvd.vcpu_bo); | |
| 266 | − } | |
| 260 | + if (adev->uvd.vcpu_bo) { | |
| 261 | + r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); | |
| 262 | + if (!r) { | |
| 263 | + amdgpu_bo_kunmap(adev->uvd.vcpu_bo); | |
| 264 | + amdgpu_bo_unpin(adev->uvd.vcpu_bo); | |
| 265 | + amdgpu_bo_unreserve(adev->uvd.vcpu_bo); | |
| 266 | + } | |
| 267 | 267 | |
| 268 | − amdgpu_bo_unref(&adev->uvd.vcpu_bo); | |
| 268 | + amdgpu_bo_unref(&adev->uvd.vcpu_bo); | |
| 269 | + } | |
| 269 | 270 | |
| 270 | 271 | amdgpu_ring_fini(&adev->uvd.ring); |
| 271 | 272 | |
| @@ -298,7 +298,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, · 297 unmodified lines | ||
| 298 | 298 | unsigned vm_id, uint64_t pd_addr, |
| 299 | 299 | uint32_t gds_base, uint32_t gds_size, |
| 300 | 300 | uint32_t gws_base, uint32_t gws_size, |
| 301 | − uint32_t oa_base, uint32_t oa_size) | |
| 301 | + uint32_t oa_base, uint32_t oa_size, | |
| 302 | + bool vmid_switch) | |
| 302 | 303 | { |
| 303 | 304 | struct amdgpu_device *adev = ring->adev; |
| 304 | 305 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; |
| @@ -312,8 +313,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, · 7 unmodified lines | ||
| 312 | 313 | int r; |
| 313 | 314 | |
| 314 | 315 | if (ring->funcs->emit_pipeline_sync && ( |
| 315 | − pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || | |
| 316 | − ring->type == AMDGPU_RING_TYPE_COMPUTE)) | |
| 316 | + pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || vmid_switch)) | |
| 317 | 317 | amdgpu_ring_emit_pipeline_sync(ring); |
| 318 | 318 | |
| 319 | 319 | if (ring->funcs->emit_vm_flush && |
| @@ -6221,6 +6221,9 @@ static int ci_dpm_sw_fini(void *handle) · 6220 unmodified lines | ||
| 6221 | 6221 | ci_dpm_fini(adev); |
| 6222 | 6222 | mutex_unlock(&adev->pm.mutex); |
| 6223 | 6223 | |
| 6224 | + release_firmware(adev->pm.fw); | |
| 6225 | + adev->pm.fw = NULL; | |
| 6226 | + | |
| 6224 | 6227 | return 0; |
| 6225 | 6228 | } |
| 6226 | 6229 | |
| @@ -66,6 +66,16 @@ MODULE_FIRMWARE("radeon/mullins_sdma1.bin"); · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); |
| 68 | 68 | |
| 69 | + | |
| 70 | +static void cik_sdma_free_microcode(struct amdgpu_device *adev) | |
| 71 | +{ | |
| 72 | + int i; | |
| 73 | + for (i = 0; i < adev->sdma.num_instances; i++) { | |
| 74 | + release_firmware(adev->sdma.instance[i].fw); | |
| 75 | + adev->sdma.instance[i].fw = NULL; | |
| 76 | + } | |
| 77 | +} | |
| 78 | + | |
| 69 | 79 | /* |
| 70 | 80 | * sDMA - System DMA |
| 71 | 81 | * Starting with CIK, the GPU has new asynchronous |
| @@ -419,6 +429,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) · 347 unmodified lines | ||
| 419 | 429 | /* Initialize the ring buffer's read and write pointers */ |
| 420 | 430 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 421 | 431 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 432 | + WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | |
| 433 | + WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | |
| 422 | 434 | |
| 423 | 435 | /* set the wb address whether it's enabled or not */ |
| 424 | 436 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -446,7 +458,12 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) · 21 unmodified lines | ||
| 446 | 458 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 447 | 459 | |
| 448 | 460 | ring->ready = true; |
| 461 | + } | |
| 462 | + | |
| 463 | + cik_sdma_enable(adev, true); | |
| 449 | 464 | |
| 465 | + for (i = 0; i < adev->sdma.num_instances; i++) { | |
| 466 | + ring = &adev->sdma.instance[i].ring; | |
| 450 | 467 | r = amdgpu_ring_test_ring(ring); |
| 451 | 468 | if (r) { |
| 452 | 469 | ring->ready = false; |
| @@ -529,8 +546,8 @@ static int cik_sdma_start(struct amdgpu_device *adev) · 76 unmodified lines | ||
| 529 | 546 | if (r) |
| 530 | 547 | return r; |
| 531 | 548 | |
| 532 | − /* unhalt the MEs */ | |
| 533 | − cik_sdma_enable(adev, true); | |
| 549 | + /* halt the engine before programing */ | |
| 550 | + cik_sdma_enable(adev, false); | |
| 534 | 551 | |
| 535 | 552 | /* start the gfx rings and rlc compute queues */ |
| 536 | 553 | r = cik_sdma_gfx_resume(adev); |
| @@ -998,6 +1015,7 @@ static int cik_sdma_sw_fini(void *handle) · 461 unmodified lines | ||
| 998 | 1015 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 999 | 1016 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1000 | 1017 | |
| 1018 | + cik_sdma_free_microcode(adev); | |
| 1001 | 1019 | return 0; |
| 1002 | 1020 | } |
| 1003 | 1021 | |
| @@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle) · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | static int fiji_dpm_sw_fini(void *handle) |
| 74 | 74 | { |
| 75 | + struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
| 76 | + | |
| 77 | + release_firmware(adev->pm.fw); | |
| 78 | + adev->pm.fw = NULL; | |
| 79 | + | |
| 75 | 80 | return 0; |
| 76 | 81 | } |
| 77 | 82 | |
| @@ -991,6 +991,22 @@ out: · 990 unmodified lines | ||
| 991 | 991 | return err; |
| 992 | 992 | } |
| 993 | 993 | |
| 994 | +static void gfx_v7_0_free_microcode(struct amdgpu_device *adev) | |
| 995 | +{ | |
| 996 | + release_firmware(adev->gfx.pfp_fw); | |
| 997 | + adev->gfx.pfp_fw = NULL; | |
| 998 | + release_firmware(adev->gfx.me_fw); | |
| 999 | + adev->gfx.me_fw = NULL; | |
| 1000 | + release_firmware(adev->gfx.ce_fw); | |
| 1001 | + adev->gfx.ce_fw = NULL; | |
| 1002 | + release_firmware(adev->gfx.mec_fw); | |
| 1003 | + adev->gfx.mec_fw = NULL; | |
| 1004 | + release_firmware(adev->gfx.mec2_fw); | |
| 1005 | + adev->gfx.mec2_fw = NULL; | |
| 1006 | + release_firmware(adev->gfx.rlc_fw); | |
| 1007 | + adev->gfx.rlc_fw = NULL; | |
| 1008 | +} | |
| 1009 | + | |
| 994 | 1010 | /** |
| 995 | 1011 | * gfx_v7_0_tiling_mode_table_init - init the hw tiling table |
| 996 | 1012 | * |
| @@ -4489,6 +4505,7 @@ static int gfx_v7_0_sw_fini(void *handle) · 3492 unmodified lines | ||
| 4489 | 4505 | gfx_v7_0_cp_compute_fini(adev); |
| 4490 | 4506 | gfx_v7_0_rlc_fini(adev); |
| 4491 | 4507 | gfx_v7_0_mec_fini(adev); |
| 4508 | + gfx_v7_0_free_microcode(adev); | |
| 4492 | 4509 | |
| 4493 | 4510 | return 0; |
| 4494 | 4511 | } |
| @@ -836,6 +836,26 @@ err1: · 835 unmodified lines | ||
| 836 | 836 | return r; |
| 837 | 837 | } |
| 838 | 838 | |
| 839 | + | |
| 840 | +static void gfx_v8_0_free_microcode(struct amdgpu_device *adev) { | |
| 841 | + release_firmware(adev->gfx.pfp_fw); | |
| 842 | + adev->gfx.pfp_fw = NULL; | |
| 843 | + release_firmware(adev->gfx.me_fw); | |
| 844 | + adev->gfx.me_fw = NULL; | |
| 845 | + release_firmware(adev->gfx.ce_fw); | |
| 846 | + adev->gfx.ce_fw = NULL; | |
| 847 | + release_firmware(adev->gfx.rlc_fw); | |
| 848 | + adev->gfx.rlc_fw = NULL; | |
| 849 | + release_firmware(adev->gfx.mec_fw); | |
| 850 | + adev->gfx.mec_fw = NULL; | |
| 851 | + if ((adev->asic_type != CHIP_STONEY) && | |
| 852 | + (adev->asic_type != CHIP_TOPAZ)) | |
| 853 | + release_firmware(adev->gfx.mec2_fw); | |
| 854 | + adev->gfx.mec2_fw = NULL; | |
| 855 | + | |
| 856 | + kfree(adev->gfx.rlc.register_list_format); | |
| 857 | +} | |
| 858 | + | |
| 839 | 859 | static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) |
| 840 | 860 | { |
| 841 | 861 | const char *chip_name; |
| @@ -1983,7 +2003,7 @@ static int gfx_v8_0_sw_fini(void *handle) · 1141 unmodified lines | ||
| 1983 | 2003 | |
| 1984 | 2004 | gfx_v8_0_rlc_fini(adev); |
| 1985 | 2005 | |
| 1986 | − kfree(adev->gfx.rlc.register_list_format); | |
| 2006 | + gfx_v8_0_free_microcode(adev); | |
| 1987 | 2007 | |
| 1988 | 2008 | return 0; |
| 1989 | 2009 | } |
| @@ -3974,11 +3994,15 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) · 1984 unmodified lines | ||
| 3974 | 3994 | amdgpu_ring_write(ring, 0x3a00161a); |
| 3975 | 3995 | amdgpu_ring_write(ring, 0x0000002e); |
| 3976 | 3996 | break; |
| 3977 | − case CHIP_TOPAZ: | |
| 3978 | 3997 | case CHIP_CARRIZO: |
| 3979 | 3998 | amdgpu_ring_write(ring, 0x00000002); |
| 3980 | 3999 | amdgpu_ring_write(ring, 0x00000000); |
| 3981 | 4000 | break; |
| 4001 | + case CHIP_TOPAZ: | |
| 4002 | + amdgpu_ring_write(ring, adev->gfx.config.num_rbs == 1 ? | |
| 4003 | + 0x00000000 : 0x00000002); | |
| 4004 | + amdgpu_ring_write(ring, 0x00000000); | |
| 4005 | + break; | |
| 3982 | 4006 | case CHIP_STONEY: |
| 3983 | 4007 | amdgpu_ring_write(ring, 0x00000000); |
| 3984 | 4008 | amdgpu_ring_write(ring, 0x00000000); |
| @@ -72,6 +72,11 @@ static int iceland_dpm_sw_init(void *handle) · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | static int iceland_dpm_sw_fini(void *handle) |
| 74 | 74 | { |
| 75 | + struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
| 76 | + | |
| 77 | + release_firmware(adev->pm.fw); | |
| 78 | + adev->pm.fw = NULL; | |
| 79 | + | |
| 75 | 80 | return 0; |
| 76 | 81 | } |
| 77 | 82 | |
| @@ -105,6 +105,15 @@ static void sdma_v2_4_init_golden_registers(struct amdgpu_device *adev) · 104 unmodified lines | ||
| 105 | 105 | } |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | +static void sdma_v2_4_free_microcode(struct amdgpu_device *adev) | |
| 109 | +{ | |
| 110 | + int i; | |
| 111 | + for (i = 0; i < adev->sdma.num_instances; i++) { | |
| 112 | + release_firmware(adev->sdma.instance[i].fw); | |
| 113 | + adev->sdma.instance[i].fw = NULL; | |
| 114 | + } | |
| 115 | +} | |
| 116 | + | |
| 108 | 117 | /** |
| 109 | 118 | * sdma_v2_4_init_microcode - load ucode images from disk |
| 110 | 119 | * |
| @@ -461,6 +470,8 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) · 350 unmodified lines | ||
| 461 | 470 | /* Initialize the ring buffer's read and write pointers */ |
| 462 | 471 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 463 | 472 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 473 | + WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | |
| 474 | + WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | |
| 464 | 475 | |
| 465 | 476 | /* set the wb address whether it's enabled or not */ |
| 466 | 477 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -489,7 +500,11 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) · 22 unmodified lines | ||
| 489 | 500 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 490 | 501 | |
| 491 | 502 | ring->ready = true; |
| 503 | + } | |
| 492 | 504 | |
| 505 | + sdma_v2_4_enable(adev, true); | |
| 506 | + for (i = 0; i < adev->sdma.num_instances; i++) { | |
| 507 | + ring = &adev->sdma.instance[i].ring; | |
| 493 | 508 | r = amdgpu_ring_test_ring(ring); |
| 494 | 509 | if (r) { |
| 495 | 510 | ring->ready = false; |
| @@ -580,8 +595,8 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) · 84 unmodified lines | ||
| 580 | 595 | return -EINVAL; |
| 581 | 596 | } |
| 582 | 597 | |
| 583 | − /* unhalt the MEs */ | |
| 584 | − sdma_v2_4_enable(adev, true); | |
| 598 | + /* halt the engine before programing */ | |
| 599 | + sdma_v2_4_enable(adev, false); | |
| 585 | 600 | |
| 586 | 601 | /* start the gfx rings and rlc compute queues */ |
| 587 | 602 | r = sdma_v2_4_gfx_resume(adev); |
| @@ -1012,6 +1027,7 @@ static int sdma_v2_4_sw_fini(void *handle) · 424 unmodified lines | ||
| 1012 | 1027 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 1013 | 1028 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1014 | 1029 | |
| 1030 | + sdma_v2_4_free_microcode(adev); | |
| 1015 | 1031 | return 0; |
| 1016 | 1032 | } |
| 1017 | 1033 | |
| @@ -236,6 +236,15 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev) · 235 unmodified lines | ||
| 236 | 236 | } |
| 237 | 237 | } |
| 238 | 238 | |
| 239 | +static void sdma_v3_0_free_microcode(struct amdgpu_device *adev) | |
| 240 | +{ | |
| 241 | + int i; | |
| 242 | + for (i = 0; i < adev->sdma.num_instances; i++) { | |
| 243 | + release_firmware(adev->sdma.instance[i].fw); | |
| 244 | + adev->sdma.instance[i].fw = NULL; | |
| 245 | + } | |
| 246 | +} | |
| 247 | + | |
| 239 | 248 | /** |
| 240 | 249 | * sdma_v3_0_init_microcode - load ucode images from disk |
| 241 | 250 | * |
| @@ -672,6 +681,8 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) · 430 unmodified lines | ||
| 672 | 681 | /* Initialize the ring buffer's read and write pointers */ |
| 673 | 682 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 674 | 683 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 684 | + WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | |
| 685 | + WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | |
| 675 | 686 | |
| 676 | 687 | /* set the wb address whether it's enabled or not */ |
| 677 | 688 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -711,7 +722,15 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) · 33 unmodified lines | ||
| 711 | 722 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 712 | 723 | |
| 713 | 724 | ring->ready = true; |
| 725 | + } | |
| 726 | + | |
| 727 | + /* unhalt the MEs */ | |
| 728 | + sdma_v3_0_enable(adev, true); | |
| 729 | + /* enable sdma ring preemption */ | |
| 730 | + sdma_v3_0_ctx_switch_enable(adev, true); | |
| 714 | 731 | |
| 732 | + for (i = 0; i < adev->sdma.num_instances; i++) { | |
| 733 | + ring = &adev->sdma.instance[i].ring; | |
| 715 | 734 | r = amdgpu_ring_test_ring(ring); |
| 716 | 735 | if (r) { |
| 717 | 736 | ring->ready = false; |
| @@ -804,10 +823,9 @@ static int sdma_v3_0_start(struct amdgpu_device *adev) · 86 unmodified lines | ||
| 804 | 823 | } |
| 805 | 824 | } |
| 806 | 825 | |
| 807 | − /* unhalt the MEs */ | |
| 808 | − sdma_v3_0_enable(adev, true); | |
| 809 | − /* enable sdma ring preemption */ | |
| 810 | − sdma_v3_0_ctx_switch_enable(adev, true); | |
| 826 | + /* disble sdma engine before programing it */ | |
| 827 | + sdma_v3_0_ctx_switch_enable(adev, false); | |
| 828 | + sdma_v3_0_enable(adev, false); | |
| 811 | 829 | |
| 812 | 830 | /* start the gfx rings and rlc compute queues */ |
| 813 | 831 | r = sdma_v3_0_gfx_resume(adev); |
| @@ -1247,6 +1265,7 @@ static int sdma_v3_0_sw_fini(void *handle) · 433 unmodified lines | ||
| 1247 | 1265 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 1248 | 1266 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1249 | 1267 | |
| 1268 | + sdma_v3_0_free_microcode(adev); | |
| 1250 | 1269 | return 0; |
| 1251 | 1270 | } |
| 1252 | 1271 | |
| @@ -71,6 +71,11 @@ static int tonga_dpm_sw_init(void *handle) · 70 unmodified lines | ||
| 71 | 71 | |
| 72 | 72 | static int tonga_dpm_sw_fini(void *handle) |
| 73 | 73 | { |
| 74 | + struct amdgpu_device *adev = (struct amdgpu_device *)handle; | |
| 75 | + | |
| 76 | + release_firmware(adev->pm.fw); | |
| 77 | + adev->pm.fw = NULL; | |
| 78 | + | |
| 74 | 79 | return 0; |
| 75 | 80 | } |
| 76 | 81 | |
| @@ -157,6 +157,7 @@ struct amd_ip_funcs { · 156 unmodified lines | ||
| 157 | 157 | int (*hw_init)(void *handle); |
| 158 | 158 | /* tears down the hw state */ |
| 159 | 159 | int (*hw_fini)(void *handle); |
| 160 | + void (*late_fini)(void *handle); | |
| 160 | 161 | /* handles IP specific hw/sw changes for suspend */ |
| 161 | 162 | int (*suspend)(void *handle); |
| 162 | 163 | /* handles IP specific hw/sw changes for resume */ |
| @@ -581,6 +581,9 @@ typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device, · 580 unmodified lines | ||
| 581 | 581 | enum cgs_ucode_id type, |
| 582 | 582 | struct cgs_firmware_info *info); |
| 583 | 583 | |
| 584 | +typedef int (*cgs_rel_firmware)(struct cgs_device *cgs_device, | |
| 585 | + enum cgs_ucode_id type); | |
| 586 | + | |
| 584 | 587 | typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, |
| 585 | 588 | enum amd_ip_block_type block_type, |
| 586 | 589 | enum amd_powergating_state state); |
| @@ -645,6 +648,7 @@ struct cgs_ops { · 58 unmodified lines | ||
| 645 | 648 | cgs_set_camera_voltages_t set_camera_voltages; |
| 646 | 649 | /* Firmware Info */ |
| 647 | 650 | cgs_get_firmware_info get_firmware_info; |
| 651 | + cgs_rel_firmware rel_firmware; | |
| 648 | 652 | /* cg pg interface*/ |
| 649 | 653 | cgs_set_powergating_state set_powergating_state; |
| 650 | 654 | cgs_set_clockgating_state set_clockgating_state; |
| @@ -738,6 +742,8 @@ struct cgs_device · 87 unmodified lines | ||
| 738 | 742 | CGS_CALL(set_camera_voltages,dev,mask,voltages) |
| 739 | 743 | #define cgs_get_firmware_info(dev, type, info) \ |
| 740 | 744 | CGS_CALL(get_firmware_info, dev, type, info) |
| 745 | +#define cgs_rel_firmware(dev, type) \ | |
| 746 | + CGS_CALL(rel_firmware, dev, type) | |
| 741 | 747 | #define cgs_set_powergating_state(dev, block_type, state) \ |
| 742 | 748 | CGS_CALL(set_powergating_state, dev, block_type, state) |
| 743 | 749 | #define cgs_set_clockgating_state(dev, block_type, state) \ |
| @@ -73,11 +73,14 @@ static int pp_sw_init(void *handle) · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); |
| 75 | 75 | if (ret) |
| 76 | − goto err; | |
| 76 | + goto err1; | |
| 77 | 77 | |
| 78 | 78 | pr_info("amdgpu: powerplay initialized\n"); |
| 79 | 79 | |
| 80 | 80 | return 0; |
| 81 | +err1: | |
| 82 | + if (hwmgr->pptable_func->pptable_fini) | |
| 83 | + hwmgr->pptable_func->pptable_fini(hwmgr); | |
| 81 | 84 | err: |
| 82 | 85 | pr_err("amdgpu: powerplay initialization failed\n"); |
| 83 | 86 | return ret; |
| @@ -100,6 +103,9 @@ static int pp_sw_fini(void *handle) · 16 unmodified lines | ||
| 100 | 103 | if (hwmgr->hwmgr_func->backend_fini != NULL) |
| 101 | 104 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); |
| 102 | 105 | |
| 106 | + if (hwmgr->pptable_func->pptable_fini) | |
| 107 | + hwmgr->pptable_func->pptable_fini(hwmgr); | |
| 108 | + | |
| 103 | 109 | return ret; |
| 104 | 110 | } |
| 105 | 111 | |
| @@ -58,9 +58,6 @@ static void pem_fini(struct pp_eventmgr *eventmgr) · 57 unmodified lines | ||
| 58 | 58 | pem_unregister_interrupts(eventmgr); |
| 59 | 59 | |
| 60 | 60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); |
| 61 | − | |
| 62 | − if (eventmgr != NULL) | |
| 63 | − kfree(eventmgr); | |
| 64 | 61 | } |
| 65 | 62 | |
| 66 | 63 | int eventmgr_init(struct pp_instance *handle) |
| @@ -1830,7 +1830,7 @@ static uint16_t fiji_find_closest_vddci(struct pp_hwmgr *hwmgr, uint16_t vddci) · 1829 unmodified lines | ||
| 1830 | 1830 | |
| 1831 | 1831 | PP_ASSERT_WITH_CODE(false, |
| 1832 | 1832 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
| 1833 | − return vddci_table->entries[i].value); | |
| 1833 | + return vddci_table->entries[i-1].value); | |
| 1834 | 1834 | } |
| 1835 | 1835 | |
| 1836 | 1836 | static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, |
| @@ -93,6 +93,13 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr) · 92 unmodified lines | ||
| 93 | 93 | if (hwmgr == NULL || hwmgr->ps == NULL) |
| 94 | 94 | return -EINVAL; |
| 95 | 95 | |
| 96 | + /* do hwmgr finish*/ | |
| 97 | + kfree(hwmgr->backend); | |
| 98 | + | |
| 99 | + kfree(hwmgr->start_thermal_controller.function_list); | |
| 100 | + | |
| 101 | + kfree(hwmgr->set_temperature_range.function_list); | |
| 102 | + | |
| 96 | 103 | kfree(hwmgr->ps); |
| 97 | 104 | kfree(hwmgr); |
| 98 | 105 | return 0; |
| @@ -462,7 +469,7 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u · 363 unmodified lines | ||
| 462 | 469 | |
| 463 | 470 | PP_ASSERT_WITH_CODE(false, |
| 464 | 471 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
| 465 | − return vddci_table->entries[i].value); | |
| 472 | + return vddci_table->entries[i-1].value); | |
| 466 | 473 | } |
| 467 | 474 | |
| 468 | 475 | int phm_find_boot_level(void *table, |
| @@ -286,7 +286,7 @@ int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr) · 285 unmodified lines | ||
| 286 | 286 | |
| 287 | 287 | if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, |
| 288 | 288 | (uint8_t *)&data->power_tune_table, |
| 289 | − sizeof(struct SMU74_Discrete_PmFuses), data->sram_end)) | |
| 289 | + (sizeof(struct SMU74_Discrete_PmFuses) - 92), data->sram_end)) | |
| 290 | 290 | PP_ASSERT_WITH_CODE(false, |
| 291 | 291 | "Attempt to download PmFuseTable Failed!", |
| 292 | 292 | return -EINVAL); |
| @@ -2847,27 +2847,6 @@ static int tonga_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) · 2846 unmodified lines | ||
| 2847 | 2847 | } |
| 2848 | 2848 | } |
| 2849 | 2849 | |
| 2850 | − /* Initialize Vddc DPM table based on allow Vddc values. And populate corresponding std values. */ | |
| 2851 | − for (i = 0; i < allowed_vdd_sclk_table->count; i++) { | |
| 2852 | − data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddc; | |
| 2853 | − /* tonga_hwmgr->dpm_table.VddcTable.dpm_levels[i].param1 = stdVoltageTable->entries[i].Leakage; */ | |
| 2854 | − /* param1 is for corresponding std voltage */ | |
| 2855 | − data->dpm_table.vddc_table.dpm_levels[i].enabled = 1; | |
| 2856 | − } | |
| 2857 | − data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count; | |
| 2858 | − | |
| 2859 | − if (NULL != allowed_vdd_mclk_table) { | |
| 2860 | − /* Initialize Vddci DPM table based on allow Mclk values */ | |
| 2861 | − for (i = 0; i < allowed_vdd_mclk_table->count; i++) { | |
| 2862 | − data->dpm_table.vdd_ci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddci; | |
| 2863 | − data->dpm_table.vdd_ci_table.dpm_levels[i].enabled = 1; | |
| 2864 | − data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].mvdd; | |
| 2865 | − data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1; | |
| 2866 | − } | |
| 2867 | − data->dpm_table.vdd_ci_table.count = allowed_vdd_mclk_table->count; | |
| 2868 | − data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count; | |
| 2869 | − } | |
| 2870 | − | |
| 2871 | 2850 | /* setup PCIE gen speed levels*/ |
| 2872 | 2851 | tonga_setup_default_pcie_tables(hwmgr); |
| 2873 | 2852 | |
| @@ -1040,48 +1040,44 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) · 1039 unmodified lines | ||
| 1040 | 1040 | struct phm_ppt_v1_information *pp_table_information = |
| 1041 | 1041 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
| 1042 | 1042 | |
| 1043 | − if (NULL != hwmgr->soft_pp_table) { | |
| 1044 | − kfree(hwmgr->soft_pp_table); | |
| 1043 | + if (NULL != hwmgr->soft_pp_table) | |
| 1045 | 1044 | hwmgr->soft_pp_table = NULL; |
| 1046 | − } | |
| 1047 | 1045 | |
| 1048 | − if (NULL != pp_table_information->vdd_dep_on_sclk) | |
| 1049 | − pp_table_information->vdd_dep_on_sclk = NULL; | |
| 1046 | + kfree(pp_table_information->vdd_dep_on_sclk); | |
| 1047 | + pp_table_information->vdd_dep_on_sclk = NULL; | |
| 1050 | 1048 | |
| 1051 | − if (NULL != pp_table_information->vdd_dep_on_mclk) | |
| 1052 | − pp_table_information->vdd_dep_on_mclk = NULL; | |
| 1049 | + kfree(pp_table_information->vdd_dep_on_mclk); | |
| 1050 | + pp_table_information->vdd_dep_on_mclk = NULL; | |
| 1053 | 1051 | |
| 1054 | − if (NULL != pp_table_information->valid_mclk_values) | |
| 1055 | − pp_table_information->valid_mclk_values = NULL; | |
| 1052 | + kfree(pp_table_information->valid_mclk_values); | |
| 1053 | + pp_table_information->valid_mclk_values = NULL; | |
| 1056 | 1054 | |
| 1057 | − if (NULL != pp_table_information->valid_sclk_values) | |
| 1058 | − pp_table_information->valid_sclk_values = NULL; | |
| 1055 | + kfree(pp_table_information->valid_sclk_values); | |
| 1056 | + pp_table_information->valid_sclk_values = NULL; | |
| 1059 | 1057 | |
| 1060 | − if (NULL != pp_table_information->vddc_lookup_table) | |
| 1061 | − pp_table_information->vddc_lookup_table = NULL; | |
| 1058 | + kfree(pp_table_information->vddc_lookup_table); | |
| 1059 | + pp_table_information->vddc_lookup_table = NULL; | |
| 1062 | 1060 | |
| 1063 | − if (NULL != pp_table_information->vddgfx_lookup_table) | |
| 1064 | − pp_table_information->vddgfx_lookup_table = NULL; | |
| 1061 | + kfree(pp_table_information->vddgfx_lookup_table); | |
| 1062 | + pp_table_information->vddgfx_lookup_table = NULL; | |
| 1065 | 1063 | |
| 1066 | − if (NULL != pp_table_information->mm_dep_table) | |
| 1067 | − pp_table_information->mm_dep_table = NULL; | |
| 1064 | + kfree(pp_table_information->mm_dep_table); | |
| 1065 | + pp_table_information->mm_dep_table = NULL; | |
| 1068 | 1066 | |
| 1069 | − if (NULL != pp_table_information->cac_dtp_table) | |
| 1070 | − pp_table_information->cac_dtp_table = NULL; | |
| 1067 | + kfree(pp_table_information->cac_dtp_table); | |
| 1068 | + pp_table_information->cac_dtp_table = NULL; | |
| 1071 | 1069 | |
| 1072 | − if (NULL != hwmgr->dyn_state.cac_dtp_table) | |
| 1073 | − hwmgr->dyn_state.cac_dtp_table = NULL; | |
| 1070 | + kfree(hwmgr->dyn_state.cac_dtp_table); | |
| 1071 | + hwmgr->dyn_state.cac_dtp_table = NULL; | |
| 1074 | 1072 | |
| 1075 | − if (NULL != pp_table_information->ppm_parameter_table) | |
| 1076 | − pp_table_information->ppm_parameter_table = NULL; | |
| 1073 | + kfree(pp_table_information->ppm_parameter_table); | |
| 1074 | + pp_table_information->ppm_parameter_table = NULL; | |
| 1077 | 1075 | |
| 1078 | − if (NULL != pp_table_information->pcie_table) | |
| 1079 | − pp_table_information->pcie_table = NULL; | |
| 1076 | + kfree(pp_table_information->pcie_table); | |
| 1077 | + pp_table_information->pcie_table = NULL; | |
| 1080 | 1078 | |
| 1081 | − if (NULL != hwmgr->pptable) { | |
| 1082 | − kfree(hwmgr->pptable); | |
| 1083 | − hwmgr->pptable = NULL; | |
| 1084 | − } | |
| 1079 | + kfree(hwmgr->pptable); | |
| 1080 | + hwmgr->pptable = NULL; | |
| 1085 | 1081 | |
| 1086 | 1082 | return result; |
| 1087 | 1083 | } |
| @@ -1006,10 +1006,16 @@ static int fiji_smu_init(struct pp_smumgr *smumgr) · 1005 unmodified lines | ||
| 1006 | 1006 | |
| 1007 | 1007 | static int fiji_smu_fini(struct pp_smumgr *smumgr) |
| 1008 | 1008 | { |
| 1009 | + struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend); | |
| 1010 | + | |
| 1011 | + smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | |
| 1012 | + | |
| 1009 | 1013 | if (smumgr->backend) { |
| 1010 | 1014 | kfree(smumgr->backend); |
| 1011 | 1015 | smumgr->backend = NULL; |
| 1012 | 1016 | } |
| 1017 | + | |
| 1018 | + cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | |
| 1013 | 1019 | return 0; |
| 1014 | 1020 | } |
| 1015 | 1021 | |
| @@ -469,6 +469,7 @@ int polaris10_smu_fini(struct pp_smumgr *smumgr) · 468 unmodified lines | ||
| 469 | 469 | kfree(smumgr->backend); |
| 470 | 470 | smumgr->backend = NULL; |
| 471 | 471 | } |
| 472 | + cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | |
| 472 | 473 | return 0; |
| 473 | 474 | } |
| 474 | 475 | |
| @@ -81,6 +81,7 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | int smum_fini(struct pp_smumgr *smumgr) |
| 83 | 83 | { |
| 84 | + kfree(smumgr->device); | |
| 84 | 85 | kfree(smumgr); |
| 85 | 86 | return 0; |
| 86 | 87 | } |
| @@ -328,10 +328,17 @@ int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, · 327 unmodified lines | ||
| 328 | 328 | |
| 329 | 329 | static int tonga_smu_fini(struct pp_smumgr *smumgr) |
| 330 | 330 | { |
| 331 | + struct tonga_smumgr *priv = (struct tonga_smumgr *)(smumgr->backend); | |
| 332 | + | |
| 333 | + smu_free_memory(smumgr->device, (void *)priv->smu_buffer.handle); | |
| 334 | + smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | |
| 335 | + | |
| 331 | 336 | if (smumgr->backend != NULL) { |
| 332 | 337 | kfree(smumgr->backend); |
| 333 | 338 | smumgr->backend = NULL; |
| 334 | 339 | } |
| 340 | + | |
| 341 | + cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | |
| 335 | 342 | return 0; |
| 336 | 343 | } |
| 337 | 344 | |
| @@ -42,9 +42,10 @@ static const struct regmap_config fsl_dcu_regmap_config = { · 41 unmodified lines | ||
| 42 | 42 | .reg_bits = 32, |
| 43 | 43 | .reg_stride = 4, |
| 44 | 44 | .val_bits = 32, |
| 45 | − .cache_type = REGCACHE_RBTREE, | |
| 45 | + .cache_type = REGCACHE_FLAT, | |
| 46 | 46 | |
| 47 | 47 | .volatile_reg = fsl_dcu_drm_is_volatile_reg, |
| 48 | + .max_register = 0x11fc, | |
| 48 | 49 | }; |
| 49 | 50 | |
| 50 | 51 | static int fsl_dcu_drm_irq_init(struct drm_device *dev) |
| @@ -408,7 +408,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, · 407 unmodified lines | ||
| 408 | 408 | } |
| 409 | 409 | |
| 410 | 410 | adreno_gpu->memptrs = msm_gem_vaddr(adreno_gpu->memptrs_bo); |
| 411 | − if (!adreno_gpu->memptrs) { | |
| 411 | + if (IS_ERR(adreno_gpu->memptrs)) { | |
| 412 | 412 | dev_err(drm->dev, "could not vmap memptrs\n"); |
| 413 | 413 | return -ENOMEM; |
| 414 | 414 | } |
| @@ -159,6 +159,10 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, · 158 unmodified lines | ||
| 159 | 159 | dev->mode_config.fb_base = paddr; |
| 160 | 160 | |
| 161 | 161 | fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo); |
| 162 | + if (IS_ERR(fbi->screen_base)) { | |
| 163 | + ret = PTR_ERR(fbi->screen_base); | |
| 164 | + goto fail_unlock; | |
| 165 | + } | |
| 162 | 166 | fbi->screen_size = fbdev->bo->size; |
| 163 | 167 | fbi->fix.smem_start = paddr; |
| 164 | 168 | fbi->fix.smem_len = fbdev->bo->size; |
| @@ -398,6 +398,8 @@ void *msm_gem_vaddr_locked(struct drm_gem_object *obj) · 397 unmodified lines | ||
| 398 | 398 | return ERR_CAST(pages); |
| 399 | 399 | msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, |
| 400 | 400 | VM_MAP, pgprot_writecombine(PAGE_KERNEL)); |
| 401 | + if (msm_obj->vaddr == NULL) | |
| 402 | + return ERR_PTR(-ENOMEM); | |
| 401 | 403 | } |
| 402 | 404 | return msm_obj->vaddr; |
| 403 | 405 | } |
| @@ -40,12 +40,14 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | submit->dev = dev; |
| 42 | 42 | submit->gpu = gpu; |
| 43 | + submit->fence = NULL; | |
| 43 | 44 | submit->pid = get_pid(task_pid(current)); |
| 44 | 45 | |
| 45 | 46 | /* initially, until copy_from_user() and bo lookup succeeds: */ |
| 46 | 47 | submit->nr_bos = 0; |
| 47 | 48 | submit->nr_cmds = 0; |
| 48 | 49 | |
| 50 | + INIT_LIST_HEAD(&submit->node); | |
| 49 | 51 | INIT_LIST_HEAD(&submit->bo_list); |
| 50 | 52 | ww_acquire_init(&submit->ticket, &reservation_ww_class); |
| 51 | 53 | |
| @@ -75,6 +77,11 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 23 unmodified lines | ||
| 75 | 77 | void __user *userptr = |
| 76 | 78 | u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); |
| 77 | 79 | |
| 80 | + /* make sure we don't have garbage flags, in case we hit | |
| 81 | + * error path before flags is initialized: | |
| 82 | + */ | |
| 83 | + submit->bos[i].flags = 0; | |
| 84 | + | |
| 78 | 85 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); |
| 79 | 86 | if (ret) { |
| 80 | 87 | ret = -EFAULT; |
| @@ -312,6 +312,9 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) · 311 unmodified lines | ||
| 312 | 312 | struct msm_gem_object *obj = submit->bos[idx].obj; |
| 313 | 313 | const char *buf = msm_gem_vaddr_locked(&obj->base); |
| 314 | 314 | |
| 315 | + if (IS_ERR(buf)) | |
| 316 | + continue; | |
| 317 | + | |
| 315 | 318 | buf += iova - submit->bos[idx].iova; |
| 316 | 319 | |
| 317 | 320 | rd_write_section(rd, RD_GPUADDR, |
| @@ -40,6 +40,10 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) · 39 unmodified lines | ||
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | ring->start = msm_gem_vaddr_locked(ring->bo); |
| 43 | + if (IS_ERR(ring->start)) { | |
| 44 | + ret = PTR_ERR(ring->start); | |
| 45 | + goto fail; | |
| 46 | + } | |
| 43 | 47 | ring->end = ring->start + (size / 4); |
| 44 | 48 | ring->cur = ring->start; |
| 45 | 49 | |
| @@ -16,9 +16,9 @@ enum nvkm_devidx { · 15 unmodified lines | ||
| 16 | 16 | NVKM_SUBDEV_MC, |
| 17 | 17 | NVKM_SUBDEV_BUS, |
| 18 | 18 | NVKM_SUBDEV_TIMER, |
| 19 | + NVKM_SUBDEV_INSTMEM, | |
| 19 | 20 | NVKM_SUBDEV_FB, |
| 20 | 21 | NVKM_SUBDEV_LTC, |
| 21 | − NVKM_SUBDEV_INSTMEM, | |
| 22 | 22 | NVKM_SUBDEV_MMU, |
| 23 | 23 | NVKM_SUBDEV_BAR, |
| 24 | 24 | NVKM_SUBDEV_PMU, |
| @@ -25,7 +25,8 @@ u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask, · 24 unmodified lines | ||
| 25 | 25 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *); |
| 26 | 26 | |
| 27 | 27 | struct nvbios_ocfg { |
| 28 | − u16 match; | |
| 28 | + u8 proto; | |
| 29 | + u8 flags; | |
| 29 | 30 | u16 clkcmp[2]; |
| 30 | 31 | }; |
| 31 | 32 | |
| @@ -33,7 +34,7 @@ u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx, · 1 unmodified line | ||
| 33 | 34 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len); |
| 34 | 35 | u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx, |
| 35 | 36 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
| 36 | −u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type, | |
| 37 | +u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u8 proto, u8 flags, | |
| 37 | 38 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
| 38 | 39 | u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz); |
| 39 | 40 | #endif |
| @@ -552,6 +552,7 @@ nouveau_fbcon_init(struct drm_device *dev) · 551 unmodified lines | ||
| 552 | 552 | if (ret) |
| 553 | 553 | goto fini; |
| 554 | 554 | |
| 555 | + fbcon->helper.fbdev->pixmap.buf_align = 4; | |
| 555 | 556 | return 0; |
| 556 | 557 | |
| 557 | 558 | fini: |
| @@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 81 unmodified lines | ||
| 82 | 82 | uint32_t fg; |
| 83 | 83 | uint32_t bg; |
| 84 | 84 | uint32_t dsize; |
| 85 | − uint32_t width; | |
| 86 | 85 | uint32_t *data = (uint32_t *)image->data; |
| 87 | 86 | int ret; |
| 88 | 87 | |
| @@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 4 unmodified lines | ||
| 93 | 92 | if (ret) |
| 94 | 93 | return ret; |
| 95 | 94 | |
| 96 | − width = ALIGN(image->width, 8); | |
| 97 | − dsize = ALIGN(width * image->height, 32) >> 5; | |
| 98 | − | |
| 99 | 95 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 100 | 96 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| 101 | 97 | fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; |
| @@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 9 unmodified lines | ||
| 111 | 107 | ((image->dx + image->width) & 0xffff)); |
| 112 | 108 | OUT_RING(chan, bg); |
| 113 | 109 | OUT_RING(chan, fg); |
| 114 | − OUT_RING(chan, (image->height << 16) | width); | |
| 110 | + OUT_RING(chan, (image->height << 16) | image->width); | |
| 115 | 111 | OUT_RING(chan, (image->height << 16) | image->width); |
| 116 | 112 | OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); |
| 117 | 113 | |
| 114 | + dsize = ALIGN(image->width * image->height, 32) >> 5; | |
| 118 | 115 | while (dsize) { |
| 119 | 116 | int iter_len = dsize > 128 ? 128 : dsize; |
| 120 | 117 | |
| @@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 94 unmodified lines | ||
| 95 | 95 | struct nouveau_fbdev *nfbdev = info->par; |
| 96 | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| 97 | 97 | struct nouveau_channel *chan = drm->channel; |
| 98 | − uint32_t width, dwords, *data = (uint32_t *)image->data; | |
| 98 | + uint32_t dwords, *data = (uint32_t *)image->data; | |
| 99 | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| 100 | 100 | uint32_t *palette = info->pseudo_palette; |
| 101 | 101 | int ret; |
| @@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 5 unmodified lines | ||
| 107 | 107 | if (ret) |
| 108 | 108 | return ret; |
| 109 | 109 | |
| 110 | − width = ALIGN(image->width, 32); | |
| 111 | − dwords = (width * image->height) >> 5; | |
| 112 | − | |
| 113 | 110 | BEGIN_NV04(chan, NvSub2D, 0x0814, 2); |
| 114 | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 115 | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 12 unmodified lines | ||
| 128 | 125 | OUT_RING(chan, 0); |
| 129 | 126 | OUT_RING(chan, image->dy); |
| 130 | 127 | |
| 128 | + dwords = ALIGN(image->width * image->height, 32) >> 5; | |
| 131 | 129 | while (dwords) { |
| 132 | 130 | int push = dwords > 2047 ? 2047 : dwords; |
| 133 | 131 | |
| @@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 94 unmodified lines | ||
| 95 | 95 | struct nouveau_fbdev *nfbdev = info->par; |
| 96 | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| 97 | 97 | struct nouveau_channel *chan = drm->channel; |
| 98 | − uint32_t width, dwords, *data = (uint32_t *)image->data; | |
| 98 | + uint32_t dwords, *data = (uint32_t *)image->data; | |
| 99 | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| 100 | 100 | uint32_t *palette = info->pseudo_palette; |
| 101 | 101 | int ret; |
| @@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 5 unmodified lines | ||
| 107 | 107 | if (ret) |
| 108 | 108 | return ret; |
| 109 | 109 | |
| 110 | − width = ALIGN(image->width, 32); | |
| 111 | − dwords = (width * image->height) >> 5; | |
| 112 | − | |
| 113 | 110 | BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); |
| 114 | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 115 | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) · 12 unmodified lines | ||
| 128 | 125 | OUT_RING (chan, 0); |
| 129 | 126 | OUT_RING (chan, image->dy); |
| 130 | 127 | |
| 128 | + dwords = ALIGN(image->width * image->height, 32) >> 5; | |
| 131 | 129 | while (dwords) { |
| 132 | 130 | int push = dwords > 2047 ? 2047 : dwords; |
| 133 | 131 | |
| @@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/disp/piornv50.o · 17 unmodified lines | ||
| 18 | 18 | nvkm-y += nvkm/engine/disp/sornv50.o |
| 19 | 19 | nvkm-y += nvkm/engine/disp/sorg94.o |
| 20 | 20 | nvkm-y += nvkm/engine/disp/sorgf119.o |
| 21 | +nvkm-y += nvkm/engine/disp/sorgm107.o | |
| 21 | 22 | nvkm-y += nvkm/engine/disp/sorgm200.o |
| 22 | 23 | nvkm-y += nvkm/engine/disp/dport.o |
| 23 | 24 | |
| @@ -76,6 +76,7 @@ exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl, · 75 unmodified lines | ||
| 76 | 76 | mask |= 0x0001 << or; |
| 77 | 77 | mask |= 0x0100 << head; |
| 78 | 78 | |
| 79 | + | |
| 79 | 80 | list_for_each_entry(outp, &disp->base.outp, head) { |
| 80 | 81 | if ((outp->info.hasht & 0xff) == type && |
| 81 | 82 | (outp->info.hashm & mask) == mask) { |
| @@ -155,25 +156,21 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) · 73 unmodified lines | ||
| 155 | 156 | if (!outp) |
| 156 | 157 | return NULL; |
| 157 | 158 | |
| 159 | + *conf = (ctrl & 0x00000f00) >> 8; | |
| 158 | 160 | switch (outp->info.type) { |
| 159 | 161 | case DCB_OUTPUT_TMDS: |
| 160 | − *conf = (ctrl & 0x00000f00) >> 8; | |
| 161 | 162 | if (*conf == 5) |
| 162 | 163 | *conf |= 0x0100; |
| 163 | 164 | break; |
| 164 | 165 | case DCB_OUTPUT_LVDS: |
| 165 | − *conf = disp->sor.lvdsconf; | |
| 166 | − break; | |
| 167 | − case DCB_OUTPUT_DP: | |
| 168 | − *conf = (ctrl & 0x00000f00) >> 8; | |
| 166 | + *conf |= disp->sor.lvdsconf; | |
| 169 | 167 | break; |
| 170 | − case DCB_OUTPUT_ANALOG: | |
| 171 | 168 | default: |
| 172 | − *conf = 0x00ff; | |
| 173 | 169 | break; |
| 174 | 170 | } |
| 175 | 171 | |
| 176 | − data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | |
| 172 | + data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, | |
| 173 | + &ver, &hdr, &cnt, &len, &info2); | |
| 177 | 174 | if (data && id < 0xff) { |
| 178 | 175 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
| 179 | 176 | if (data) { |
| @@ -36,7 +36,7 @@ gm107_disp = { · 35 unmodified lines | ||
| 36 | 36 | .outp.internal.crt = nv50_dac_output_new, |
| 37 | 37 | .outp.internal.tmds = nv50_sor_output_new, |
| 38 | 38 | .outp.internal.lvds = nv50_sor_output_new, |
| 39 | − .outp.internal.dp = gf119_sor_dp_new, | |
| 39 | + .outp.internal.dp = gm107_sor_dp_new, | |
| 40 | 40 | .dac.nr = 3, |
| 41 | 41 | .dac.power = nv50_dac_power, |
| 42 | 42 | .dac.sense = nv50_dac_sense, |
| @@ -387,22 +387,17 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) · 386 unmodified lines | ||
| 387 | 387 | if (!outp) |
| 388 | 388 | return NULL; |
| 389 | 389 | |
| 390 | + *conf = (ctrl & 0x00000f00) >> 8; | |
| 390 | 391 | if (outp->info.location == 0) { |
| 391 | 392 | switch (outp->info.type) { |
| 392 | 393 | case DCB_OUTPUT_TMDS: |
| 393 | − *conf = (ctrl & 0x00000f00) >> 8; | |
| 394 | 394 | if (*conf == 5) |
| 395 | 395 | *conf |= 0x0100; |
| 396 | 396 | break; |
| 397 | 397 | case DCB_OUTPUT_LVDS: |
| 398 | − *conf = disp->sor.lvdsconf; | |
| 398 | + *conf |= disp->sor.lvdsconf; | |
| 399 | 399 | break; |
| 400 | − case DCB_OUTPUT_DP: | |
| 401 | − *conf = (ctrl & 0x00000f00) >> 8; | |
| 402 | − break; | |
| 403 | − case DCB_OUTPUT_ANALOG: | |
| 404 | 400 | default: |
| 405 | − *conf = 0x00ff; | |
| 406 | 401 | break; |
| 407 | 402 | } |
| 408 | 403 | } else { |
| @@ -410,7 +405,8 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) · 1 unmodified line | ||
| 410 | 405 | pclk = pclk / 2; |
| 411 | 406 | } |
| 412 | 407 | |
| 413 | − data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | |
| 408 | + data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, | |
| 409 | + &ver, &hdr, &cnt, &len, &info2); | |
| 414 | 410 | if (data && id < 0xff) { |
| 415 | 411 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
| 416 | 412 | if (data) { |
| @@ -62,7 +62,12 @@ int g94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int); · 61 unmodified lines | ||
| 62 | 62 | int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, |
| 63 | 63 | struct nvkm_output **); |
| 64 | 64 | int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool); |
| 65 | +int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int); | |
| 65 | 66 | |
| 66 | −int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | |
| 67 | − struct nvkm_output **); | |
| 67 | +int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | |
| 68 | + struct nvkm_output **); | |
| 69 | +int gm107_sor_dp_pattern(struct nvkm_output_dp *, int); | |
| 70 | + | |
| 71 | +int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | |
| 72 | + struct nvkm_output **); | |
| 68 | 73 | #endif |
| @@ -40,8 +40,7 @@ static int · 39 unmodified lines | ||
| 40 | 40 | gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) |
| 41 | 41 | { |
| 42 | 42 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; |
| 43 | − const u32 loff = gf119_sor_loff(outp); | |
| 44 | − nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern); | |
| 43 | + nvkm_mask(device, 0x61c110, 0x0f0f0f0f, 0x01010101 * pattern); | |
| 45 | 44 | return 0; |
| 46 | 45 | } |
| 47 | 46 | |
| @@ -64,7 +63,7 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) · 16 unmodified lines | ||
| 64 | 63 | return 0; |
| 65 | 64 | } |
| 66 | 65 | |
| 67 | −static int | |
| 66 | +int | |
| 68 | 67 | gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp, |
| 69 | 68 | int ln, int vs, int pe, int pc) |
| 70 | 69 | { |
| @@ -0,0 +1,53 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright 2016 Red Hat Inc. | |
| 3 | + * | |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | + * copy of this software and associated documentation files (the "Software"), | |
| 6 | + * to deal in the Software without restriction, including without limitation | |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the | |
| 9 | + * Software is furnished to do so, subject to the following conditions: | |
| 10 | + * | |
| 11 | + * The above copyright notice and this permission notice shall be included in | |
| 12 | + * all copies or substantial portions of the Software. | |
| 13 | + * | |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 17 | + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 18 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 19 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 20 | + * OTHER DEALINGS IN THE SOFTWARE. | |
| 21 | + * | |
| 22 | + * Authors: Ben Skeggs <bskeggs@redhat.com> | |
| 23 | + */ | |
| 24 | +#include "nv50.h" | |
| 25 | +#include "outpdp.h" | |
| 26 | + | |
| 27 | +int | |
| 28 | +gm107_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | |
| 29 | +{ | |
| 30 | + struct nvkm_device *device = outp->base.disp->engine.subdev.device; | |
| 31 | + const u32 soff = outp->base.or * 0x800; | |
| 32 | + const u32 data = 0x01010101 * pattern; | |
| 33 | + if (outp->base.info.sorconf.link & 1) | |
| 34 | + nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data); | |
| 35 | + else | |
| 36 | + nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data); | |
| 37 | + return 0; | |
| 38 | +} | |
| 39 | + | |
| 40 | +static const struct nvkm_output_dp_func | |
| 41 | +gm107_sor_dp_func = { | |
| 42 | + .pattern = gm107_sor_dp_pattern, | |
| 43 | + .lnk_pwr = g94_sor_dp_lnk_pwr, | |
| 44 | + .lnk_ctl = gf119_sor_dp_lnk_ctl, | |
| 45 | + .drv_ctl = gf119_sor_dp_drv_ctl, | |
| 46 | +}; | |
| 47 | + | |
| 48 | +int | |
| 49 | +gm107_sor_dp_new(struct nvkm_disp *disp, int index, | |
| 50 | + struct dcb_output *dcbE, struct nvkm_output **poutp) | |
| 51 | +{ | |
| 52 | + return nvkm_output_dp_new_(&gm107_sor_dp_func, disp, index, dcbE, poutp); | |
| 53 | +} | |
| @@ -56,19 +56,6 @@ gm200_sor_dp_lane_map(struct nvkm_device *device, u8 lane) · 55 unmodified lines | ||
| 56 | 56 | return lane * 0x08; |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | −static int | |
| 60 | −gm200_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | |
| 61 | −{ | |
| 62 | − struct nvkm_device *device = outp->base.disp->engine.subdev.device; | |
| 63 | − const u32 soff = gm200_sor_soff(outp); | |
| 64 | − const u32 data = 0x01010101 * pattern; | |
| 65 | − if (outp->base.info.sorconf.link & 1) | |
| 66 | − nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data); | |
| 67 | − else | |
| 68 | − nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data); | |
| 69 | − return 0; | |
| 70 | −} | |
| 71 | − | |
| 72 | 59 | static int |
| 73 | 60 | gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) |
| 74 | 61 | { |
| @@ -129,7 +116,7 @@ gm200_sor_dp_drv_ctl(struct nvkm_output_dp *outp, · 54 unmodified lines | ||
| 129 | 116 | |
| 130 | 117 | static const struct nvkm_output_dp_func |
| 131 | 118 | gm200_sor_dp_func = { |
| 132 | − .pattern = gm200_sor_dp_pattern, | |
| 119 | + .pattern = gm107_sor_dp_pattern, | |
| 133 | 120 | .lnk_pwr = gm200_sor_dp_lnk_pwr, |
| 134 | 121 | .lnk_ctl = gf119_sor_dp_lnk_ctl, |
| 135 | 122 | .drv_ctl = gm200_sor_dp_drv_ctl, |
| @@ -949,22 +949,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *gr, int gpc) · 948 unmodified lines | ||
| 949 | 949 | } |
| 950 | 950 | |
| 951 | 951 | static const struct nvkm_enum gf100_mp_warp_error[] = { |
| 952 | − { 0x00, "NO_ERROR" }, | |
| 953 | − { 0x01, "STACK_MISMATCH" }, | |
| 952 | + { 0x01, "STACK_ERROR" }, | |
| 953 | + { 0x02, "API_STACK_ERROR" }, | |
| 954 | + { 0x03, "RET_EMPTY_STACK_ERROR" }, | |
| 955 | + { 0x04, "PC_WRAP" }, | |
| 954 | 956 | { 0x05, "MISALIGNED_PC" }, |
| 955 | − { 0x08, "MISALIGNED_GPR" }, | |
| 956 | − { 0x09, "INVALID_OPCODE" }, | |
| 957 | − { 0x0d, "GPR_OUT_OF_BOUNDS" }, | |
| 958 | − { 0x0e, "MEM_OUT_OF_BOUNDS" }, | |
| 959 | − { 0x0f, "UNALIGNED_MEM_ACCESS" }, | |
| 957 | + { 0x06, "PC_OVERFLOW" }, | |
| 958 | + { 0x07, "MISALIGNED_IMMC_ADDR" }, | |
| 959 | + { 0x08, "MISALIGNED_REG" }, | |
| 960 | + { 0x09, "ILLEGAL_INSTR_ENCODING" }, | |
| 961 | + { 0x0a, "ILLEGAL_SPH_INSTR_COMBO" }, | |
| 962 | + { 0x0b, "ILLEGAL_INSTR_PARAM" }, | |
| 963 | + { 0x0c, "INVALID_CONST_ADDR" }, | |
| 964 | + { 0x0d, "OOR_REG" }, | |
| 965 | + { 0x0e, "OOR_ADDR" }, | |
| 966 | + { 0x0f, "MISALIGNED_ADDR" }, | |
| 960 | 967 | { 0x10, "INVALID_ADDR_SPACE" }, |
| 961 | − { 0x11, "INVALID_PARAM" }, | |
| 968 | + { 0x11, "ILLEGAL_INSTR_PARAM2" }, | |
| 969 | + { 0x12, "INVALID_CONST_ADDR_LDC" }, | |
| 970 | + { 0x13, "GEOMETRY_SM_ERROR" }, | |
| 971 | + { 0x14, "DIVERGENT" }, | |
| 972 | + { 0x15, "WARP_EXIT" }, | |
| 962 | 973 | {} |
| 963 | 974 | }; |
| 964 | 975 | |
| 965 | 976 | static const struct nvkm_bitfield gf100_mp_global_error[] = { |
| 977 | + { 0x00000001, "SM_TO_SM_FAULT" }, | |
| 978 | + { 0x00000002, "L1_ERROR" }, | |
| 966 | 979 | { 0x00000004, "MULTIPLE_WARP_ERRORS" }, |
| 967 | − { 0x00000008, "OUT_OF_STACK_SPACE" }, | |
| 980 | + { 0x00000008, "PHYSICAL_STACK_OVERFLOW" }, | |
| 981 | + { 0x00000010, "BPT_INT" }, | |
| 982 | + { 0x00000020, "BPT_PAUSE" }, | |
| 983 | + { 0x00000040, "SINGLE_STEP_COMPLETE" }, | |
| 984 | + { 0x20000000, "ECC_SEC_ERROR" }, | |
| 985 | + { 0x40000000, "ECC_DED_ERROR" }, | |
| 986 | + { 0x80000000, "TIMEOUT" }, | |
| 968 | 987 | {} |
| 969 | 988 | }; |
| 970 | 989 | |
| @@ -141,7 +141,8 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, · 140 unmodified lines | ||
| 141 | 141 | { |
| 142 | 142 | u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len); |
| 143 | 143 | if (data) { |
| 144 | − info->match = nvbios_rd16(bios, data + 0x00); | |
| 144 | + info->proto = nvbios_rd08(bios, data + 0x00); | |
| 145 | + info->flags = nvbios_rd16(bios, data + 0x01); | |
| 145 | 146 | info->clkcmp[0] = nvbios_rd16(bios, data + 0x02); |
| 146 | 147 | info->clkcmp[1] = nvbios_rd16(bios, data + 0x04); |
| 147 | 148 | } |
| @@ -149,12 +150,13 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, · 1 unmodified line | ||
| 149 | 150 | } |
| 150 | 151 | |
| 151 | 152 | u16 |
| 152 | −nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u16 type, | |
| 153 | +nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u8 proto, u8 flags, | |
| 153 | 154 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info) |
| 154 | 155 | { |
| 155 | 156 | u16 data, idx = 0; |
| 156 | 157 | while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) { |
| 157 | − if (info->match == type) | |
| 158 | + if ((info->proto == proto || info->proto == 0xff) && | |
| 159 | + (info->flags == flags)) | |
| 158 | 160 | break; |
| 159 | 161 | } |
| 160 | 162 | return data; |
| @@ -69,11 +69,11 @@ gm107_ltc_zbc_clear_depth(struct nvkm_ltc *ltc, int i, const u32 depth) · 68 unmodified lines | ||
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | static void |
| 72 | −gm107_ltc_lts_isr(struct nvkm_ltc *ltc, int c, int s) | |
| 72 | +gm107_ltc_intr_lts(struct nvkm_ltc *ltc, int c, int s) | |
| 73 | 73 | { |
| 74 | 74 | struct nvkm_subdev *subdev = <c->subdev; |
| 75 | 75 | struct nvkm_device *device = subdev->device; |
| 76 | − u32 base = 0x140000 + (c * 0x2000) + (s * 0x200); | |
| 76 | + u32 base = 0x140400 + (c * 0x2000) + (s * 0x200); | |
| 77 | 77 | u32 stat = nvkm_rd32(device, base + 0x00c); |
| 78 | 78 | |
| 79 | 79 | if (stat) { |
| @@ -92,7 +92,7 @@ gm107_ltc_intr(struct nvkm_ltc *ltc) · 12 unmodified lines | ||
| 92 | 92 | while (mask) { |
| 93 | 93 | u32 s, c = __ffs(mask); |
| 94 | 94 | for (s = 0; s < ltc->lts_nr; s++) |
| 95 | − gm107_ltc_lts_isr(ltc, c, s); | |
| 95 | + gm107_ltc_intr_lts(ltc, c, s); | |
| 96 | 96 | mask &= ~(1 << c); |
| 97 | 97 | } |
| 98 | 98 | } |
| @@ -46,7 +46,7 @@ static const struct nvkm_ltc_func · 45 unmodified lines | ||
| 46 | 46 | gm200_ltc = { |
| 47 | 47 | .oneinit = gm200_ltc_oneinit, |
| 48 | 48 | .init = gm200_ltc_init, |
| 49 | − .intr = gm107_ltc_intr, /*XXX: not validated */ | |
| 49 | + .intr = gm107_ltc_intr, | |
| 50 | 50 | .cbc_clear = gm107_ltc_cbc_clear, |
| 51 | 51 | .cbc_wait = gm107_ltc_cbc_wait, |
| 52 | 52 | .zbc = 16, |
| @@ -1167,7 +1167,6 @@ static int dsi_regulator_init(struct platform_device *dsidev) · 1166 unmodified lines | ||
| 1167 | 1167 | { |
| 1168 | 1168 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 1169 | 1169 | struct regulator *vdds_dsi; |
| 1170 | − int r; | |
| 1171 | 1170 | |
| 1172 | 1171 | if (dsi->vdds_dsi_reg != NULL) |
| 1173 | 1172 | return 0; |
| @@ -120,7 +120,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | static int hdmi_init_regulator(void) |
| 122 | 122 | { |
| 123 | − int r; | |
| 124 | 123 | struct regulator *reg; |
| 125 | 124 | |
| 126 | 125 | if (hdmi.vdda_reg != NULL) |
| @@ -456,14 +456,6 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, · 455 unmodified lines | ||
| 456 | 456 | |
| 457 | 457 | WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); |
| 458 | 458 | |
| 459 | − HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | |
| 460 | − vc4_state->mm.start); | |
| 461 | − | |
| 462 | − if (debug_dump_regs) { | |
| 463 | − DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); | |
| 464 | − vc4_hvs_dump_state(dev); | |
| 465 | − } | |
| 466 | − | |
| 467 | 459 | if (crtc->state->event) { |
| 468 | 460 | unsigned long flags; |
| 469 | 461 | |
| @@ -473,8 +465,20 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, · 3 unmodified lines | ||
| 473 | 465 | |
| 474 | 466 | spin_lock_irqsave(&dev->event_lock, flags); |
| 475 | 467 | vc4_crtc->event = crtc->state->event; |
| 476 | − spin_unlock_irqrestore(&dev->event_lock, flags); | |
| 477 | 468 | crtc->state->event = NULL; |
| 469 | + | |
| 470 | + HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | |
| 471 | + vc4_state->mm.start); | |
| 472 | + | |
| 473 | + spin_unlock_irqrestore(&dev->event_lock, flags); | |
| 474 | + } else { | |
| 475 | + HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | |
| 476 | + vc4_state->mm.start); | |
| 477 | + } | |
| 478 | + | |
| 479 | + if (debug_dump_regs) { | |
| 480 | + DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); | |
| 481 | + vc4_hvs_dump_state(dev); | |
| 478 | 482 | } |
| 479 | 483 | } |
| 480 | 484 | |
| @@ -500,12 +504,17 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) · 19 unmodified lines | ||
| 500 | 504 | { |
| 501 | 505 | struct drm_crtc *crtc = &vc4_crtc->base; |
| 502 | 506 | struct drm_device *dev = crtc->dev; |
| 507 | + struct vc4_dev *vc4 = to_vc4_dev(dev); | |
| 508 | + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); | |
| 509 | + u32 chan = vc4_crtc->channel; | |
| 503 | 510 | unsigned long flags; |
| 504 | 511 | |
| 505 | 512 | spin_lock_irqsave(&dev->event_lock, flags); |
| 506 | − if (vc4_crtc->event) { | |
| 513 | + if (vc4_crtc->event && | |
| 514 | + (vc4_state->mm.start == HVS_READ(SCALER_DISPLACTX(chan)))) { | |
| 507 | 515 | drm_crtc_send_vblank_event(crtc, vc4_crtc->event); |
| 508 | 516 | vc4_crtc->event = NULL; |
| 517 | + drm_crtc_vblank_put(crtc); | |
| 509 | 518 | } |
| 510 | 519 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 511 | 520 | } |
| @@ -556,6 +565,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) · 44 unmodified lines | ||
| 556 | 565 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 557 | 566 | } |
| 558 | 567 | |
| 568 | + drm_crtc_vblank_put(crtc); | |
| 559 | 569 | drm_framebuffer_unreference(flip_state->fb); |
| 560 | 570 | kfree(flip_state); |
| 561 | 571 | |
| @@ -598,6 +608,8 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, · 36 unmodified lines | ||
| 598 | 608 | return ret; |
| 599 | 609 | } |
| 600 | 610 | |
| 611 | + WARN_ON(drm_crtc_vblank_get(crtc) != 0); | |
| 612 | + | |
| 601 | 613 | /* Immediately update the plane's legacy fb pointer, so that later |
| 602 | 614 | * modeset prep sees the state that will be present when the semaphore |
| 603 | 615 | * is released. |
| @@ -66,12 +66,12 @@ static const struct file_operations vc4_drm_fops = { · 65 unmodified lines | ||
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | 68 | static const struct drm_ioctl_desc vc4_drm_ioctls[] = { |
| 69 | − DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0), | |
| 70 | − DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0), | |
| 71 | − DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0), | |
| 72 | − DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), | |
| 73 | − DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), | |
| 74 | − DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), | |
| 69 | + DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, DRM_RENDER_ALLOW), | |
| 70 | + DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, DRM_RENDER_ALLOW), | |
| 71 | + DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, DRM_RENDER_ALLOW), | |
| 72 | + DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, DRM_RENDER_ALLOW), | |
| 73 | + DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, DRM_RENDER_ALLOW), | |
| 74 | + DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, DRM_RENDER_ALLOW), | |
| 75 | 75 | DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, |
| 76 | 76 | DRM_ROOT_ONLY), |
| 77 | 77 | }; |
| @@ -91,7 +91,7 @@ static struct drm_driver vc4_drm_driver = { · 13 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | .enable_vblank = vc4_enable_vblank, |
| 93 | 93 | .disable_vblank = vc4_disable_vblank, |
| 94 | − .get_vblank_counter = drm_vblank_count, | |
| 94 | + .get_vblank_counter = drm_vblank_no_hw_counter, | |
| 95 | 95 | |
| 96 | 96 | #if defined(CONFIG_DEBUG_FS) |
| 97 | 97 | .debugfs_init = vc4_debugfs_init, |
| @@ -117,10 +117,18 @@ static int vc4_atomic_commit(struct drm_device *dev, · 116 unmodified lines | ||
| 117 | 117 | return -ENOMEM; |
| 118 | 118 | |
| 119 | 119 | /* Make sure that any outstanding modesets have finished. */ |
| 120 | − ret = down_interruptible(&vc4->async_modeset); | |
| 121 | − if (ret) { | |
| 122 | − kfree(c); | |
| 123 | − return ret; | |
| 120 | + if (nonblock) { | |
| 121 | + ret = down_trylock(&vc4->async_modeset); | |
| 122 | + if (ret) { | |
| 123 | + kfree(c); | |
| 124 | + return -EBUSY; | |
| 125 | + } | |
| 126 | + } else { | |
| 127 | + ret = down_interruptible(&vc4->async_modeset); | |
| 128 | + if (ret) { | |
| 129 | + kfree(c); | |
| 130 | + return ret; | |
| 131 | + } | |
| 124 | 132 | } |
| 125 | 133 | |
| 126 | 134 | ret = drm_atomic_helper_prepare_planes(dev, state); |
| @@ -341,6 +341,10 @@ · 340 unmodified lines | ||
| 341 | 341 | #define SCALER_DISPLACT0 0x00000030 |
| 342 | 342 | #define SCALER_DISPLACT1 0x00000034 |
| 343 | 343 | #define SCALER_DISPLACT2 0x00000038 |
| 344 | +#define SCALER_DISPLACTX(x) (SCALER_DISPLACT0 + \ | |
| 345 | + (x) * (SCALER_DISPLACT1 - \ | |
| 346 | + SCALER_DISPLACT0)) | |
| 347 | + | |
| 344 | 348 | #define SCALER_DISPCTRL0 0x00000040 |
| 345 | 349 | # define SCALER_DISPCTRLX_ENABLE BIT(31) |
| 346 | 350 | # define SCALER_DISPCTRLX_RESET BIT(30) |