Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-next-2021-02-26' of git://anongit.freedesktop.org/drm/drm

Pull more drm updates from Dave Airlie:
"This is mostly fixes but I missed msm-next pull last week. It's been
in drm-next.

Otherwise it's a selection of i915, amdgpu and misc fixes, one TTM
memory leak, nothing really major stands out otherwise.

core:
- vblank fence timing improvements

dma-buf:
- improve error handling

ttm:
- memory leak fix

msm:
- a6xx speedbin support
- a508, a509, a512 support
- various a5xx fixes
- various dpu fixes
- qseed3lite support for sm8250
- dsi fix for msm8994
- mdp5 fix for framerate bug with cmd mode panels
- a6xx GMU OOB race fixes that were showing up in CI
- various addition and removal of semicolons
- gem submit fix for legacy userspace relocs path

amdgpu:
- clang warning fix
- S0ix platform shutdown/poweroff fix
- misc display fixes

i915:
- color format fix
- -Wuninitialised reenabled
- GVT ww locking, cmd parser fixes

atyfb:
- fix build

rockchip:
- AFBC modifier fix"

* tag 'drm-next-2021-02-26' of git://anongit.freedesktop.org/drm/drm: (60 commits)
drm/panel: kd35t133: allow using non-continuous dsi clock
drm/rockchip: Require the YTR modifier for AFBC
drm/ttm: Fix a memory leak
drm/drm_vblank: set the dma-fence timestamp during send_vblank_event
dma-fence: allow signaling drivers to set fence timestamp
dma-buf: heaps: Rework heap allocation hooks to return struct dma_buf instead of fd
dma-buf: system_heap: Make sure to return an error if we abort
drm/amd/display: Fix system hang after multiple hotplugs (v3)
drm/amdgpu: fix shutdown and poweroff process failed with s0ix
drm/i915: Nuke INTEL_OUTPUT_FORMAT_INVALID
drm/i915: Enable -Wuninitialized
drm/amd/display: Remove Assert from dcn10_get_dig_frontend
drm/amd/display: Add vupdate_no_lock interrupts for DCN2.1
Revert "drm/amd/display: reuse current context instead of recreating one"
drm/amd/pm/swsmu: Avoid using structure_size uninitialized in smu_cmn_init_soft_gpu_metrics
fbdev: atyfb: add stubs for aty_{ld,st}_lcd()
drm/i915/gvt: Introduce per object locking in GVT scheduler.
drm/i915/gvt: Purge dev_priv->gt
drm/i915/gvt: Parse default state to update reg whitelist
dt-bindings: dp-connector: Drop maxItems from -supply
...

+1253 -453
-1
Documentation/devicetree/bindings/display/connector/dp-connector.yaml
··· 26 26 27 27 dp-pwr-supply: 28 28 description: Power supply for the DP_PWR pin 29 - maxItems: 1 30 29 31 30 port: 32 31 $ref: /schemas/graph.yaml#/properties/port
+79 -23
drivers/dma-buf/dma-fence.c
··· 312 312 313 313 314 314 /** 315 + * dma_fence_signal_timestamp_locked - signal completion of a fence 316 + * @fence: the fence to signal 317 + * @timestamp: fence signal timestamp in kernel's CLOCK_MONOTONIC time domain 318 + * 319 + * Signal completion for software callbacks on a fence, this will unblock 320 + * dma_fence_wait() calls and run all the callbacks added with 321 + * dma_fence_add_callback(). Can be called multiple times, but since a fence 322 + * can only go from the unsignaled to the signaled state and not back, it will 323 + * only be effective the first time. Set the timestamp provided as the fence 324 + * signal timestamp. 325 + * 326 + * Unlike dma_fence_signal_timestamp(), this function must be called with 327 + * &dma_fence.lock held. 328 + * 329 + * Returns 0 on success and a negative error value when @fence has been 330 + * signalled already. 331 + */ 332 + int dma_fence_signal_timestamp_locked(struct dma_fence *fence, 333 + ktime_t timestamp) 334 + { 335 + struct dma_fence_cb *cur, *tmp; 336 + struct list_head cb_list; 337 + 338 + lockdep_assert_held(fence->lock); 339 + 340 + if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, 341 + &fence->flags))) 342 + return -EINVAL; 343 + 344 + /* Stash the cb_list before replacing it with the timestamp */ 345 + list_replace(&fence->cb_list, &cb_list); 346 + 347 + fence->timestamp = timestamp; 348 + set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags); 349 + trace_dma_fence_signaled(fence); 350 + 351 + list_for_each_entry_safe(cur, tmp, &cb_list, node) { 352 + INIT_LIST_HEAD(&cur->node); 353 + cur->func(fence, cur); 354 + } 355 + 356 + return 0; 357 + } 358 + EXPORT_SYMBOL(dma_fence_signal_timestamp_locked); 359 + 360 + /** 361 + * dma_fence_signal_timestamp - signal completion of a fence 362 + * @fence: the fence to signal 363 + * @timestamp: fence signal timestamp in kernel's CLOCK_MONOTONIC time domain 364 + * 365 + * Signal completion for software callbacks on a fence, this will unblock 366 + * dma_fence_wait() calls and run all the callbacks added with 367 + * dma_fence_add_callback(). Can be called multiple times, but since a fence 368 + * can only go from the unsignaled to the signaled state and not back, it will 369 + * only be effective the first time. Set the timestamp provided as the fence 370 + * signal timestamp. 371 + * 372 + * Returns 0 on success and a negative error value when @fence has been 373 + * signalled already. 374 + */ 375 + int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp) 376 + { 377 + unsigned long flags; 378 + int ret; 379 + 380 + if (!fence) 381 + return -EINVAL; 382 + 383 + spin_lock_irqsave(fence->lock, flags); 384 + ret = dma_fence_signal_timestamp_locked(fence, timestamp); 385 + spin_unlock_irqrestore(fence->lock, flags); 386 + 387 + return ret; 388 + } 389 + EXPORT_SYMBOL(dma_fence_signal_timestamp); 390 + 391 + /** 315 392 * dma_fence_signal_locked - signal completion of a fence 316 393 * @fence: the fence to signal 317 394 * ··· 406 329 */ 407 330 int dma_fence_signal_locked(struct dma_fence *fence) 408 331 { 409 - struct dma_fence_cb *cur, *tmp; 410 - struct list_head cb_list; 411 - 412 - lockdep_assert_held(fence->lock); 413 - 414 - if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, 415 - &fence->flags))) 416 - return -EINVAL; 417 - 418 - /* Stash the cb_list before replacing it with the timestamp */ 419 - list_replace(&fence->cb_list, &cb_list); 420 - 421 - fence->timestamp = ktime_get(); 422 - set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags); 423 - trace_dma_fence_signaled(fence); 424 - 425 - list_for_each_entry_safe(cur, tmp, &cb_list, node) { 426 - INIT_LIST_HEAD(&cur->node); 427 - cur->func(fence, cur); 428 - } 429 - 430 - return 0; 332 + return dma_fence_signal_timestamp_locked(fence, ktime_get()); 431 333 } 432 334 EXPORT_SYMBOL(dma_fence_signal_locked); 433 335 ··· 435 379 tmp = dma_fence_begin_signalling(); 436 380 437 381 spin_lock_irqsave(fence->lock, flags); 438 - ret = dma_fence_signal_locked(fence); 382 + ret = dma_fence_signal_timestamp_locked(fence, ktime_get()); 439 383 spin_unlock_irqrestore(fence->lock, flags); 440 384 441 385 dma_fence_end_signalling(tmp);
+13 -1
drivers/dma-buf/dma-heap.c
··· 52 52 unsigned int fd_flags, 53 53 unsigned int heap_flags) 54 54 { 55 + struct dma_buf *dmabuf; 56 + int fd; 57 + 55 58 /* 56 59 * Allocations from all heaps have to begin 57 60 * and end on page boundaries. ··· 63 60 if (!len) 64 61 return -EINVAL; 65 62 66 - return heap->ops->allocate(heap, len, fd_flags, heap_flags); 63 + dmabuf = heap->ops->allocate(heap, len, fd_flags, heap_flags); 64 + if (IS_ERR(dmabuf)) 65 + return PTR_ERR(dmabuf); 66 + 67 + fd = dma_buf_fd(dmabuf, fd_flags); 68 + if (fd < 0) { 69 + dma_buf_put(dmabuf); 70 + /* just return, as put will call release and that will free */ 71 + } 72 + return fd; 67 73 } 68 74 69 75 static int dma_heap_open(struct inode *inode, struct file *file)
+7 -15
drivers/dma-buf/heaps/cma_heap.c
··· 271 271 .release = cma_heap_dma_buf_release, 272 272 }; 273 273 274 - static int cma_heap_allocate(struct dma_heap *heap, 275 - unsigned long len, 276 - unsigned long fd_flags, 277 - unsigned long heap_flags) 274 + static struct dma_buf *cma_heap_allocate(struct dma_heap *heap, 275 + unsigned long len, 276 + unsigned long fd_flags, 277 + unsigned long heap_flags) 278 278 { 279 279 struct cma_heap *cma_heap = dma_heap_get_drvdata(heap); 280 280 struct cma_heap_buffer *buffer; ··· 289 289 290 290 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 291 291 if (!buffer) 292 - return -ENOMEM; 292 + return ERR_PTR(-ENOMEM); 293 293 294 294 INIT_LIST_HEAD(&buffer->attachments); 295 295 mutex_init(&buffer->lock); ··· 348 348 ret = PTR_ERR(dmabuf); 349 349 goto free_pages; 350 350 } 351 - 352 - ret = dma_buf_fd(dmabuf, fd_flags); 353 - if (ret < 0) { 354 - dma_buf_put(dmabuf); 355 - /* just return, as put will call release and that will free */ 356 - return ret; 357 - } 358 - 359 - return ret; 351 + return dmabuf; 360 352 361 353 free_pages: 362 354 kfree(buffer->pages); ··· 357 365 free_buffer: 358 366 kfree(buffer); 359 367 360 - return ret; 368 + return ERR_PTR(ret); 361 369 } 362 370 363 371 static const struct dma_heap_ops cma_heap_ops = {
+10 -15
drivers/dma-buf/heaps/system_heap.c
··· 331 331 return NULL; 332 332 } 333 333 334 - static int system_heap_allocate(struct dma_heap *heap, 335 - unsigned long len, 336 - unsigned long fd_flags, 337 - unsigned long heap_flags) 334 + static struct dma_buf *system_heap_allocate(struct dma_heap *heap, 335 + unsigned long len, 336 + unsigned long fd_flags, 337 + unsigned long heap_flags) 338 338 { 339 339 struct system_heap_buffer *buffer; 340 340 DEFINE_DMA_BUF_EXPORT_INFO(exp_info); ··· 349 349 350 350 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 351 351 if (!buffer) 352 - return -ENOMEM; 352 + return ERR_PTR(-ENOMEM); 353 353 354 354 INIT_LIST_HEAD(&buffer->attachments); 355 355 mutex_init(&buffer->lock); ··· 363 363 * Avoid trying to allocate memory if the process 364 364 * has been killed by SIGKILL 365 365 */ 366 - if (fatal_signal_pending(current)) 366 + if (fatal_signal_pending(current)) { 367 + ret = -EINTR; 367 368 goto free_buffer; 369 + } 368 370 369 371 page = alloc_largest_available(size_remaining, max_order); 370 372 if (!page) ··· 399 397 ret = PTR_ERR(dmabuf); 400 398 goto free_pages; 401 399 } 402 - 403 - ret = dma_buf_fd(dmabuf, fd_flags); 404 - if (ret < 0) { 405 - dma_buf_put(dmabuf); 406 - /* just return, as put will call release and that will free */ 407 - return ret; 408 - } 409 - return ret; 400 + return dmabuf; 410 401 411 402 free_pages: 412 403 for_each_sgtable_sg(table, sg, i) { ··· 413 418 __free_pages(page, compound_order(page)); 414 419 kfree(buffer); 415 420 416 - return ret; 421 + return ERR_PTR(ret); 417 422 } 418 423 419 424 static const struct dma_heap_ops system_heap_ops = {
+6
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 1008 1008 bool in_suspend; 1009 1009 bool in_hibernate; 1010 1010 1011 + /* 1012 + * The combination flag in_poweroff_reboot_com used to identify the poweroff 1013 + * and reboot opt in the s0i3 system-wide suspend. 1014 + */ 1015 + bool in_poweroff_reboot_com; 1016 + 1011 1017 atomic_t in_gpu_reset; 1012 1018 enum pp_mp1_state mp1_state; 1013 1019 struct rw_semaphore reset_sem;
+4 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 2678 2678 { 2679 2679 int i, r; 2680 2680 2681 - if (!amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) { 2681 + if (adev->in_poweroff_reboot_com || 2682 + !amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) { 2682 2683 amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); 2683 2684 amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); 2684 2685 } ··· 3742 3741 3743 3742 amdgpu_fence_driver_suspend(adev); 3744 3743 3745 - if (!amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) 3744 + if (adev->in_poweroff_reboot_com || 3745 + !amdgpu_acpi_is_s0ix_supported(adev) || amdgpu_in_reset(adev)) 3746 3746 r = amdgpu_device_ip_suspend_phase2(adev); 3747 3747 else 3748 3748 amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry);
+8 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 1270 1270 */ 1271 1271 if (!amdgpu_passthrough(adev)) 1272 1272 adev->mp1_state = PP_MP1_STATE_UNLOAD; 1273 + adev->in_poweroff_reboot_com = true; 1273 1274 amdgpu_device_ip_suspend(adev); 1275 + adev->in_poweroff_reboot_com = false; 1274 1276 adev->mp1_state = PP_MP1_STATE_NONE; 1275 1277 } 1276 1278 ··· 1314 1312 static int amdgpu_pmops_poweroff(struct device *dev) 1315 1313 { 1316 1314 struct drm_device *drm_dev = dev_get_drvdata(dev); 1315 + struct amdgpu_device *adev = drm_to_adev(drm_dev); 1316 + int r; 1317 1317 1318 - return amdgpu_device_suspend(drm_dev, true); 1318 + adev->in_poweroff_reboot_com = true; 1319 + r = amdgpu_device_suspend(drm_dev, true); 1320 + adev->in_poweroff_reboot_com = false; 1321 + return r; 1319 1322 } 1320 1323 1321 1324 static int amdgpu_pmops_restore(struct device *dev)
+78 -23
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 937 937 938 938 } 939 939 #endif 940 + #if defined(CONFIG_DRM_AMD_DC_DCN) 941 + static void event_mall_stutter(struct work_struct *work) 942 + { 940 943 944 + struct vblank_workqueue *vblank_work = container_of(work, struct vblank_workqueue, mall_work); 945 + struct amdgpu_display_manager *dm = vblank_work->dm; 946 + 947 + mutex_lock(&dm->dc_lock); 948 + 949 + if (vblank_work->enable) 950 + dm->active_vblank_irq_count++; 951 + else 952 + dm->active_vblank_irq_count--; 953 + 954 + 955 + dc_allow_idle_optimizations( 956 + dm->dc, dm->active_vblank_irq_count == 0 ? true : false); 957 + 958 + DRM_DEBUG_DRIVER("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0); 959 + 960 + 961 + mutex_unlock(&dm->dc_lock); 962 + } 963 + 964 + static struct vblank_workqueue *vblank_create_workqueue(struct amdgpu_device *adev, struct dc *dc) 965 + { 966 + 967 + int max_caps = dc->caps.max_links; 968 + struct vblank_workqueue *vblank_work; 969 + int i = 0; 970 + 971 + vblank_work = kcalloc(max_caps, sizeof(*vblank_work), GFP_KERNEL); 972 + if (ZERO_OR_NULL_PTR(vblank_work)) { 973 + kfree(vblank_work); 974 + return NULL; 975 + } 976 + 977 + for (i = 0; i < max_caps; i++) 978 + INIT_WORK(&vblank_work[i].mall_work, event_mall_stutter); 979 + 980 + return vblank_work; 981 + } 982 + #endif 941 983 static int amdgpu_dm_init(struct amdgpu_device *adev) 942 984 { 943 985 struct dc_init_data init_data; ··· 999 957 1000 958 mutex_init(&adev->dm.dc_lock); 1001 959 mutex_init(&adev->dm.audio_lock); 960 + #if defined(CONFIG_DRM_AMD_DC_DCN) 961 + spin_lock_init(&adev->dm.vblank_lock); 962 + #endif 1002 963 1003 964 if(amdgpu_dm_irq_init(adev)) { 1004 965 DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n"); ··· 1115 1070 adev->dm.freesync_module); 1116 1071 1117 1072 amdgpu_dm_init_color_mod(); 1073 + 1074 + #if defined(CONFIG_DRM_AMD_DC_DCN) 1075 + if (adev->dm.dc->caps.max_links > 0) { 1076 + adev->dm.vblank_workqueue = vblank_create_workqueue(adev, adev->dm.dc); 1077 + 1078 + if (!adev->dm.vblank_workqueue) 1079 + DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n"); 1080 + else 1081 + DRM_DEBUG_DRIVER("amdgpu: vblank_workqueue init done %p.\n", adev->dm.vblank_workqueue); 1082 + } 1083 + #endif 1118 1084 1119 1085 #ifdef CONFIG_DRM_AMD_DC_HDCP 1120 1086 if (adev->dm.dc->caps.max_links > 0 && adev->asic_type >= CHIP_RAVEN) { ··· 1992 1936 dc_commit_updates_for_stream( 1993 1937 dm->dc, bundle->surface_updates, 1994 1938 dc_state->stream_status->plane_count, 1995 - dc_state->streams[k], &bundle->stream_update); 1939 + dc_state->streams[k], &bundle->stream_update, dc_state); 1996 1940 } 1997 1941 1998 1942 cleanup: ··· 2023 1967 2024 1968 stream_update.stream = stream_state; 2025 1969 dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0, 2026 - stream_state, &stream_update); 1970 + stream_state, &stream_update, 1971 + stream_state->ctx->dc->current_state); 2027 1972 mutex_unlock(&adev->dm.dc_lock); 2028 1973 } 2029 1974 ··· 5431 5374 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); 5432 5375 struct amdgpu_device *adev = drm_to_adev(crtc->dev); 5433 5376 struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); 5377 + #if defined(CONFIG_DRM_AMD_DC_DCN) 5434 5378 struct amdgpu_display_manager *dm = &adev->dm; 5379 + unsigned long flags; 5380 + #endif 5435 5381 int rc = 0; 5436 5382 5437 5383 if (enable) { ··· 5457 5397 if (amdgpu_in_reset(adev)) 5458 5398 return 0; 5459 5399 5460 - mutex_lock(&dm->dc_lock); 5461 - 5462 - if (enable) 5463 - dm->active_vblank_irq_count++; 5464 - else 5465 - dm->active_vblank_irq_count--; 5466 - 5467 5400 #if defined(CONFIG_DRM_AMD_DC_DCN) 5468 - dc_allow_idle_optimizations( 5469 - adev->dm.dc, dm->active_vblank_irq_count == 0 ? true : false); 5470 - 5471 - DRM_DEBUG_DRIVER("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0); 5401 + spin_lock_irqsave(&dm->vblank_lock, flags); 5402 + dm->vblank_workqueue->dm = dm; 5403 + dm->vblank_workqueue->otg_inst = acrtc->otg_inst; 5404 + dm->vblank_workqueue->enable = enable; 5405 + spin_unlock_irqrestore(&dm->vblank_lock, flags); 5406 + schedule_work(&dm->vblank_workqueue->mall_work); 5472 5407 #endif 5473 - 5474 - mutex_unlock(&dm->dc_lock); 5475 5408 5476 5409 return 0; 5477 5410 } ··· 7716 7663 struct drm_crtc *pcrtc, 7717 7664 bool wait_for_vblank) 7718 7665 { 7719 - int i; 7666 + uint32_t i; 7720 7667 uint64_t timestamp_ns; 7721 7668 struct drm_plane *plane; 7722 7669 struct drm_plane_state *old_plane_state, *new_plane_state; ··· 7757 7704 amdgpu_dm_commit_cursors(state); 7758 7705 7759 7706 /* update planes when needed */ 7760 - for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { 7707 + for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { 7761 7708 struct drm_crtc *crtc = new_plane_state->crtc; 7762 7709 struct drm_crtc_state *new_crtc_state; 7763 7710 struct drm_framebuffer *fb = new_plane_state->fb; ··· 7980 7927 bundle->surface_updates, 7981 7928 planes_count, 7982 7929 acrtc_state->stream, 7983 - &bundle->stream_update); 7930 + &bundle->stream_update, 7931 + dc_state); 7984 7932 7985 7933 /** 7986 7934 * Enable or disable the interrupts on the backend. ··· 8317 8263 struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); 8318 8264 struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state); 8319 8265 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); 8320 - struct dc_surface_update surface_updates[MAX_SURFACES]; 8266 + struct dc_surface_update dummy_updates[MAX_SURFACES]; 8321 8267 struct dc_stream_update stream_update; 8322 8268 struct dc_info_packet hdr_packet; 8323 8269 struct dc_stream_status *status = NULL; 8324 8270 bool abm_changed, hdr_changed, scaling_changed; 8325 8271 8326 - memset(&surface_updates, 0, sizeof(surface_updates)); 8272 + memset(&dummy_updates, 0, sizeof(dummy_updates)); 8327 8273 memset(&stream_update, 0, sizeof(stream_update)); 8328 8274 8329 8275 if (acrtc) { ··· 8380 8326 * To fix this, DC should permit updating only stream properties. 8381 8327 */ 8382 8328 for (j = 0; j < status->plane_count; j++) 8383 - surface_updates[j].surface = status->plane_states[j]; 8329 + dummy_updates[j].surface = status->plane_states[0]; 8384 8330 8385 8331 8386 8332 mutex_lock(&dm->dc_lock); 8387 8333 dc_commit_updates_for_stream(dm->dc, 8388 - surface_updates, 8334 + dummy_updates, 8389 8335 status->plane_count, 8390 8336 dm_new_crtc_state->stream, 8391 - &stream_update); 8337 + &stream_update, 8338 + dc_state); 8392 8339 mutex_unlock(&dm->dc_lock); 8393 8340 } 8394 8341
+27
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
··· 93 93 }; 94 94 95 95 /** 96 + * struct vblank_workqueue - Works to be executed in a separate thread during vblank 97 + * @mall_work: work for mall stutter 98 + * @dm: amdgpu display manager device 99 + * @otg_inst: otg instance of which vblank is being set 100 + * @enable: true if enable vblank 101 + */ 102 + struct vblank_workqueue { 103 + struct work_struct mall_work; 104 + struct amdgpu_display_manager *dm; 105 + int otg_inst; 106 + bool enable; 107 + }; 108 + 109 + /** 96 110 * struct amdgpu_dm_backlight_caps - Information about backlight 97 111 * 98 112 * Describe the backlight support for ACPI or eDP AUX. ··· 258 244 struct mutex audio_lock; 259 245 260 246 /** 247 + * @vblank_work_lock: 248 + * 249 + * Guards access to deferred vblank work state. 250 + */ 251 + #if defined(CONFIG_DRM_AMD_DC_DCN) 252 + spinlock_t vblank_lock; 253 + #endif 254 + 255 + /** 261 256 * @audio_component: 262 257 * 263 258 * Used to notify ELD changes to sound driver. ··· 342 319 struct mod_freesync *freesync_module; 343 320 #ifdef CONFIG_DRM_AMD_DC_HDCP 344 321 struct hdcp_workqueue *hdcp_workqueue; 322 + #endif 323 + 324 + #if defined(CONFIG_DRM_AMD_DC_DCN) 325 + struct vblank_workqueue *vblank_workqueue; 345 326 #endif 346 327 347 328 struct drm_atomic_state *cached_state;
+9 -20
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 2697 2697 struct dc_surface_update *srf_updates, 2698 2698 int surface_count, 2699 2699 struct dc_stream_state *stream, 2700 - struct dc_stream_update *stream_update) 2700 + struct dc_stream_update *stream_update, 2701 + struct dc_state *state) 2701 2702 { 2702 2703 const struct dc_stream_status *stream_status; 2703 2704 enum surface_update_type update_type; ··· 2717 2716 2718 2717 2719 2718 if (update_type >= UPDATE_TYPE_FULL) { 2720 - struct dc_plane_state *new_planes[MAX_SURFACES]; 2721 - 2722 - memset(new_planes, 0, sizeof(new_planes)); 2723 - 2724 - for (i = 0; i < surface_count; i++) 2725 - new_planes[i] = srf_updates[i].surface; 2726 2719 2727 2720 /* initialize scratch memory for building context */ 2728 2721 context = dc_create_state(dc); ··· 2725 2730 return; 2726 2731 } 2727 2732 2728 - dc_resource_state_copy_construct( 2729 - dc->current_state, context); 2733 + dc_resource_state_copy_construct(state, context); 2730 2734 2731 - /*remove old surfaces from context */ 2732 - if (!dc_rem_all_planes_for_stream(dc, stream, context)) { 2733 - DC_ERROR("Failed to remove streams for new validate context!\n"); 2734 - return; 2735 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 2736 + struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; 2737 + struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 2738 + 2739 + if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) 2740 + new_pipe->plane_state->force_full_update = true; 2735 2741 } 2736 - 2737 - /* add surface to context */ 2738 - if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) { 2739 - DC_ERROR("Failed to add streams for new validate context!\n"); 2740 - return; 2741 - } 2742 - 2743 2742 } 2744 2743 2745 2744
+2 -1
drivers/gpu/drm/amd/display/dc/dc_stream.h
··· 294 294 struct dc_surface_update *srf_updates, 295 295 int surface_count, 296 296 struct dc_stream_state *stream, 297 - struct dc_stream_update *stream_update); 297 + struct dc_stream_update *stream_update, 298 + struct dc_state *state); 298 299 /* 299 300 * Log the current stream state. 300 301 */
+2
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
··· 539 539 540 540 fe = dc->links[i]->link_enc->funcs->get_dig_frontend( 541 541 dc->links[i]->link_enc); 542 + if (fe == ENGINE_ID_UNKNOWN) 543 + continue; 542 544 543 545 for (j = 0; j < dc->res_pool->stream_enc_count; j++) { 544 546 if (fe == dc->res_pool->stream_enc[j]->id) {
+22
drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
··· 168 168 .ack = NULL 169 169 }; 170 170 171 + static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { 172 + .set = NULL, 173 + .ack = NULL 174 + }; 175 + 171 176 #undef BASE_INNER 172 177 #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg 173 178 ··· 233 228 OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\ 234 229 OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\ 235 230 .funcs = &vblank_irq_info_funcs\ 231 + } 232 + 233 + /* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic 234 + * of DCE's DC_IRQ_SOURCE_VUPDATEx. 235 + */ 236 + #define vupdate_no_lock_int_entry(reg_num)\ 237 + [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ 238 + IRQ_REG_ENTRY(OTG, reg_num,\ 239 + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ 240 + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ 241 + .funcs = &vupdate_no_lock_irq_info_funcs\ 236 242 } 237 243 238 244 #define vblank_int_entry(reg_num)\ ··· 354 338 vupdate_int_entry(3), 355 339 vupdate_int_entry(4), 356 340 vupdate_int_entry(5), 341 + vupdate_no_lock_int_entry(0), 342 + vupdate_no_lock_int_entry(1), 343 + vupdate_no_lock_int_entry(2), 344 + vupdate_no_lock_int_entry(3), 345 + vupdate_no_lock_int_entry(4), 346 + vupdate_no_lock_int_entry(5), 357 347 vblank_int_entry(0), 358 348 vblank_int_entry(1), 359 349 vblank_int_entry(2),
+1 -1
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
··· 762 762 structure_size = sizeof(struct gpu_metrics_v2_0); 763 763 break; 764 764 default: 765 - break; 765 + return; 766 766 } 767 767 768 768 #undef METRICS_VERSION
+68 -24
drivers/gpu/drm/drm_file.c
··· 775 775 EXPORT_SYMBOL(drm_event_cancel_free); 776 776 777 777 /** 778 + * drm_send_event_helper - send DRM event to file descriptor 779 + * @dev: DRM device 780 + * @e: DRM event to deliver 781 + * @timestamp: timestamp to set for the fence event in kernel's CLOCK_MONOTONIC 782 + * time domain 783 + * 784 + * This helper function sends the event @e, initialized with 785 + * drm_event_reserve_init(), to its associated userspace DRM file. 786 + * The timestamp variant of dma_fence_signal is used when the caller 787 + * sends a valid timestamp. 788 + */ 789 + void drm_send_event_helper(struct drm_device *dev, 790 + struct drm_pending_event *e, ktime_t timestamp) 791 + { 792 + assert_spin_locked(&dev->event_lock); 793 + 794 + if (e->completion) { 795 + complete_all(e->completion); 796 + e->completion_release(e->completion); 797 + e->completion = NULL; 798 + } 799 + 800 + if (e->fence) { 801 + if (timestamp) 802 + dma_fence_signal_timestamp(e->fence, timestamp); 803 + else 804 + dma_fence_signal(e->fence); 805 + dma_fence_put(e->fence); 806 + } 807 + 808 + if (!e->file_priv) { 809 + kfree(e); 810 + return; 811 + } 812 + 813 + list_del(&e->pending_link); 814 + list_add_tail(&e->link, 815 + &e->file_priv->event_list); 816 + wake_up_interruptible_poll(&e->file_priv->event_wait, 817 + EPOLLIN | EPOLLRDNORM); 818 + } 819 + 820 + /** 821 + * drm_send_event_timestamp_locked - send DRM event to file descriptor 822 + * @dev: DRM device 823 + * @e: DRM event to deliver 824 + * @timestamp: timestamp to set for the fence event in kernel's CLOCK_MONOTONIC 825 + * time domain 826 + * 827 + * This function sends the event @e, initialized with drm_event_reserve_init(), 828 + * to its associated userspace DRM file. Callers must already hold 829 + * &drm_device.event_lock. 830 + * 831 + * Note that the core will take care of unlinking and disarming events when the 832 + * corresponding DRM file is closed. Drivers need not worry about whether the 833 + * DRM file for this event still exists and can call this function upon 834 + * completion of the asynchronous work unconditionally. 835 + */ 836 + void drm_send_event_timestamp_locked(struct drm_device *dev, 837 + struct drm_pending_event *e, ktime_t timestamp) 838 + { 839 + drm_send_event_helper(dev, e, timestamp); 840 + } 841 + EXPORT_SYMBOL(drm_send_event_timestamp_locked); 842 + 843 + /** 778 844 * drm_send_event_locked - send DRM event to file descriptor 779 845 * @dev: DRM device 780 846 * @e: DRM event to deliver ··· 856 790 */ 857 791 void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) 858 792 { 859 - assert_spin_locked(&dev->event_lock); 860 - 861 - if (e->completion) { 862 - complete_all(e->completion); 863 - e->completion_release(e->completion); 864 - e->completion = NULL; 865 - } 866 - 867 - if (e->fence) { 868 - dma_fence_signal(e->fence); 869 - dma_fence_put(e->fence); 870 - } 871 - 872 - if (!e->file_priv) { 873 - kfree(e); 874 - return; 875 - } 876 - 877 - list_del(&e->pending_link); 878 - list_add_tail(&e->link, 879 - &e->file_priv->event_list); 880 - wake_up_interruptible_poll(&e->file_priv->event_wait, 881 - EPOLLIN | EPOLLRDNORM); 793 + drm_send_event_helper(dev, e, 0); 882 794 } 883 795 EXPORT_SYMBOL(drm_send_event_locked); 884 796 ··· 880 836 unsigned long irqflags; 881 837 882 838 spin_lock_irqsave(&dev->event_lock, irqflags); 883 - drm_send_event_locked(dev, e); 839 + drm_send_event_helper(dev, e, 0); 884 840 spin_unlock_irqrestore(&dev->event_lock, irqflags); 885 841 } 886 842 EXPORT_SYMBOL(drm_send_event);
+8 -1
drivers/gpu/drm/drm_vblank.c
··· 1006 1006 break; 1007 1007 } 1008 1008 trace_drm_vblank_event_delivered(e->base.file_priv, e->pipe, seq); 1009 - drm_send_event_locked(dev, &e->base); 1009 + /* 1010 + * Use the same timestamp for any associated fence signal to avoid 1011 + * mismatch in timestamps for vsync & fence events triggered by the 1012 + * same HW event. Frameworks like SurfaceFlinger in Android expects the 1013 + * retire-fence timestamp to match exactly with HW vsync as it uses it 1014 + * for its software vsync modeling. 1015 + */ 1016 + drm_send_event_timestamp_locked(dev, &e->base, now); 1010 1017 } 1011 1018 1012 1019 /**
-1
drivers/gpu/drm/i915/Makefile
··· 21 21 subdir-ccflags-y += $(call cc-disable-warning, sign-compare) 22 22 subdir-ccflags-y += $(call cc-disable-warning, sometimes-uninitialized) 23 23 subdir-ccflags-y += $(call cc-disable-warning, initializer-overrides) 24 - subdir-ccflags-y += $(call cc-disable-warning, uninitialized) 25 24 subdir-ccflags-y += $(call cc-disable-warning, frame-address) 26 25 subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror 27 26
-1
drivers/gpu/drm/i915/display/intel_crtc.c
··· 109 109 crtc_state->cpu_transcoder = INVALID_TRANSCODER; 110 110 crtc_state->master_transcoder = INVALID_TRANSCODER; 111 111 crtc_state->hsw_workaround_pipe = INVALID_PIPE; 112 - crtc_state->output_format = INTEL_OUTPUT_FORMAT_INVALID; 113 112 crtc_state->scaler_state.scaler_id = -1; 114 113 crtc_state->mst_master_transcoder = INVALID_TRANSCODER; 115 114 }
+1 -2
drivers/gpu/drm/i915/display/intel_display.c
··· 10211 10211 } 10212 10212 10213 10213 static const char * const output_format_str[] = { 10214 - [INTEL_OUTPUT_FORMAT_INVALID] = "Invalid", 10215 10214 [INTEL_OUTPUT_FORMAT_RGB] = "RGB", 10216 10215 [INTEL_OUTPUT_FORMAT_YCBCR420] = "YCBCR4:2:0", 10217 10216 [INTEL_OUTPUT_FORMAT_YCBCR444] = "YCBCR4:4:4", ··· 10219 10220 static const char *output_formats(enum intel_output_format format) 10220 10221 { 10221 10222 if (format >= ARRAY_SIZE(output_format_str)) 10222 - format = INTEL_OUTPUT_FORMAT_INVALID; 10223 + return "invalid"; 10223 10224 return output_format_str[format]; 10224 10225 } 10225 10226
-1
drivers/gpu/drm/i915/display/intel_display_types.h
··· 830 830 }; 831 831 832 832 enum intel_output_format { 833 - INTEL_OUTPUT_FORMAT_INVALID, 834 833 INTEL_OUTPUT_FORMAT_RGB, 835 834 INTEL_OUTPUT_FORMAT_YCBCR420, 836 835 INTEL_OUTPUT_FORMAT_YCBCR444,
+20 -73
drivers/gpu/drm/i915/gvt/cmd_parser.c
··· 41 41 #include "gt/intel_lrc.h" 42 42 #include "gt/intel_ring.h" 43 43 #include "gt/intel_gt_requests.h" 44 + #include "gt/shmem_utils.h" 44 45 #include "gvt.h" 45 46 #include "i915_pvinfo.h" 46 47 #include "trace.h" ··· 3095 3094 */ 3096 3095 void intel_gvt_update_reg_whitelist(struct intel_vgpu *vgpu) 3097 3096 { 3097 + const unsigned long start = LRC_STATE_PN * PAGE_SIZE; 3098 3098 struct intel_gvt *gvt = vgpu->gvt; 3099 - struct drm_i915_private *dev_priv = gvt->gt->i915; 3100 3099 struct intel_engine_cs *engine; 3101 3100 enum intel_engine_id id; 3102 - const unsigned long start = LRC_STATE_PN * PAGE_SIZE; 3103 - struct i915_request *rq; 3104 - struct intel_vgpu_submission *s = &vgpu->submission; 3105 - struct i915_request *requests[I915_NUM_ENGINES] = {}; 3106 - bool is_ctx_pinned[I915_NUM_ENGINES] = {}; 3107 - int ret = 0; 3108 3101 3109 3102 if (gvt->is_reg_whitelist_updated) 3110 3103 return; 3111 3104 3112 - for_each_engine(engine, &dev_priv->gt, id) { 3113 - ret = intel_context_pin(s->shadow[id]); 3114 - if (ret) { 3115 - gvt_vgpu_err("fail to pin shadow ctx\n"); 3116 - goto out; 3117 - } 3118 - is_ctx_pinned[id] = true; 3119 - 3120 - rq = i915_request_create(s->shadow[id]); 3121 - if (IS_ERR(rq)) { 3122 - gvt_vgpu_err("fail to alloc default request\n"); 3123 - ret = -EIO; 3124 - goto out; 3125 - } 3126 - requests[id] = i915_request_get(rq); 3127 - i915_request_add(rq); 3128 - } 3129 - 3130 - if (intel_gt_wait_for_idle(&dev_priv->gt, 3131 - I915_GEM_IDLE_TIMEOUT) == -ETIME) { 3132 - ret = -EIO; 3133 - goto out; 3134 - } 3135 - 3136 3105 /* scan init ctx to update cmd accessible list */ 3137 - for_each_engine(engine, &dev_priv->gt, id) { 3138 - int size = engine->context_size - PAGE_SIZE; 3139 - void *vaddr; 3106 + for_each_engine(engine, gvt->gt, id) { 3140 3107 struct parser_exec_state s; 3141 - struct drm_i915_gem_object *obj; 3142 - struct i915_request *rq; 3108 + void *vaddr; 3109 + int ret; 3143 3110 3144 - rq = requests[id]; 3145 - GEM_BUG_ON(!i915_request_completed(rq)); 3146 - GEM_BUG_ON(!intel_context_is_pinned(rq->context)); 3147 - obj = rq->context->state->obj; 3111 + if (!engine->default_state) 3112 + continue; 3148 3113 3149 - if (!obj) { 3150 - ret = -EIO; 3151 - goto out; 3152 - } 3153 - 3154 - i915_gem_object_set_cache_coherency(obj, 3155 - I915_CACHE_LLC); 3156 - 3157 - vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB); 3114 + vaddr = shmem_pin_map(engine->default_state); 3158 3115 if (IS_ERR(vaddr)) { 3159 - gvt_err("failed to pin init ctx obj, ring=%d, err=%lx\n", 3160 - id, PTR_ERR(vaddr)); 3161 - ret = PTR_ERR(vaddr); 3162 - goto out; 3116 + gvt_err("failed to map %s->default state, err:%zd\n", 3117 + engine->name, PTR_ERR(vaddr)); 3118 + return; 3163 3119 } 3164 3120 3165 3121 s.buf_type = RING_BUFFER_CTX; ··· 3124 3166 s.vgpu = vgpu; 3125 3167 s.engine = engine; 3126 3168 s.ring_start = 0; 3127 - s.ring_size = size; 3169 + s.ring_size = engine->context_size - start; 3128 3170 s.ring_head = 0; 3129 - s.ring_tail = size; 3171 + s.ring_tail = s.ring_size; 3130 3172 s.rb_va = vaddr + start; 3131 3173 s.workload = NULL; 3132 3174 s.is_ctx_wa = false; ··· 3134 3176 3135 3177 /* skipping the first RING_CTX_SIZE(0x50) dwords */ 3136 3178 ret = ip_gma_set(&s, RING_CTX_SIZE); 3137 - if (ret) { 3138 - i915_gem_object_unpin_map(obj); 3139 - goto out; 3179 + if (ret == 0) { 3180 + ret = command_scan(&s, 0, s.ring_size, 0, s.ring_size); 3181 + if (ret) 3182 + gvt_err("Scan init ctx error\n"); 3140 3183 } 3141 3184 3142 - ret = command_scan(&s, 0, size, 0, size); 3185 + shmem_unpin_map(engine->default_state, vaddr); 3143 3186 if (ret) 3144 - gvt_err("Scan init ctx error\n"); 3145 - 3146 - i915_gem_object_unpin_map(obj); 3187 + return; 3147 3188 } 3148 3189 3149 - out: 3150 - if (!ret) 3151 - gvt->is_reg_whitelist_updated = true; 3152 - 3153 - for (id = 0; id < I915_NUM_ENGINES ; id++) { 3154 - if (requests[id]) 3155 - i915_request_put(requests[id]); 3156 - 3157 - if (is_ctx_pinned[id]) 3158 - intel_context_unpin(s->shadow[id]); 3159 - } 3190 + gvt->is_reg_whitelist_updated = true; 3160 3191 } 3161 3192 3162 3193 int intel_gvt_scan_engine_context(struct intel_vgpu_workload *workload)
+3 -5
drivers/gpu/drm/i915/gvt/execlist.c
··· 522 522 static void clean_execlist(struct intel_vgpu *vgpu, 523 523 intel_engine_mask_t engine_mask) 524 524 { 525 - struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; 526 - struct intel_engine_cs *engine; 527 525 struct intel_vgpu_submission *s = &vgpu->submission; 526 + struct intel_engine_cs *engine; 528 527 intel_engine_mask_t tmp; 529 528 530 - for_each_engine_masked(engine, &dev_priv->gt, engine_mask, tmp) { 529 + for_each_engine_masked(engine, vgpu->gvt->gt, engine_mask, tmp) { 531 530 kfree(s->ring_scan_buffer[engine->id]); 532 531 s->ring_scan_buffer[engine->id] = NULL; 533 532 s->ring_scan_buffer_size[engine->id] = 0; ··· 536 537 static void reset_execlist(struct intel_vgpu *vgpu, 537 538 intel_engine_mask_t engine_mask) 538 539 { 539 - struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; 540 540 struct intel_engine_cs *engine; 541 541 intel_engine_mask_t tmp; 542 542 543 - for_each_engine_masked(engine, &dev_priv->gt, engine_mask, tmp) 543 + for_each_engine_masked(engine, vgpu->gvt->gt, engine_mask, tmp) 544 544 init_vgpu_execlist(vgpu, engine); 545 545 } 546 546
+41 -11
drivers/gpu/drm/i915/gvt/scheduler.c
··· 412 412 if (!wa_ctx->indirect_ctx.obj) 413 413 return; 414 414 415 + i915_gem_object_lock(wa_ctx->indirect_ctx.obj, NULL); 415 416 i915_gem_object_unpin_map(wa_ctx->indirect_ctx.obj); 417 + i915_gem_object_unlock(wa_ctx->indirect_ctx.obj); 416 418 i915_gem_object_put(wa_ctx->indirect_ctx.obj); 417 419 418 420 wa_ctx->indirect_ctx.obj = NULL; ··· 522 520 struct intel_gvt *gvt = workload->vgpu->gvt; 523 521 const int gmadr_bytes = gvt->device_info.gmadr_bytes_in_cmd; 524 522 struct intel_vgpu_shadow_bb *bb; 523 + struct i915_gem_ww_ctx ww; 525 524 int ret; 526 525 527 526 list_for_each_entry(bb, &workload->shadow_bb, list) { ··· 547 544 * directly 548 545 */ 549 546 if (!bb->ppgtt) { 550 - bb->vma = i915_gem_object_ggtt_pin(bb->obj, 551 - NULL, 0, 0, 0); 547 + i915_gem_ww_ctx_init(&ww, false); 548 + retry: 549 + i915_gem_object_lock(bb->obj, &ww); 550 + 551 + bb->vma = i915_gem_object_ggtt_pin_ww(bb->obj, &ww, 552 + NULL, 0, 0, 0); 552 553 if (IS_ERR(bb->vma)) { 553 554 ret = PTR_ERR(bb->vma); 555 + if (ret == -EDEADLK) { 556 + ret = i915_gem_ww_ctx_backoff(&ww); 557 + if (!ret) 558 + goto retry; 559 + } 554 560 goto err; 555 561 } 556 562 ··· 573 561 0); 574 562 if (ret) 575 563 goto err; 576 - } 577 564 578 - /* No one is going to touch shadow bb from now on. */ 579 - i915_gem_object_flush_map(bb->obj); 565 + /* No one is going to touch shadow bb from now on. */ 566 + i915_gem_object_flush_map(bb->obj); 567 + i915_gem_object_unlock(bb->obj); 568 + } 580 569 } 581 570 return 0; 582 571 err: 572 + i915_gem_ww_ctx_fini(&ww); 583 573 release_shadow_batch_buffer(workload); 584 574 return ret; 585 575 } ··· 608 594 unsigned char *per_ctx_va = 609 595 (unsigned char *)wa_ctx->indirect_ctx.shadow_va + 610 596 wa_ctx->indirect_ctx.size; 597 + struct i915_gem_ww_ctx ww; 598 + int ret; 611 599 612 600 if (wa_ctx->indirect_ctx.size == 0) 613 601 return 0; 614 602 615 - vma = i915_gem_object_ggtt_pin(wa_ctx->indirect_ctx.obj, NULL, 616 - 0, CACHELINE_BYTES, 0); 617 - if (IS_ERR(vma)) 618 - return PTR_ERR(vma); 603 + i915_gem_ww_ctx_init(&ww, false); 604 + retry: 605 + i915_gem_object_lock(wa_ctx->indirect_ctx.obj, &ww); 606 + 607 + vma = i915_gem_object_ggtt_pin_ww(wa_ctx->indirect_ctx.obj, &ww, NULL, 608 + 0, CACHELINE_BYTES, 0); 609 + if (IS_ERR(vma)) { 610 + ret = PTR_ERR(vma); 611 + if (ret == -EDEADLK) { 612 + ret = i915_gem_ww_ctx_backoff(&ww); 613 + if (!ret) 614 + goto retry; 615 + } 616 + return ret; 617 + } 618 + 619 + i915_gem_object_unlock(wa_ctx->indirect_ctx.obj); 619 620 620 621 /* FIXME: we are not tracking our pinned VMA leaving it 621 622 * up to the core to fix up the stray pin_count upon ··· 664 635 665 636 list_for_each_entry_safe(bb, pos, &workload->shadow_bb, list) { 666 637 if (bb->obj) { 638 + i915_gem_object_lock(bb->obj, NULL); 667 639 if (bb->va && !IS_ERR(bb->va)) 668 640 i915_gem_object_unpin_map(bb->obj); 669 641 670 642 if (bb->vma && !IS_ERR(bb->vma)) 671 643 i915_vma_unpin(bb->vma); 672 644 645 + i915_gem_object_unlock(bb->obj); 673 646 i915_gem_object_put(bb->obj); 674 647 } 675 648 list_del(&bb->list); ··· 1046 1015 intel_engine_mask_t engine_mask) 1047 1016 { 1048 1017 struct intel_vgpu_submission *s = &vgpu->submission; 1049 - struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; 1050 1018 struct intel_engine_cs *engine; 1051 1019 struct intel_vgpu_workload *pos, *n; 1052 1020 intel_engine_mask_t tmp; 1053 1021 1054 1022 /* free the unsubmited workloads in the queues. */ 1055 - for_each_engine_masked(engine, &dev_priv->gt, engine_mask, tmp) { 1023 + for_each_engine_masked(engine, vgpu->gvt->gt, engine_mask, tmp) { 1056 1024 list_for_each_entry_safe(pos, n, 1057 1025 &s->workload_q_head[engine->id], list) { 1058 1026 list_del_init(&pos->list);
+2
drivers/gpu/drm/msm/adreno/a5xx.xml.h
··· 2367 2367 2368 2368 #define REG_A5XX_UCHE_ADDR_MODE_CNTL 0x00000e80 2369 2369 2370 + #define REG_A5XX_UCHE_MODE_CNTL 0x00000e81 2371 + 2370 2372 #define REG_A5XX_UCHE_SVM_CNTL 0x00000e82 2371 2373 2372 2374 #define REG_A5XX_UCHE_WRITE_THRU_BASE_LO 0x00000e87
+170 -25
drivers/gpu/drm/msm/adreno/a5xx_gpu.c
··· 222 222 a5xx_preempt_trigger(gpu); 223 223 } 224 224 225 - static const struct { 225 + static const struct adreno_five_hwcg_regs { 226 226 u32 offset; 227 227 u32 value; 228 228 } a5xx_hwcg[] = { ··· 318 318 {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, 319 319 {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, 320 320 {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222} 321 + }, a50x_hwcg[] = { 322 + {REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, 323 + {REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, 324 + {REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF}, 325 + {REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080}, 326 + {REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222}, 327 + {REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, 328 + {REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222}, 329 + {REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, 330 + {REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, 331 + {REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777}, 332 + {REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, 333 + {REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, 334 + {REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111}, 335 + {REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222}, 336 + {REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222}, 337 + {REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222}, 338 + {REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, 339 + {REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00FFFFF4}, 340 + {REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, 341 + {REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, 342 + {REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222}, 343 + {REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220}, 344 + {REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222}, 345 + {REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555}, 346 + {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404}, 347 + {REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044}, 348 + {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002}, 349 + {REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011}, 350 + {REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, 351 + {REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222}, 352 + {REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, 353 + {REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, 354 + {REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, 355 + {REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, 356 + {REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, 357 + {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, 358 + {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, 359 + {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}, 360 + }, a512_hwcg[] = { 361 + {REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, 362 + {REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222}, 363 + {REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, 364 + {REG_A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220}, 365 + {REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF}, 366 + {REG_A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF}, 367 + {REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080}, 368 + {REG_A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080}, 369 + {REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222}, 370 + {REG_A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222}, 371 + {REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, 372 + {REG_A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222}, 373 + {REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222}, 374 + {REG_A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222}, 375 + {REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, 376 + {REG_A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777}, 377 + {REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, 378 + {REG_A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777}, 379 + {REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777}, 380 + {REG_A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777}, 381 + {REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, 382 + {REG_A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111}, 383 + {REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, 384 + {REG_A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111}, 385 + {REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111}, 386 + {REG_A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111}, 387 + {REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, 388 + {REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222}, 389 + {REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222}, 390 + {REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222}, 391 + {REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444}, 392 + {REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, 393 + {REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, 394 + {REG_A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222}, 395 + {REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222}, 396 + {REG_A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222}, 397 + {REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220}, 398 + {REG_A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220}, 399 + {REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222}, 400 + {REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555}, 401 + {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404}, 402 + {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404}, 403 + {REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044}, 404 + {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002}, 405 + {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002}, 406 + {REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011}, 407 + {REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, 408 + {REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222}, 409 + {REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, 410 + {REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, 411 + {REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, 412 + {REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, 413 + {REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, 414 + {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, 415 + {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, 416 + {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}, 321 417 }; 322 418 323 419 void a5xx_set_hwcg(struct msm_gpu *gpu, bool state) 324 420 { 325 421 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 326 - unsigned int i; 422 + const struct adreno_five_hwcg_regs *regs; 423 + unsigned int i, sz; 327 424 328 - for (i = 0; i < ARRAY_SIZE(a5xx_hwcg); i++) 329 - gpu_write(gpu, a5xx_hwcg[i].offset, 330 - state ? a5xx_hwcg[i].value : 0); 425 + if (adreno_is_a508(adreno_gpu)) { 426 + regs = a50x_hwcg; 427 + sz = ARRAY_SIZE(a50x_hwcg); 428 + } else if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu)) { 429 + regs = a512_hwcg; 430 + sz = ARRAY_SIZE(a512_hwcg); 431 + } else { 432 + regs = a5xx_hwcg; 433 + sz = ARRAY_SIZE(a5xx_hwcg); 434 + } 435 + 436 + for (i = 0; i < sz; i++) 437 + gpu_write(gpu, regs[i].offset, 438 + state ? regs[i].value : 0); 331 439 332 440 if (adreno_is_a540(adreno_gpu)) { 333 441 gpu_write(gpu, REG_A5XX_RBBM_CLOCK_DELAY_GPMU, state ? 0x00000770 : 0); ··· 646 538 { 647 539 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 648 540 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); 541 + u32 regbit; 649 542 int ret; 650 543 651 544 gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003); 652 545 653 - if (adreno_is_a540(adreno_gpu)) 546 + if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) || 547 + adreno_is_a540(adreno_gpu)) 654 548 gpu_write(gpu, REG_A5XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009); 655 549 656 550 /* Make all blocks contribute to the GPU BUSY perf counter */ ··· 714 604 0x00100000 + adreno_gpu->gmem - 1); 715 605 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000); 716 606 717 - if (adreno_is_a510(adreno_gpu)) { 607 + if (adreno_is_a508(adreno_gpu) || adreno_is_a510(adreno_gpu)) { 718 608 gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x20); 719 - gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x20); 609 + if (adreno_is_a508(adreno_gpu)) 610 + gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400); 611 + else 612 + gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x20); 720 613 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x40000030); 721 614 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A); 722 - gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 723 - (0x200 << 11 | 0x200 << 22)); 724 615 } else { 725 616 gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40); 726 617 if (adreno_is_a530(adreno_gpu)) 727 618 gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40); 728 - if (adreno_is_a540(adreno_gpu)) 619 + else 729 620 gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400); 730 621 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060); 731 622 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16); 623 + } 624 + 625 + if (adreno_is_a508(adreno_gpu)) 626 + gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 627 + (0x100 << 11 | 0x100 << 22)); 628 + else if (adreno_is_a509(adreno_gpu) || adreno_is_a510(adreno_gpu) || 629 + adreno_is_a512(adreno_gpu)) 630 + gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 631 + (0x200 << 11 | 0x200 << 22)); 632 + else 732 633 gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 733 634 (0x400 << 11 | 0x300 << 22)); 734 - } 735 635 736 636 if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) 737 637 gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); 738 638 739 - gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); 639 + /* 640 + * Disable the RB sampler datapath DP2 clock gating optimization 641 + * for 1-SP GPUs, as it is enabled by default. 642 + */ 643 + if (adreno_is_a508(adreno_gpu) || adreno_is_a509(adreno_gpu) || 644 + adreno_is_a512(adreno_gpu)) 645 + gpu_rmw(gpu, REG_A5XX_RB_DBG_ECO_CNTL, 0, (1 << 9)); 646 + 647 + /* Disable UCHE global filter as SP can invalidate/flush independently */ 648 + gpu_write(gpu, REG_A5XX_UCHE_MODE_CNTL, BIT(29)); 740 649 741 650 /* Enable USE_RETENTION_FLOPS */ 742 651 gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000); ··· 782 653 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F); 783 654 784 655 /* Set the highest bank bit */ 785 - gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, 2 << 7); 786 - gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, 2 << 1); 787 656 if (adreno_is_a540(adreno_gpu)) 788 - gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, 2); 657 + regbit = 2; 658 + else 659 + regbit = 1; 660 + 661 + gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, regbit << 7); 662 + gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, regbit << 1); 663 + 664 + if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) || 665 + adreno_is_a540(adreno_gpu)) 666 + gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, regbit); 667 + 668 + /* Disable All flat shading optimization (ALLFLATOPTDIS) */ 669 + gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10)); 789 670 790 671 /* Protect registers from the CP */ 791 672 gpu_write(gpu, REG_A5XX_CP_PROTECT_CNTL, 0x00000007); ··· 827 688 828 689 /* VPC */ 829 690 gpu_write(gpu, REG_A5XX_CP_PROTECT(14), ADRENO_PROTECT_RW(0xE68, 8)); 830 - gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 4)); 691 + gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 16)); 831 692 832 693 /* UCHE */ 833 694 gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16)); 834 695 835 - if (adreno_is_a530(adreno_gpu) || adreno_is_a510(adreno_gpu)) 696 + if (adreno_is_a508(adreno_gpu) || adreno_is_a509(adreno_gpu) || 697 + adreno_is_a510(adreno_gpu) || adreno_is_a512(adreno_gpu) || 698 + adreno_is_a530(adreno_gpu)) 836 699 gpu_write(gpu, REG_A5XX_CP_PROTECT(17), 837 700 ADRENO_PROTECT_RW(0x10000, 0x8000)); 838 701 ··· 876 735 if (ret) 877 736 return ret; 878 737 879 - if (!adreno_is_a510(adreno_gpu)) 738 + if (!(adreno_is_a508(adreno_gpu) || adreno_is_a509(adreno_gpu) || 739 + adreno_is_a510(adreno_gpu) || adreno_is_a512(adreno_gpu))) 880 740 a5xx_gpmu_ucode_init(gpu); 881 741 882 742 ret = a5xx_ucode_init(gpu); ··· 1310 1168 if (ret) 1311 1169 return ret; 1312 1170 1313 - if (adreno_is_a510(adreno_gpu)) { 1171 + /* Adreno 508, 509, 510, 512 needs manual RBBM sus/res control */ 1172 + if (!(adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu))) { 1314 1173 /* Halt the sp_input_clk at HM level */ 1315 1174 gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0x00000055); 1316 1175 a5xx_set_hwcg(gpu, true); ··· 1353 1210 u32 mask = 0xf; 1354 1211 int i, ret; 1355 1212 1356 - /* A510 has 3 XIN ports in VBIF */ 1357 - if (adreno_is_a510(adreno_gpu)) 1213 + /* A508, A510 have 3 XIN ports in VBIF */ 1214 + if (adreno_is_a508(adreno_gpu) || adreno_is_a510(adreno_gpu)) 1358 1215 mask = 0x7; 1359 1216 1360 1217 /* Clear the VBIF pipe before shutting down */ ··· 1366 1223 1367 1224 /* 1368 1225 * Reset the VBIF before power collapse to avoid issue with FIFO 1369 - * entries 1226 + * entries on Adreno A510 and A530 (the others will tend to lock up) 1370 1227 */ 1371 - gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C0000); 1372 - gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x00000000); 1228 + if (adreno_is_a510(adreno_gpu) || adreno_is_a530(adreno_gpu)) { 1229 + gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C0000); 1230 + gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x00000000); 1231 + } 1373 1232 1374 1233 ret = msm_gpu_pm_suspend(gpu); 1375 1234 if (ret)
+2 -2
drivers/gpu/drm/msm/adreno/a5xx_power.c
··· 298 298 int ret; 299 299 300 300 /* Not all A5xx chips have a GPMU */ 301 - if (adreno_is_a510(adreno_gpu)) 301 + if (!(adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu))) 302 302 return 0; 303 303 304 304 /* Set up the limits management */ ··· 330 330 unsigned int *data, *ptr, *cmds; 331 331 unsigned int cmds_size; 332 332 333 - if (adreno_is_a510(adreno_gpu)) 333 + if (!(adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu))) 334 334 return; 335 335 336 336 if (a5xx_gpu->gpmu_bo)
+63 -44
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
··· 245 245 return ret; 246 246 } 247 247 248 + struct a6xx_gmu_oob_bits { 249 + int set, ack, set_new, ack_new; 250 + const char *name; 251 + }; 252 + 253 + /* These are the interrupt / ack bits for each OOB request that are set 254 + * in a6xx_gmu_set_oob and a6xx_clear_oob 255 + */ 256 + static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = { 257 + [GMU_OOB_GPU_SET] = { 258 + .name = "GPU_SET", 259 + .set = 16, 260 + .ack = 24, 261 + .set_new = 30, 262 + .ack_new = 31, 263 + }, 264 + 265 + [GMU_OOB_PERFCOUNTER_SET] = { 266 + .name = "PERFCOUNTER", 267 + .set = 17, 268 + .ack = 25, 269 + .set_new = 28, 270 + .ack_new = 30, 271 + }, 272 + 273 + [GMU_OOB_BOOT_SLUMBER] = { 274 + .name = "BOOT_SLUMBER", 275 + .set = 22, 276 + .ack = 30, 277 + }, 278 + 279 + [GMU_OOB_DCVS_SET] = { 280 + .name = "GPU_DCVS", 281 + .set = 23, 282 + .ack = 31, 283 + }, 284 + }; 285 + 248 286 /* Trigger a OOB (out of band) request to the GMU */ 249 287 int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) 250 288 { 251 289 int ret; 252 290 u32 val; 253 291 int request, ack; 254 - const char *name; 255 292 256 - switch (state) { 257 - case GMU_OOB_GPU_SET: 258 - if (gmu->legacy) { 259 - request = GMU_OOB_GPU_SET_REQUEST; 260 - ack = GMU_OOB_GPU_SET_ACK; 261 - } else { 262 - request = GMU_OOB_GPU_SET_REQUEST_NEW; 263 - ack = GMU_OOB_GPU_SET_ACK_NEW; 264 - } 265 - name = "GPU_SET"; 266 - break; 267 - case GMU_OOB_BOOT_SLUMBER: 268 - request = GMU_OOB_BOOT_SLUMBER_REQUEST; 269 - ack = GMU_OOB_BOOT_SLUMBER_ACK; 270 - name = "BOOT_SLUMBER"; 271 - break; 272 - case GMU_OOB_DCVS_SET: 273 - request = GMU_OOB_DCVS_REQUEST; 274 - ack = GMU_OOB_DCVS_ACK; 275 - name = "GPU_DCVS"; 276 - break; 277 - default: 293 + if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits)) 278 294 return -EINVAL; 295 + 296 + if (gmu->legacy) { 297 + request = a6xx_gmu_oob_bits[state].set; 298 + ack = a6xx_gmu_oob_bits[state].ack; 299 + } else { 300 + request = a6xx_gmu_oob_bits[state].set_new; 301 + ack = a6xx_gmu_oob_bits[state].ack_new; 302 + if (!request || !ack) { 303 + DRM_DEV_ERROR(gmu->dev, 304 + "Invalid non-legacy GMU request %s\n", 305 + a6xx_gmu_oob_bits[state].name); 306 + return -EINVAL; 307 + } 279 308 } 280 309 281 310 /* Trigger the equested OOB operation */ ··· 317 288 if (ret) 318 289 DRM_DEV_ERROR(gmu->dev, 319 290 "Timeout waiting for GMU OOB set %s: 0x%x\n", 320 - name, 291 + a6xx_gmu_oob_bits[state].name, 321 292 gmu_read(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO)); 322 293 323 294 /* Clear the acknowledge interrupt */ ··· 329 300 /* Clear a pending OOB state in the GMU */ 330 301 void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) 331 302 { 332 - if (!gmu->legacy) { 333 - WARN_ON(state != GMU_OOB_GPU_SET); 334 - gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 335 - 1 << GMU_OOB_GPU_SET_CLEAR_NEW); 336 - return; 337 - } 303 + int bit; 338 304 339 - switch (state) { 340 - case GMU_OOB_GPU_SET: 341 - gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 342 - 1 << GMU_OOB_GPU_SET_CLEAR); 343 - break; 344 - case GMU_OOB_BOOT_SLUMBER: 345 - gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 346 - 1 << GMU_OOB_BOOT_SLUMBER_CLEAR); 347 - break; 348 - case GMU_OOB_DCVS_SET: 349 - gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 350 - 1 << GMU_OOB_DCVS_CLEAR); 351 - break; 352 - } 305 + if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits)) 306 + return; 307 + 308 + if (gmu->legacy) 309 + bit = a6xx_gmu_oob_bits[state].ack; 310 + else 311 + bit = a6xx_gmu_oob_bits[state].ack_new; 312 + 313 + gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, bit); 353 314 } 354 315 355 316 /* Enable CPU control of SPTP power power collapse */
+16 -33
drivers/gpu/drm/msm/adreno/a6xx_gmu.h
··· 153 153 */ 154 154 155 155 enum a6xx_gmu_oob_state { 156 + /* 157 + * Let the GMU know that a boot or slumber operation has started. The value in 158 + * REG_A6XX_GMU_BOOT_SLUMBER_OPTION lets the GMU know which operation we are 159 + * doing 160 + */ 156 161 GMU_OOB_BOOT_SLUMBER = 0, 162 + /* 163 + * Let the GMU know to not turn off any GPU registers while the CPU is in a 164 + * critical section 165 + */ 157 166 GMU_OOB_GPU_SET, 167 + /* 168 + * Set a new power level for the GPU when the CPU is doing frequency scaling 169 + */ 158 170 GMU_OOB_DCVS_SET, 171 + /* 172 + * Used to keep the GPU on for CPU-side reads of performance counters. 173 + */ 174 + GMU_OOB_PERFCOUNTER_SET, 159 175 }; 160 - 161 - /* These are the interrupt / ack bits for each OOB request that are set 162 - * in a6xx_gmu_set_oob and a6xx_clear_oob 163 - */ 164 - 165 - /* 166 - * Let the GMU know that a boot or slumber operation has started. The value in 167 - * REG_A6XX_GMU_BOOT_SLUMBER_OPTION lets the GMU know which operation we are 168 - * doing 169 - */ 170 - #define GMU_OOB_BOOT_SLUMBER_REQUEST 22 171 - #define GMU_OOB_BOOT_SLUMBER_ACK 30 172 - #define GMU_OOB_BOOT_SLUMBER_CLEAR 30 173 - 174 - /* 175 - * Set a new power level for the GPU when the CPU is doing frequency scaling 176 - */ 177 - #define GMU_OOB_DCVS_REQUEST 23 178 - #define GMU_OOB_DCVS_ACK 31 179 - #define GMU_OOB_DCVS_CLEAR 31 180 - 181 - /* 182 - * Let the GMU know to not turn off any GPU registers while the CPU is in a 183 - * critical section 184 - */ 185 - #define GMU_OOB_GPU_SET_REQUEST 16 186 - #define GMU_OOB_GPU_SET_ACK 24 187 - #define GMU_OOB_GPU_SET_CLEAR 24 188 - 189 - #define GMU_OOB_GPU_SET_REQUEST_NEW 30 190 - #define GMU_OOB_GPU_SET_ACK_NEW 31 191 - #define GMU_OOB_GPU_SET_CLEAR_NEW 31 192 - 193 176 194 177 void a6xx_hfi_init(struct a6xx_gmu *gmu); 195 178 int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
+135 -4
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
··· 10 10 11 11 #include <linux/bitfield.h> 12 12 #include <linux/devfreq.h> 13 + #include <linux/nvmem-consumer.h> 13 14 #include <linux/soc/qcom/llcc-qcom.h> 14 15 15 16 #define GPU_PAS_ID 13 ··· 1118 1117 a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU); 1119 1118 a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW); 1120 1119 1121 - if (IS_ERR(a6xx_gpu->llc_slice) && IS_ERR(a6xx_gpu->htw_llc_slice)) 1120 + if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice)) 1122 1121 a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL); 1123 1122 } 1124 1123 ··· 1170 1169 { 1171 1170 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 1172 1171 struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); 1172 + static DEFINE_MUTEX(perfcounter_oob); 1173 + 1174 + mutex_lock(&perfcounter_oob); 1173 1175 1174 1176 /* Force the GPU power on so we can read this register */ 1175 - a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET); 1177 + a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET); 1176 1178 1177 1179 *value = gpu_read64(gpu, REG_A6XX_RBBM_PERFCTR_CP_0_LO, 1178 1180 REG_A6XX_RBBM_PERFCTR_CP_0_HI); 1179 1181 1180 - a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET); 1182 + a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET); 1183 + mutex_unlock(&perfcounter_oob); 1181 1184 return 0; 1182 1185 } 1183 1186 ··· 1213 1208 a6xx_gmu_remove(a6xx_gpu); 1214 1209 1215 1210 adreno_gpu_cleanup(adreno_gpu); 1211 + 1212 + if (a6xx_gpu->opp_table) 1213 + dev_pm_opp_put_supported_hw(a6xx_gpu->opp_table); 1214 + 1216 1215 kfree(a6xx_gpu); 1217 1216 } 1218 1217 ··· 1249 1240 } 1250 1241 1251 1242 static struct msm_gem_address_space * 1243 + a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev) 1244 + { 1245 + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 1246 + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); 1247 + struct iommu_domain *iommu; 1248 + struct msm_mmu *mmu; 1249 + struct msm_gem_address_space *aspace; 1250 + u64 start, size; 1251 + 1252 + iommu = iommu_domain_alloc(&platform_bus_type); 1253 + if (!iommu) 1254 + return NULL; 1255 + 1256 + /* 1257 + * This allows GPU to set the bus attributes required to use system 1258 + * cache on behalf of the iommu page table walker. 1259 + */ 1260 + if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice)) 1261 + adreno_set_llc_attributes(iommu); 1262 + 1263 + mmu = msm_iommu_new(&pdev->dev, iommu); 1264 + if (IS_ERR(mmu)) { 1265 + iommu_domain_free(iommu); 1266 + return ERR_CAST(mmu); 1267 + } 1268 + 1269 + /* 1270 + * Use the aperture start or SZ_16M, whichever is greater. This will 1271 + * ensure that we align with the allocated pagetable range while still 1272 + * allowing room in the lower 32 bits for GMEM and whatnot 1273 + */ 1274 + start = max_t(u64, SZ_16M, iommu->geometry.aperture_start); 1275 + size = iommu->geometry.aperture_end - start + 1; 1276 + 1277 + aspace = msm_gem_address_space_create(mmu, "gpu", 1278 + start & GENMASK_ULL(48, 0), size); 1279 + 1280 + if (IS_ERR(aspace) && !IS_ERR(mmu)) 1281 + mmu->funcs->destroy(mmu); 1282 + 1283 + return aspace; 1284 + } 1285 + 1286 + static struct msm_gem_address_space * 1252 1287 a6xx_create_private_address_space(struct msm_gpu *gpu) 1253 1288 { 1254 1289 struct msm_mmu *mmu; ··· 1317 1264 return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR); 1318 1265 } 1319 1266 1267 + static u32 a618_get_speed_bin(u32 fuse) 1268 + { 1269 + if (fuse == 0) 1270 + return 0; 1271 + else if (fuse == 169) 1272 + return 1; 1273 + else if (fuse == 174) 1274 + return 2; 1275 + 1276 + return UINT_MAX; 1277 + } 1278 + 1279 + static u32 fuse_to_supp_hw(struct device *dev, u32 revn, u32 fuse) 1280 + { 1281 + u32 val = UINT_MAX; 1282 + 1283 + if (revn == 618) 1284 + val = a618_get_speed_bin(fuse); 1285 + 1286 + if (val == UINT_MAX) { 1287 + DRM_DEV_ERROR(dev, 1288 + "missing support for speed-bin: %u. Some OPPs may not be supported by hardware", 1289 + fuse); 1290 + return UINT_MAX; 1291 + } 1292 + 1293 + return (1 << val); 1294 + } 1295 + 1296 + static int a6xx_set_supported_hw(struct device *dev, struct a6xx_gpu *a6xx_gpu, 1297 + u32 revn) 1298 + { 1299 + struct opp_table *opp_table; 1300 + struct nvmem_cell *cell; 1301 + u32 supp_hw = UINT_MAX; 1302 + void *buf; 1303 + 1304 + cell = nvmem_cell_get(dev, "speed_bin"); 1305 + /* 1306 + * -ENOENT means that the platform doesn't support speedbin which is 1307 + * fine 1308 + */ 1309 + if (PTR_ERR(cell) == -ENOENT) 1310 + return 0; 1311 + else if (IS_ERR(cell)) { 1312 + DRM_DEV_ERROR(dev, 1313 + "failed to read speed-bin. Some OPPs may not be supported by hardware"); 1314 + goto done; 1315 + } 1316 + 1317 + buf = nvmem_cell_read(cell, NULL); 1318 + if (IS_ERR(buf)) { 1319 + nvmem_cell_put(cell); 1320 + DRM_DEV_ERROR(dev, 1321 + "failed to read speed-bin. Some OPPs may not be supported by hardware"); 1322 + goto done; 1323 + } 1324 + 1325 + supp_hw = fuse_to_supp_hw(dev, revn, *((u32 *) buf)); 1326 + 1327 + kfree(buf); 1328 + nvmem_cell_put(cell); 1329 + 1330 + done: 1331 + opp_table = dev_pm_opp_set_supported_hw(dev, &supp_hw, 1); 1332 + if (IS_ERR(opp_table)) 1333 + return PTR_ERR(opp_table); 1334 + 1335 + a6xx_gpu->opp_table = opp_table; 1336 + return 0; 1337 + } 1338 + 1320 1339 static const struct adreno_gpu_funcs funcs = { 1321 1340 .base = { 1322 1341 .get_param = adreno_get_param, ··· 1410 1285 .gpu_state_get = a6xx_gpu_state_get, 1411 1286 .gpu_state_put = a6xx_gpu_state_put, 1412 1287 #endif 1413 - .create_address_space = adreno_iommu_create_address_space, 1288 + .create_address_space = a6xx_create_address_space, 1414 1289 .create_private_address_space = a6xx_create_private_address_space, 1415 1290 .get_rptr = a6xx_get_rptr, 1416 1291 }, ··· 1449 1324 adreno_gpu->base.hw_apriv = true; 1450 1325 1451 1326 a6xx_llc_slices_init(pdev, a6xx_gpu); 1327 + 1328 + ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info->revn); 1329 + if (ret) { 1330 + a6xx_destroy(&(a6xx_gpu->base.base)); 1331 + return ERR_PTR(ret); 1332 + } 1452 1333 1453 1334 ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); 1454 1335 if (ret) {
+2
drivers/gpu/drm/msm/adreno/a6xx_gpu.h
··· 33 33 void *llc_slice; 34 34 void *htw_llc_slice; 35 35 bool have_mmu500; 36 + 37 + struct opp_table *opp_table; 36 38 }; 37 39 38 40 #define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base)
+53 -1
drivers/gpu/drm/msm/adreno/adreno_device.c
··· 134 134 .inactive_period = DRM_MSM_INACTIVE_PERIOD, 135 135 .init = a4xx_gpu_init, 136 136 }, { 137 + .rev = ADRENO_REV(5, 0, 8, ANY_ID), 138 + .revn = 508, 139 + .name = "A508", 140 + .fw = { 141 + [ADRENO_FW_PM4] = "a530_pm4.fw", 142 + [ADRENO_FW_PFP] = "a530_pfp.fw", 143 + }, 144 + .gmem = (SZ_128K + SZ_8K), 145 + /* 146 + * Increase inactive period to 250 to avoid bouncing 147 + * the GDSC which appears to make it grumpy 148 + */ 149 + .inactive_period = 250, 150 + .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE, 151 + .init = a5xx_gpu_init, 152 + .zapfw = "a508_zap.mdt", 153 + }, { 154 + .rev = ADRENO_REV(5, 0, 9, ANY_ID), 155 + .revn = 509, 156 + .name = "A509", 157 + .fw = { 158 + [ADRENO_FW_PM4] = "a530_pm4.fw", 159 + [ADRENO_FW_PFP] = "a530_pfp.fw", 160 + }, 161 + .gmem = (SZ_256K + SZ_16K), 162 + /* 163 + * Increase inactive period to 250 to avoid bouncing 164 + * the GDSC which appears to make it grumpy 165 + */ 166 + .inactive_period = 250, 167 + .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE, 168 + .init = a5xx_gpu_init, 169 + /* Adreno 509 uses the same ZAP as 512 */ 170 + .zapfw = "a512_zap.mdt", 171 + }, { 137 172 .rev = ADRENO_REV(5, 1, 0, ANY_ID), 138 173 .revn = 510, 139 174 .name = "A510", ··· 183 148 */ 184 149 .inactive_period = 250, 185 150 .init = a5xx_gpu_init, 151 + }, { 152 + .rev = ADRENO_REV(5, 1, 2, ANY_ID), 153 + .revn = 512, 154 + .name = "A512", 155 + .fw = { 156 + [ADRENO_FW_PM4] = "a530_pm4.fw", 157 + [ADRENO_FW_PFP] = "a530_pfp.fw", 158 + }, 159 + .gmem = (SZ_256K + SZ_16K), 160 + /* 161 + * Increase inactive period to 250 to avoid bouncing 162 + * the GDSC which appears to make it grumpy 163 + */ 164 + .inactive_period = 250, 165 + .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE, 166 + .init = a5xx_gpu_init, 167 + .zapfw = "a512_zap.mdt", 186 168 }, { 187 169 .rev = ADRENO_REV(5, 3, 0, 2), 188 170 .revn = 530, ··· 220 168 .init = a5xx_gpu_init, 221 169 .zapfw = "a530_zap.mdt", 222 170 }, { 223 - .rev = ADRENO_REV(5, 4, 0, 2), 171 + .rev = ADRENO_REV(5, 4, 0, ANY_ID), 224 172 .revn = 540, 225 173 .name = "A540", 226 174 .fw = {
+8 -15
drivers/gpu/drm/msm/adreno/adreno_gpu.c
··· 186 186 return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid); 187 187 } 188 188 189 + void adreno_set_llc_attributes(struct iommu_domain *iommu) 190 + { 191 + struct io_pgtable_domain_attr pgtbl_cfg; 192 + 193 + pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; 194 + iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg); 195 + } 196 + 189 197 struct msm_gem_address_space * 190 198 adreno_iommu_create_address_space(struct msm_gpu *gpu, 191 199 struct platform_device *pdev) 192 200 { 193 - struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 194 201 struct iommu_domain *iommu; 195 202 struct msm_mmu *mmu; 196 203 struct msm_gem_address_space *aspace; ··· 206 199 iommu = iommu_domain_alloc(&platform_bus_type); 207 200 if (!iommu) 208 201 return NULL; 209 - 210 - 211 - if (adreno_is_a6xx(adreno_gpu)) { 212 - struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); 213 - struct io_pgtable_domain_attr pgtbl_cfg; 214 - /* 215 - * This allows GPU to set the bus attributes required to use system 216 - * cache on behalf of the iommu page table walker. 217 - */ 218 - if (!IS_ERR(a6xx_gpu->htw_llc_slice)) { 219 - pgtbl_cfg.quirks = IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; 220 - iommu_domain_set_attr(iommu, DOMAIN_ATTR_IO_PGTABLE_CFG, &pgtbl_cfg); 221 - } 222 - } 223 202 224 203 mmu = msm_iommu_new(&pdev->dev, iommu); 225 204 if (IS_ERR(mmu)) {
+17 -5
drivers/gpu/drm/msm/adreno/adreno_gpu.h
··· 197 197 return gpu->revn == 430; 198 198 } 199 199 200 + static inline int adreno_is_a508(struct adreno_gpu *gpu) 201 + { 202 + return gpu->revn == 508; 203 + } 204 + 205 + static inline int adreno_is_a509(struct adreno_gpu *gpu) 206 + { 207 + return gpu->revn == 509; 208 + } 209 + 200 210 static inline int adreno_is_a510(struct adreno_gpu *gpu) 201 211 { 202 212 return gpu->revn == 510; 213 + } 214 + 215 + static inline int adreno_is_a512(struct adreno_gpu *gpu) 216 + { 217 + return gpu->revn == 512; 203 218 } 204 219 205 220 static inline int adreno_is_a530(struct adreno_gpu *gpu) ··· 225 210 static inline int adreno_is_a540(struct adreno_gpu *gpu) 226 211 { 227 212 return gpu->revn == 540; 228 - } 229 - 230 - static inline bool adreno_is_a6xx(struct adreno_gpu *gpu) 231 - { 232 - return ((gpu->revn < 700 && gpu->revn > 599)); 233 213 } 234 214 235 215 static inline int adreno_is_a618(struct adreno_gpu *gpu) ··· 287 277 struct msm_gem_address_space * 288 278 adreno_iommu_create_address_space(struct msm_gpu *gpu, 289 279 struct platform_device *pdev); 280 + 281 + void adreno_set_llc_attributes(struct iommu_domain *iommu); 290 282 291 283 /* 292 284 * For a5xx and a6xx targets load the zap shader that is used to pull the GPU
+75 -15
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
··· 4 4 */ 5 5 6 6 #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ 7 + #include <linux/delay.h> 7 8 #include "dpu_encoder_phys.h" 8 9 #include "dpu_hw_interrupts.h" 10 + #include "dpu_hw_pingpong.h" 9 11 #include "dpu_core_irq.h" 10 12 #include "dpu_formats.h" 11 13 #include "dpu_trace.h" ··· 36 34 #define DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE 4 37 35 38 36 #define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000 37 + 38 + #define DPU_ENC_MAX_POLL_TIMEOUT_US 2000 39 39 40 40 static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc) 41 41 { ··· 372 368 tc_cfg.vsync_count = vsync_hz / 373 369 (mode->vtotal * drm_mode_vrefresh(mode)); 374 370 375 - /* enable external TE after kickoff to avoid premature autorefresh */ 376 - tc_cfg.hw_vsync_mode = 0; 377 - 378 371 /* 379 - * By setting sync_cfg_height to near max register value, we essentially 380 - * disable dpu hw generated TE signal, since hw TE will arrive first. 381 - * Only caveat is if due to error, we hit wrap-around. 372 + * Set the sync_cfg_height to twice vtotal so that if we lose a 373 + * TE event coming from the display TE pin we won't stall immediately 382 374 */ 383 - tc_cfg.sync_cfg_height = 0xFFF0; 375 + tc_cfg.hw_vsync_mode = 1; 376 + tc_cfg.sync_cfg_height = mode->vtotal * 2; 384 377 tc_cfg.vsync_init_val = mode->vdisplay; 385 378 tc_cfg.sync_threshold_start = DEFAULT_TEARCHECK_SYNC_THRESH_START; 386 379 tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE; ··· 581 580 atomic_read(&phys_enc->pending_kickoff_cnt)); 582 581 } 583 582 583 + static bool dpu_encoder_phys_cmd_is_ongoing_pptx( 584 + struct dpu_encoder_phys *phys_enc) 585 + { 586 + struct dpu_hw_pp_vsync_info info; 587 + 588 + if (!phys_enc) 589 + return false; 590 + 591 + phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info); 592 + if (info.wr_ptr_line_count > 0 && 593 + info.wr_ptr_line_count < phys_enc->cached_mode.vdisplay) 594 + return true; 595 + 596 + return false; 597 + } 598 + 599 + static void dpu_encoder_phys_cmd_prepare_commit( 600 + struct dpu_encoder_phys *phys_enc) 601 + { 602 + struct dpu_encoder_phys_cmd *cmd_enc = 603 + to_dpu_encoder_phys_cmd(phys_enc); 604 + int trial = 0; 605 + 606 + if (!phys_enc) 607 + return; 608 + if (!phys_enc->hw_pp) 609 + return; 610 + if (!dpu_encoder_phys_cmd_is_master(phys_enc)) 611 + return; 612 + 613 + /* If autorefresh is already disabled, we have nothing to do */ 614 + if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL)) 615 + return; 616 + 617 + /* 618 + * If autorefresh is enabled, disable it and make sure it is safe to 619 + * proceed with current frame commit/push. Sequence fallowed is, 620 + * 1. Disable TE 621 + * 2. Disable autorefresh config 622 + * 4. Poll for frame transfer ongoing to be false 623 + * 5. Enable TE back 624 + */ 625 + _dpu_encoder_phys_cmd_connect_te(phys_enc, false); 626 + phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false); 627 + 628 + do { 629 + udelay(DPU_ENC_MAX_POLL_TIMEOUT_US); 630 + if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US) 631 + > (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) { 632 + DPU_ERROR_CMDENC(cmd_enc, 633 + "disable autorefresh failed\n"); 634 + break; 635 + } 636 + 637 + trial++; 638 + } while (dpu_encoder_phys_cmd_is_ongoing_pptx(phys_enc)); 639 + 640 + _dpu_encoder_phys_cmd_connect_te(phys_enc, true); 641 + 642 + DPU_DEBUG_CMDENC(to_dpu_encoder_phys_cmd(phys_enc), 643 + "disabled autorefresh\n"); 644 + } 645 + 584 646 static int _dpu_encoder_phys_cmd_wait_for_ctl_start( 585 647 struct dpu_encoder_phys *phys_enc) 586 648 { ··· 685 621 static int dpu_encoder_phys_cmd_wait_for_commit_done( 686 622 struct dpu_encoder_phys *phys_enc) 687 623 { 688 - int rc = 0; 689 624 struct dpu_encoder_phys_cmd *cmd_enc; 690 625 691 626 cmd_enc = to_dpu_encoder_phys_cmd(phys_enc); 692 627 693 628 /* only required for master controller */ 694 - if (dpu_encoder_phys_cmd_is_master(phys_enc)) 695 - rc = _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc); 629 + if (!dpu_encoder_phys_cmd_is_master(phys_enc)) 630 + return 0; 696 631 697 - /* required for both controllers */ 698 - if (!rc && cmd_enc->serialize_wait4pp) 699 - dpu_encoder_phys_cmd_prepare_for_kickoff(phys_enc); 700 - 701 - return rc; 632 + return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc); 702 633 } 703 634 704 635 static int dpu_encoder_phys_cmd_wait_for_vblank( ··· 740 681 static void dpu_encoder_phys_cmd_init_ops( 741 682 struct dpu_encoder_phys_ops *ops) 742 683 { 684 + ops->prepare_commit = dpu_encoder_phys_cmd_prepare_commit; 743 685 ops->is_master = dpu_encoder_phys_cmd_is_master; 744 686 ops->mode_set = dpu_encoder_phys_cmd_mode_set; 745 687 ops->mode_fixup = dpu_encoder_phys_cmd_mode_fixup;
+61 -26
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
··· 12 12 13 13 #define VIG_MASK \ 14 14 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\ 15 - BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_QOS_8LVL) |\ 15 + BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\ 16 16 BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT)) 17 17 18 18 #define VIG_SDM845_MASK \ 19 - (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3)) 19 + (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3)) 20 20 21 21 #define VIG_SC7180_MASK \ 22 - (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED4)) 22 + (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4)) 23 + 24 + #define VIG_SM8250_MASK \ 25 + (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3LITE)) 23 26 24 27 #define DMA_SDM845_MASK \ 25 28 (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ ··· 188 185 static const struct dpu_caps sm8250_dpu_caps = { 189 186 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, 190 187 .max_mixer_blendstages = 0xb, 191 - .qseed_type = DPU_SSPP_SCALER_QSEED3, /* TODO: qseed3 lite */ 188 + .qseed_type = DPU_SSPP_SCALER_QSEED3LITE, 192 189 .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */ 193 190 .ubwc_version = DPU_HW_UBWC_VER_40, 194 191 .has_src_split = true, ··· 447 444 sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1), 448 445 }; 449 446 447 + static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 = 448 + _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3LITE); 449 + static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 = 450 + _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3LITE); 451 + static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 = 452 + _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3LITE); 453 + static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 = 454 + _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3LITE); 455 + 456 + static const struct dpu_sspp_cfg sm8250_sspp[] = { 457 + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SM8250_MASK, 458 + sm8250_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), 459 + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SM8250_MASK, 460 + sm8250_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), 461 + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SM8250_MASK, 462 + sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), 463 + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SM8250_MASK, 464 + sm8250_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), 465 + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK, 466 + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), 467 + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK, 468 + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), 469 + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK, 470 + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0), 471 + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK, 472 + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1), 473 + }; 474 + 450 475 /************************************************************* 451 476 * MIXER sub blocks config 452 477 *************************************************************/ ··· 563 532 .len = 0x90, .version = 0x40000}, 564 533 }; 565 534 566 - #define DSPP_BLK(_name, _id, _base, _sblk) \ 535 + #define DSPP_BLK(_name, _id, _base, _mask, _sblk) \ 567 536 {\ 568 537 .name = _name, .id = _id, \ 569 538 .base = _base, .len = 0x1800, \ 570 - .features = DSPP_SC7180_MASK, \ 539 + .features = _mask, \ 571 540 .sblk = _sblk \ 572 541 } 573 542 574 543 static const struct dpu_dspp_cfg sc7180_dspp[] = { 575 - DSPP_BLK("dspp_0", DSPP_0, 0x54000, &sc7180_dspp_sblk), 544 + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, 545 + &sc7180_dspp_sblk), 576 546 }; 577 547 578 548 static const struct dpu_dspp_cfg sm8150_dspp[] = { 579 - DSPP_BLK("dspp_0", DSPP_0, 0x54000, &sm8150_dspp_sblk), 580 - DSPP_BLK("dspp_1", DSPP_1, 0x56000, &sm8150_dspp_sblk), 581 - DSPP_BLK("dspp_2", DSPP_2, 0x58000, &sm8150_dspp_sblk), 582 - DSPP_BLK("dspp_3", DSPP_3, 0x5a000, &sm8150_dspp_sblk), 549 + DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_SC7180_MASK, 550 + &sm8150_dspp_sblk), 551 + DSPP_BLK("dspp_1", DSPP_1, 0x56000, DSPP_SC7180_MASK, 552 + &sm8150_dspp_sblk), 553 + DSPP_BLK("dspp_2", DSPP_2, 0x58000, DSPP_SC7180_MASK, 554 + &sm8150_dspp_sblk), 555 + DSPP_BLK("dspp_3", DSPP_3, 0x5a000, DSPP_SC7180_MASK, 556 + &sm8150_dspp_sblk), 583 557 }; 584 558 585 559 /************************************************************* ··· 660 624 /************************************************************* 661 625 * INTF sub blocks config 662 626 *************************************************************/ 663 - #define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _features) \ 627 + #define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features) \ 664 628 {\ 665 629 .name = _name, .id = _id, \ 666 630 .base = _base, .len = 0x280, \ 667 631 .features = _features, \ 668 632 .type = _type, \ 669 633 .controller_id = _ctrl_id, \ 670 - .prog_fetch_lines_worst_case = 24 \ 634 + .prog_fetch_lines_worst_case = _progfetch \ 671 635 } 672 636 673 637 static const struct dpu_intf_cfg sdm845_intf[] = { 674 - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, INTF_SDM845_MASK), 675 - INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, INTF_SDM845_MASK), 676 - INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, INTF_SDM845_MASK), 677 - INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, INTF_SDM845_MASK), 638 + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK), 639 + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK), 640 + INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SDM845_MASK), 641 + INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SDM845_MASK), 678 642 }; 679 643 680 644 static const struct dpu_intf_cfg sc7180_intf[] = { 681 - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, INTF_SC7180_MASK), 682 - INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, INTF_SC7180_MASK), 645 + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK), 646 + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK), 683 647 }; 684 648 685 649 static const struct dpu_intf_cfg sm8150_intf[] = { 686 - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, INTF_SC7180_MASK), 687 - INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, INTF_SC7180_MASK), 688 - INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, INTF_SC7180_MASK), 689 - INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, INTF_SC7180_MASK), 650 + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK), 651 + INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK), 652 + INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK), 653 + INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SC7180_MASK), 690 654 }; 691 655 692 656 /************************************************************* ··· 1005 969 .mdp = sm8250_mdp, 1006 970 .ctl_count = ARRAY_SIZE(sm8150_ctl), 1007 971 .ctl = sm8150_ctl, 1008 - /* TODO: sspp qseed version differs from 845 */ 1009 - .sspp_count = ARRAY_SIZE(sdm845_sspp), 1010 - .sspp = sdm845_sspp, 972 + .sspp_count = ARRAY_SIZE(sm8250_sspp), 973 + .sspp = sm8250_sspp, 1011 974 .mixer_count = ARRAY_SIZE(sm8150_lm), 1012 975 .mixer = sm8150_lm, 1013 976 .dspp_count = ARRAY_SIZE(sm8150_dspp),
+2
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
··· 95 95 * @DPU_SSPP_SRC Src and fetch part of the pipes, 96 96 * @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support 97 97 * @DPU_SSPP_SCALER_QSEED3, QSEED3 alogorithm support 98 + * @DPU_SSPP_SCALER_QSEED3LITE, QSEED3 Lite alogorithm support 98 99 * @DPU_SSPP_SCALER_QSEED4, QSEED4 algorithm support 99 100 * @DPU_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes 100 101 * @DPU_SSPP_CSC, Support of Color space converion ··· 115 114 DPU_SSPP_SRC = 0x1, 116 115 DPU_SSPP_SCALER_QSEED2, 117 116 DPU_SSPP_SCALER_QSEED3, 117 + DPU_SSPP_SCALER_QSEED3LITE, 118 118 DPU_SSPP_SCALER_QSEED4, 119 119 DPU_SSPP_SCALER_RGB, 120 120 DPU_SSPP_CSC,
+26
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
··· 23 23 #define PP_WR_PTR_IRQ 0x024 24 24 #define PP_OUT_LINE_COUNT 0x028 25 25 #define PP_LINE_COUNT 0x02C 26 + #define PP_AUTOREFRESH_CONFIG 0x030 26 27 27 28 #define PP_FBC_MODE 0x034 28 29 #define PP_FBC_BUDGET_CTL 0x038 ··· 119 118 (te->start_pos + te->sync_threshold_start + 1)); 120 119 121 120 return 0; 121 + } 122 + 123 + static void dpu_hw_pp_setup_autorefresh_config(struct dpu_hw_pingpong *pp, 124 + u32 frame_count, bool enable) 125 + { 126 + DPU_REG_WRITE(&pp->hw, PP_AUTOREFRESH_CONFIG, 127 + enable ? (BIT(31) | frame_count) : 0); 128 + } 129 + 130 + /* 131 + * dpu_hw_pp_get_autorefresh_config - Get autorefresh config from HW 132 + * @pp: DPU pingpong structure 133 + * @frame_count: Used to return the current frame count from hw 134 + * 135 + * Returns: True if autorefresh enabled, false if disabled. 136 + */ 137 + static bool dpu_hw_pp_get_autorefresh_config(struct dpu_hw_pingpong *pp, 138 + u32 *frame_count) 139 + { 140 + u32 val = DPU_REG_READ(&pp->hw, PP_AUTOREFRESH_CONFIG); 141 + if (frame_count != NULL) 142 + *frame_count = val & 0xffff; 143 + return !!((val & BIT(31)) >> 31); 122 144 } 123 145 124 146 static int dpu_hw_pp_poll_timeout_wr_ptr(struct dpu_hw_pingpong *pp, ··· 252 228 c->ops.enable_tearcheck = dpu_hw_pp_enable_te; 253 229 c->ops.connect_external_te = dpu_hw_pp_connect_external_te; 254 230 c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info; 231 + c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config; 232 + c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config; 255 233 c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr; 256 234 c->ops.get_line_count = dpu_hw_pp_get_line_count; 257 235
+14
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
··· 63 63 * @setup_tearcheck : program tear check values 64 64 * @enable_tearcheck : enables tear check 65 65 * @get_vsync_info : retries timing info of the panel 66 + * @setup_autorefresh : configure and enable the autorefresh config 67 + * @get_autorefresh : retrieve autorefresh config from hardware 66 68 * @setup_dither : function to program the dither hw block 67 69 * @get_line_count: obtain current vertical line counter 68 70 */ ··· 95 93 */ 96 94 int (*get_vsync_info)(struct dpu_hw_pingpong *pp, 97 95 struct dpu_hw_pp_vsync_info *info); 96 + 97 + /** 98 + * configure and enable the autorefresh config 99 + */ 100 + void (*setup_autorefresh)(struct dpu_hw_pingpong *pp, 101 + u32 frame_count, bool enable); 102 + 103 + /** 104 + * retrieve autorefresh config from hardware 105 + */ 106 + bool (*get_autorefresh)(struct dpu_hw_pingpong *pp, 107 + u32 *frame_count); 98 108 99 109 /** 100 110 * poll until write pointer transmission starts
+1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
··· 673 673 c->ops.setup_multirect = dpu_hw_sspp_setup_multirect; 674 674 675 675 if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) || 676 + test_bit(DPU_SSPP_SCALER_QSEED3LITE, &features) || 676 677 test_bit(DPU_SSPP_SCALER_QSEED4, &features)) { 677 678 c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3; 678 679 c->ops.get_scaler_ver = _dpu_hw_sspp_get_scaler3_ver;
+1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
··· 28 28 #define DPU_SSPP_SCALER ((1UL << DPU_SSPP_SCALER_RGB) | \ 29 29 (1UL << DPU_SSPP_SCALER_QSEED2) | \ 30 30 (1UL << DPU_SSPP_SCALER_QSEED3) | \ 31 + (1UL << DPU_SSPP_SCALER_QSEED3LITE) | \ 31 32 (1UL << DPU_SSPP_SCALER_QSEED4)) 32 33 33 34 /**
+70 -3
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
··· 59 59 #define QSEED3_SEP_LUT_SIZE \ 60 60 (QSEED3_LUT_SIZE * QSEED3_SEPARABLE_LUTS * sizeof(u32)) 61 61 62 + /* DPU_SCALER_QSEED3LITE */ 63 + #define QSEED3LITE_COEF_LUT_Y_SEP_BIT 4 64 + #define QSEED3LITE_COEF_LUT_UV_SEP_BIT 5 65 + #define QSEED3LITE_COEF_LUT_CTRL 0x4C 66 + #define QSEED3LITE_COEF_LUT_SWAP_BIT 0 67 + #define QSEED3LITE_DIR_FILTER_WEIGHT 0x60 68 + #define QSEED3LITE_FILTERS 2 69 + #define QSEED3LITE_SEPARABLE_LUTS 10 70 + #define QSEED3LITE_LUT_SIZE 33 71 + #define QSEED3LITE_SEP_LUT_SIZE \ 72 + (QSEED3LITE_LUT_SIZE * QSEED3LITE_SEPARABLE_LUTS * sizeof(u32)) 73 + 74 + 62 75 void dpu_reg_write(struct dpu_hw_blk_reg_map *c, 63 76 u32 reg_off, 64 77 u32 val, ··· 169 156 170 157 } 171 158 159 + static void _dpu_hw_setup_scaler3lite_lut(struct dpu_hw_blk_reg_map *c, 160 + struct dpu_hw_scaler3_cfg *scaler3_cfg, u32 offset) 161 + { 162 + int j, filter; 163 + int config_lut = 0x0; 164 + unsigned long lut_flags; 165 + u32 lut_addr, lut_offset; 166 + u32 *lut[QSEED3LITE_FILTERS] = {NULL, NULL}; 167 + static const uint32_t off_tbl[QSEED3_FILTERS] = { 0x000, 0x200 }; 168 + 169 + DPU_REG_WRITE(c, QSEED3LITE_DIR_FILTER_WEIGHT + offset, scaler3_cfg->dir_weight); 170 + 171 + if (!scaler3_cfg->sep_lut) 172 + return; 173 + 174 + lut_flags = (unsigned long) scaler3_cfg->lut_flag; 175 + if (test_bit(QSEED3_COEF_LUT_Y_SEP_BIT, &lut_flags) && 176 + (scaler3_cfg->y_rgb_sep_lut_idx < QSEED3LITE_SEPARABLE_LUTS) && 177 + (scaler3_cfg->sep_len == QSEED3LITE_SEP_LUT_SIZE)) { 178 + lut[0] = scaler3_cfg->sep_lut + 179 + scaler3_cfg->y_rgb_sep_lut_idx * QSEED3LITE_LUT_SIZE; 180 + config_lut = 1; 181 + } 182 + if (test_bit(QSEED3_COEF_LUT_UV_SEP_BIT, &lut_flags) && 183 + (scaler3_cfg->uv_sep_lut_idx < QSEED3LITE_SEPARABLE_LUTS) && 184 + (scaler3_cfg->sep_len == QSEED3LITE_SEP_LUT_SIZE)) { 185 + lut[1] = scaler3_cfg->sep_lut + 186 + scaler3_cfg->uv_sep_lut_idx * QSEED3LITE_LUT_SIZE; 187 + config_lut = 1; 188 + } 189 + 190 + if (config_lut) { 191 + for (filter = 0; filter < QSEED3LITE_FILTERS; filter++) { 192 + if (!lut[filter]) 193 + continue; 194 + lut_offset = 0; 195 + lut_addr = QSEED3_COEF_LUT + offset + off_tbl[filter]; 196 + for (j = 0; j < QSEED3LITE_LUT_SIZE; j++) { 197 + DPU_REG_WRITE(c, 198 + lut_addr, 199 + (lut[filter])[lut_offset++]); 200 + lut_addr += 4; 201 + } 202 + } 203 + } 204 + 205 + if (test_bit(QSEED3_COEF_LUT_SWAP_BIT, &lut_flags)) 206 + DPU_REG_WRITE(c, QSEED3_COEF_LUT_CTRL + offset, BIT(0)); 207 + 208 + } 209 + 172 210 static void _dpu_hw_setup_scaler3_de(struct dpu_hw_blk_reg_map *c, 173 211 struct dpu_hw_scaler3_de_cfg *de_cfg, u32 offset) 174 212 { ··· 306 242 op_mode |= BIT(8); 307 243 } 308 244 309 - if (scaler3_cfg->lut_flag) 310 - _dpu_hw_setup_scaler3_lut(c, scaler3_cfg, 311 - scaler_offset); 245 + if (scaler3_cfg->lut_flag) { 246 + if (scaler_version < 0x2004) 247 + _dpu_hw_setup_scaler3_lut(c, scaler3_cfg, scaler_offset); 248 + else 249 + _dpu_hw_setup_scaler3lite_lut(c, scaler3_cfg, scaler_offset); 250 + } 312 251 313 252 if (scaler_version == 0x1002) { 314 253 phase_init =
+3
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
··· 97 97 * @ cir_lut: pointer to circular filter LUT 98 98 * @ sep_lut: pointer to separable filter LUT 99 99 * @ de: detail enhancer configuration 100 + * @ dir_weight: Directional weight 100 101 */ 101 102 struct dpu_hw_scaler3_cfg { 102 103 u32 enable; ··· 138 137 * Detail enhancer settings 139 138 */ 140 139 struct dpu_hw_scaler3_de_cfg de; 140 + 141 + u32 dir_weight; 141 142 }; 142 143 143 144 /**
+5 -4
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c
··· 30 30 #define VBIF_XIN_HALT_CTRL0 0x0200 31 31 #define VBIF_XIN_HALT_CTRL1 0x0204 32 32 #define VBIF_XINL_QOS_RP_REMAP_000 0x0550 33 - #define VBIF_XINL_QOS_LVL_REMAP_000 0x0590 33 + #define VBIF_XINL_QOS_LVL_REMAP_000(v) (v < DPU_HW_VER_400 ? 0x570 : 0x0590) 34 34 35 35 static void dpu_hw_clear_errors(struct dpu_hw_vbif *vbif, 36 36 u32 *pnd_errors, u32 *src_errors) ··· 156 156 u32 xin_id, u32 level, u32 remap_level) 157 157 { 158 158 struct dpu_hw_blk_reg_map *c; 159 - u32 reg_val, reg_val_lvl, mask, reg_high, reg_shift; 159 + u32 reg_lvl, reg_val, reg_val_lvl, mask, reg_high, reg_shift; 160 160 161 161 if (!vbif) 162 162 return; 163 163 164 164 c = &vbif->hw; 165 165 166 + reg_lvl = VBIF_XINL_QOS_LVL_REMAP_000(c->hwversion); 166 167 reg_high = ((xin_id & 0x8) >> 3) * 4 + (level * 8); 167 168 reg_shift = (xin_id & 0x7) * 4; 168 169 169 170 reg_val = DPU_REG_READ(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high); 170 - reg_val_lvl = DPU_REG_READ(c, VBIF_XINL_QOS_LVL_REMAP_000 + reg_high); 171 + reg_val_lvl = DPU_REG_READ(c, reg_lvl + reg_high); 171 172 172 173 mask = 0x7 << reg_shift; 173 174 ··· 179 178 reg_val_lvl |= (remap_level << reg_shift) & mask; 180 179 181 180 DPU_REG_WRITE(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high, reg_val); 182 - DPU_REG_WRITE(c, VBIF_XINL_QOS_LVL_REMAP_000 + reg_high, reg_val_lvl); 181 + DPU_REG_WRITE(c, reg_lvl + reg_high, reg_val_lvl); 183 182 } 184 183 185 184 static void dpu_hw_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id)
+1 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
··· 749 749 case DRM_MODE_ENCODER_TMDS: 750 750 info.num_of_h_tiles = 1; 751 751 break; 752 - }; 752 + } 753 753 754 754 rc = dpu_encoder_setup(encoder->dev, encoder, &info); 755 755 if (rc)
+1
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
··· 1465 1465 pdpu->debugfs_root, &pdpu->debugfs_src); 1466 1466 1467 1467 if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) || 1468 + cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) || 1468 1469 cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) || 1469 1470 cfg->features & BIT(DPU_SSPP_SCALER_QSEED4)) { 1470 1471 dpu_debugfs_setup_regset32(&pdpu->debugfs_scaler,
+1 -1
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
··· 177 177 [3] = INTF_HDMI, 178 178 }, 179 179 }, 180 - .max_clk = 200000000, 180 + .max_clk = 320000000, 181 181 }; 182 182 183 183 static const struct mdp5_cfg_hw apq8084_config = {
+1 -1
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
··· 1180 1180 struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, 1181 1181 pp_done); 1182 1182 1183 - complete(&mdp5_crtc->pp_completion); 1183 + complete_all(&mdp5_crtc->pp_completion); 1184 1184 } 1185 1185 1186 1186 static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc)
-7
drivers/gpu/drm/msm/dp/dp_aux.c
··· 336 336 ssize_t ret; 337 337 int const aux_cmd_native_max = 16; 338 338 int const aux_cmd_i2c_max = 128; 339 - int const retry_count = 5; 340 339 struct dp_aux_private *aux = container_of(dp_aux, 341 340 struct dp_aux_private, dp_aux); 342 341 ··· 377 378 ret = dp_aux_cmd_fifo_tx(aux, msg); 378 379 379 380 if (ret < 0) { 380 - if (aux->native) { 381 - aux->retry_cnt++; 382 - if (!(aux->retry_cnt % retry_count)) 383 - dp_catalog_aux_update_cfg(aux->catalog); 384 - dp_catalog_aux_reset(aux->catalog); 385 - } 386 381 usleep_range(400, 500); /* at least 400us to next try */ 387 382 goto unlock_exit; 388 383 }
+24
drivers/gpu/drm/msm/dp/dp_catalog.c
··· 190 190 return 0; 191 191 } 192 192 193 + /** 194 + * dp_catalog_aux_reset() - reset AUX controller 195 + * 196 + * @aux: DP catalog structure 197 + * 198 + * return: void 199 + * 200 + * This function reset AUX controller 201 + * 202 + * NOTE: reset AUX controller will also clear any pending HPD related interrupts 203 + * 204 + */ 193 205 void dp_catalog_aux_reset(struct dp_catalog *dp_catalog) 194 206 { 195 207 u32 aux_ctrl; ··· 495 483 return 0; 496 484 } 497 485 486 + /** 487 + * dp_catalog_ctrl_reset() - reset DP controller 488 + * 489 + * @dp_catalog: DP catalog structure 490 + * 491 + * return: void 492 + * 493 + * This function reset the DP controller 494 + * 495 + * NOTE: reset DP controller will also clear any pending HPD related interrupts 496 + * 497 + */ 498 498 void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog) 499 499 { 500 500 u32 sw_reset;
+8 -7
drivers/gpu/drm/msm/dp/dp_ctrl.c
··· 631 631 632 632 tu = kzalloc(sizeof(*tu), GFP_KERNEL); 633 633 if (!tu) 634 - return 634 + return; 635 635 636 636 dp_panel_update_tu_timings(in, tu); 637 637 ··· 1158 1158 default: 1159 1159 ret = -EINVAL; 1160 1160 break; 1161 - }; 1161 + } 1162 1162 1163 1163 if (!ret) 1164 1164 DRM_DEBUG_DP("new rate=0x%x\n", ctrl->link->link_params.rate); ··· 1296 1296 * transitioned to PUSH_IDLE. In order to start transmitting 1297 1297 * a link training pattern, we have to first do soft reset. 1298 1298 */ 1299 - dp_catalog_ctrl_reset(ctrl->catalog); 1300 1299 1301 1300 ret = dp_ctrl_link_train(ctrl, cr, training_step); 1302 1301 ··· 1364 1365 return ret; 1365 1366 } 1366 1367 1367 - int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip) 1368 + int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset) 1368 1369 { 1369 1370 struct dp_ctrl_private *ctrl; 1370 1371 struct dp_io *dp_io; ··· 1380 1381 phy = dp_io->phy; 1381 1382 1382 1383 ctrl->dp_ctrl.orientation = flip; 1384 + 1385 + if (reset) 1386 + dp_catalog_ctrl_reset(ctrl->catalog); 1383 1387 1384 1388 dp_catalog_ctrl_phy_reset(ctrl->catalog); 1385 1389 phy_init(phy); ··· 1498 1496 int training_step = DP_TRAINING_NONE; 1499 1497 1500 1498 dp_ctrl_push_idle(&ctrl->dp_ctrl); 1501 - dp_catalog_ctrl_reset(ctrl->catalog); 1502 1499 1503 1500 ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; 1504 1501 ··· 1786 1785 * Set up transfer unit values and set controller state to send 1787 1786 * video. 1788 1787 */ 1788 + reinit_completion(&ctrl->video_comp); 1789 + 1789 1790 dp_ctrl_configure_source_params(ctrl); 1790 1791 1791 1792 dp_catalog_ctrl_config_msa(ctrl->catalog, 1792 1793 ctrl->link->link_params.rate, 1793 1794 ctrl->dp_ctrl.pixel_rate, dp_ctrl_use_fixed_nvid(ctrl)); 1794 - 1795 - reinit_completion(&ctrl->video_comp); 1796 1795 1797 1796 dp_ctrl_setup_tr_unit(ctrl); 1798 1797
+1 -1
drivers/gpu/drm/msm/dp/dp_ctrl.h
··· 19 19 u32 pixel_rate; 20 20 }; 21 21 22 - int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip); 22 + int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip, bool reset); 23 23 void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl); 24 24 int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl); 25 25 int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl);
+17 -7
drivers/gpu/drm/msm/dp/dp_display.c
··· 350 350 return rc; 351 351 } 352 352 353 - static void dp_display_host_init(struct dp_display_private *dp) 353 + static void dp_display_host_init(struct dp_display_private *dp, int reset) 354 354 { 355 355 bool flip = false; 356 356 ··· 365 365 dp_display_set_encoder_mode(dp); 366 366 367 367 dp_power_init(dp->power, flip); 368 - dp_ctrl_host_init(dp->ctrl, flip); 368 + dp_ctrl_host_init(dp->ctrl, flip, reset); 369 369 dp_aux_init(dp->aux); 370 370 dp->core_initialized = true; 371 371 } ··· 403 403 goto end; 404 404 } 405 405 406 - dp_display_host_init(dp); 406 + dp_display_host_init(dp, false); 407 407 408 408 /* 409 409 * set sink to normal operation mode -- D0 ··· 651 651 dp_add_event(dp, EV_DISCONNECT_PENDING_TIMEOUT, 0, DP_TIMEOUT_5_SECOND); 652 652 653 653 /* signal the disconnect event early to ensure proper teardown */ 654 - dp_display_handle_plugged_change(g_dp_display, false); 655 654 reinit_completion(&dp->audio_comp); 655 + dp_display_handle_plugged_change(g_dp_display, false); 656 656 657 657 dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK | 658 658 DP_DP_IRQ_HPD_INT_MASK, true); ··· 694 694 } 695 695 696 696 if (state == ST_CONNECT_PENDING) { 697 + /* wait until ST_CONNECTED */ 698 + dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */ 699 + mutex_unlock(&dp->event_mutex); 700 + return 0; 701 + } 702 + 703 + if (state == ST_CONNECT_PENDING || state == ST_DISCONNECT_PENDING) { 697 704 /* wait until ST_CONNECTED */ 698 705 dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */ 699 706 mutex_unlock(&dp->event_mutex); ··· 897 890 898 891 /* wait only if audio was enabled */ 899 892 if (dp_display->audio_enabled) { 893 + /* signal the disconnect event */ 894 + reinit_completion(&dp->audio_comp); 895 + dp_display_handle_plugged_change(dp_display, false); 900 896 if (!wait_for_completion_timeout(&dp->audio_comp, 901 897 HZ * 5)) 902 898 DRM_ERROR("audio comp timeout\n"); ··· 1012 1002 static void dp_display_config_hpd(struct dp_display_private *dp) 1013 1003 { 1014 1004 1015 - dp_display_host_init(dp); 1005 + dp_display_host_init(dp, true); 1016 1006 dp_catalog_ctrl_hpd_config(dp->catalog); 1017 1007 1018 1008 /* Enable interrupt first time ··· 1266 1256 dp->hpd_state = ST_DISCONNECTED; 1267 1257 1268 1258 /* turn on dp ctrl/phy */ 1269 - dp_display_host_init(dp); 1259 + dp_display_host_init(dp, true); 1270 1260 1271 1261 dp_catalog_ctrl_hpd_config(dp->catalog); 1272 1262 ··· 1449 1439 state = dp_display->hpd_state; 1450 1440 1451 1441 if (state == ST_DISPLAY_OFF) 1452 - dp_display_host_init(dp_display); 1442 + dp_display_host_init(dp_display, true); 1453 1443 1454 1444 dp_display_enable(dp_display, 0); 1455 1445
+1 -2
drivers/gpu/drm/msm/dp/dp_panel.c
··· 409 409 410 410 int dp_panel_init_panel_info(struct dp_panel *dp_panel) 411 411 { 412 - int rc = 0; 413 412 struct drm_display_mode *drm_mode; 414 413 415 414 drm_mode = &dp_panel->dp_mode.drm_mode; ··· 435 436 min_t(u32, dp_panel->dp_mode.bpp, 30)); 436 437 DRM_DEBUG_DP("updated bpp = %d\n", dp_panel->dp_mode.bpp); 437 438 438 - return rc; 439 + return 0; 439 440 } 440 441 441 442 struct dp_panel *dp_panel_get(struct dp_panel_in *in)
+1 -1
drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c
··· 139 139 .disable = dsi_20nm_phy_disable, 140 140 .init = msm_dsi_phy_init_common, 141 141 }, 142 - .io_start = { 0xfd998300, 0xfd9a0300 }, 142 + .io_start = { 0xfd998500, 0xfd9a0500 }, 143 143 .num_dsi_phy = 2, 144 144 }; 145 145
+11 -10
drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
··· 172 172 173 173 multiplier = 1 << config->frac_bits; 174 174 dec_multiple = div_u64(pll_freq * multiplier, divider); 175 - div_u64_rem(dec_multiple, multiplier, &frac); 176 - 177 - dec = div_u64(dec_multiple, multiplier); 175 + dec = div_u64_rem(dec_multiple, multiplier, &frac); 178 176 179 177 if (pll_freq <= 1900000000UL) 180 178 regs->pll_prop_gain_rate = 8; ··· 304 306 reg->frac_div_start_mid); 305 307 pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1, 306 308 reg->frac_div_start_high); 307 - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40); 309 + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1, 310 + reg->pll_lockdet_rate); 308 311 pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); 309 312 pll_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10); 310 313 pll_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS, ··· 344 345 345 346 static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) 346 347 { 348 + struct device *dev = &pll->pdev->dev; 347 349 int rc; 348 350 u32 status = 0; 349 351 u32 const delay_us = 100; ··· 357 357 delay_us, 358 358 timeout_us); 359 359 if (rc) 360 - pr_err("DSI PLL(%d) lock failed, status=0x%08x\n", 361 - pll->id, status); 360 + DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n", 361 + pll->id, status); 362 362 363 363 return rc; 364 364 } ··· 405 405 { 406 406 struct msm_dsi_pll *pll = hw_clk_to_pll(hw); 407 407 struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); 408 + struct device *dev = &pll_10nm->pdev->dev; 408 409 int rc; 409 410 410 411 dsi_pll_enable_pll_bias(pll_10nm); ··· 414 413 415 414 rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0); 416 415 if (rc) { 417 - pr_err("vco_set_rate failed, rc=%d\n", rc); 416 + DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc); 418 417 return rc; 419 418 } 420 419 ··· 431 430 /* Check for PLL lock */ 432 431 rc = dsi_pll_10nm_lock_status(pll_10nm); 433 432 if (rc) { 434 - pr_err("PLL(%d) lock failed\n", pll_10nm->id); 433 + DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->id); 435 434 goto error; 436 435 } 437 436 ··· 484 483 { 485 484 struct msm_dsi_pll *pll = hw_clk_to_pll(hw); 486 485 struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); 486 + struct dsi_pll_config *config = &pll_10nm->pll_configuration; 487 487 void __iomem *base = pll_10nm->mmio; 488 488 u64 ref_clk = pll_10nm->vco_ref_clk_rate; 489 489 u64 vco_rate = 0x0; ··· 505 503 /* 506 504 * TODO: 507 505 * 1. Assumes prescaler is disabled 508 - * 2. Multiplier is 2^18. it should be 2^(num_of_frac_bits) 509 506 */ 510 - multiplier = 1 << 18; 507 + multiplier = 1 << config->frac_bits; 511 508 pll_freq = dec * (ref_clk * 2); 512 509 tmp64 = (ref_clk * 2 * frac); 513 510 pll_freq += div_u64(tmp64, multiplier);
+2 -1
drivers/gpu/drm/msm/msm_drv.c
··· 788 788 struct drm_file *file, struct drm_gem_object *obj, 789 789 uint64_t *iova) 790 790 { 791 + struct msm_drm_private *priv = dev->dev_private; 791 792 struct msm_file_private *ctx = file->driver_priv; 792 793 793 - if (!ctx->aspace) 794 + if (!priv->gpu) 794 795 return -EINVAL; 795 796 796 797 /*
+1 -2
drivers/gpu/drm/msm/msm_gem.c
··· 987 987 /* Don't drop the pages for imported dmabuf, as they are not 988 988 * ours, just free the array we allocated: 989 989 */ 990 - if (msm_obj->pages) 991 - kvfree(msm_obj->pages); 990 + kvfree(msm_obj->pages); 992 991 993 992 put_iova_vmas(obj); 994 993
+2
drivers/gpu/drm/msm/msm_gem_submit.c
··· 198 198 submit->cmd[i].idx = submit_cmd.submit_idx; 199 199 submit->cmd[i].nr_relocs = submit_cmd.nr_relocs; 200 200 201 + userptr = u64_to_user_ptr(submit_cmd.relocs); 202 + 201 203 sz = array_size(submit_cmd.nr_relocs, 202 204 sizeof(struct drm_msm_gem_submit_reloc)); 203 205 /* check for overflow: */
+6 -2
drivers/gpu/drm/msm/msm_kms.h
··· 157 157 * from the crtc's pending_timer close to end of the frame: 158 158 */ 159 159 struct mutex commit_lock[MAX_CRTCS]; 160 + struct lock_class_key commit_lock_keys[MAX_CRTCS]; 160 161 unsigned pending_crtc_mask; 161 162 struct msm_pending_timer pending_timers[MAX_CRTCS]; 162 163 }; ··· 167 166 { 168 167 unsigned i, ret; 169 168 170 - for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++) 171 - mutex_init(&kms->commit_lock[i]); 169 + for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++) { 170 + lockdep_register_key(&kms->commit_lock_keys[i]); 171 + __mutex_init(&kms->commit_lock[i], "&kms->commit_lock[i]", 172 + &kms->commit_lock_keys[i]); 173 + } 172 174 173 175 kms->funcs = funcs; 174 176
+2 -1
drivers/gpu/drm/panel/panel-elida-kd35t133.c
··· 265 265 dsi->lanes = 1; 266 266 dsi->format = MIPI_DSI_FMT_RGB888; 267 267 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 268 - MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET; 268 + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET | 269 + MIPI_DSI_CLOCK_NON_CONTINUOUS; 269 270 270 271 drm_panel_init(&ctx->panel, &dsi->dev, &kd35t133_funcs, 271 272 DRM_MODE_CONNECTOR_DSI);
+11
drivers/gpu/drm/rockchip/rockchip_drm_vop.h
··· 17 17 18 18 #define NUM_YUV2YUV_COEFFICIENTS 12 19 19 20 + /* AFBC supports a number of configurable modes. Relevant to us is block size 21 + * (16x16 or 32x8), storage modifiers (SPARSE, SPLIT), and the YUV-like 22 + * colourspace transform (YTR). 16x16 SPARSE mode is always used. SPLIT mode 23 + * could be enabled via the hreg_block_split register, but is not currently 24 + * handled. The colourspace transform is implicitly always assumed by the 25 + * decoder, so consumers must use this transform as well. 26 + * 27 + * Failure to match modifiers will cause errors displaying AFBC buffers 28 + * produced by conformant AFBC producers, including Mesa. 29 + */ 20 30 #define ROCKCHIP_AFBC_MOD \ 21 31 DRM_FORMAT_MOD_ARM_AFBC( \ 22 32 AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE \ 33 + | AFBC_FORMAT_MOD_YTR \ 23 34 ) 24 35 25 36 enum vop_data_format {
+6 -3
drivers/gpu/drm/ttm/ttm_bo.c
··· 959 959 return ret; 960 960 /* move to the bounce domain */ 961 961 ret = ttm_bo_handle_move_mem(bo, &hop_mem, false, ctx, NULL); 962 - if (ret) 962 + if (ret) { 963 + ttm_resource_free(bo, &hop_mem); 963 964 return ret; 965 + } 964 966 return 0; 965 967 } 966 968 ··· 993 991 * stop and the driver will be called to make 994 992 * the second hop. 995 993 */ 996 - bounce: 997 994 ret = ttm_bo_mem_space(bo, placement, &mem, ctx); 998 995 if (ret) 999 996 return ret; 997 + bounce: 1000 998 ret = ttm_bo_handle_move_mem(bo, &mem, false, ctx, &hop); 1001 999 if (ret == -EMULTIHOP) { 1002 1000 ret = ttm_bo_bounce_temp_buffer(bo, &mem, ctx, &hop); 1003 1001 if (ret) 1004 - return ret; 1002 + goto out; 1005 1003 /* try and move to final place now. */ 1006 1004 goto bounce; 1007 1005 } 1006 + out: 1008 1007 if (ret) 1009 1008 ttm_resource_free(bo, &mem); 1010 1009 return ret;
+9
drivers/video/fbdev/aty/atyfb_base.c
··· 175 175 return aty_ld_le32(LCD_DATA, par); 176 176 } 177 177 } 178 + #else /* defined(CONFIG_PMAC_BACKLIGHT) || defined(CONFIG_FB_ATY_BACKLIGHT) \ 179 + defined(CONFIG_FB_ATY_GENERIC_LCD) */ 180 + void aty_st_lcd(int index, u32 val, const struct atyfb_par *par) 181 + { } 182 + 183 + u32 aty_ld_lcd(int index, const struct atyfb_par *par) 184 + { 185 + return 0; 186 + } 178 187 #endif /* defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */ 179 188 180 189 #ifdef CONFIG_FB_ATY_GENERIC_LCD
+3
include/drm/drm_file.h
··· 399 399 struct drm_pending_event *p); 400 400 void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e); 401 401 void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); 402 + void drm_send_event_timestamp_locked(struct drm_device *dev, 403 + struct drm_pending_event *e, 404 + ktime_t timestamp); 402 405 403 406 struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags); 404 407
+3
include/linux/dma-fence.h
··· 372 372 373 373 int dma_fence_signal(struct dma_fence *fence); 374 374 int dma_fence_signal_locked(struct dma_fence *fence); 375 + int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp); 376 + int dma_fence_signal_timestamp_locked(struct dma_fence *fence, 377 + ktime_t timestamp); 375 378 signed long dma_fence_default_wait(struct dma_fence *fence, 376 379 bool intr, signed long timeout); 377 380 int dma_fence_add_callback(struct dma_fence *fence,
+6 -6
include/linux/dma-heap.h
··· 16 16 17 17 /** 18 18 * struct dma_heap_ops - ops to operate on a given heap 19 - * @allocate: allocate dmabuf and return fd 19 + * @allocate: allocate dmabuf and return struct dma_buf ptr 20 20 * 21 - * allocate returns dmabuf fd on success, -errno on error. 21 + * allocate returns dmabuf on success, ERR_PTR(-errno) on error. 22 22 */ 23 23 struct dma_heap_ops { 24 - int (*allocate)(struct dma_heap *heap, 25 - unsigned long len, 26 - unsigned long fd_flags, 27 - unsigned long heap_flags); 24 + struct dma_buf *(*allocate)(struct dma_heap *heap, 25 + unsigned long len, 26 + unsigned long fd_flags, 27 + unsigned long heap_flags); 28 28 }; 29 29 30 30 /**