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

Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next

First feature request for 4.19. Highlights:
- Add initial amdgpu documentation
- Add initial GPU scheduler documention
- GPU scheduler fixes for dying processes
- Add support for the JPEG engine on VCN
- Switch CI to use powerplay by default
- EDC support for CZ
- More powerplay cleanups
- Misc DC fixes

Signed-off-by: Dave Airlie <airlied@redhat.com>

Link: https://patchwork.freedesktop.org/patch/msgid/20180621161138.3008-1-alexander.deucher@amd.com

+3718 -1580
+117
Documentation/gpu/amdgpu.rst
··· 1 + ========================= 2 + drm/amdgpu AMDgpu driver 3 + ========================= 4 + 5 + The drm/amdgpu driver supports all AMD Radeon GPUs based on the Graphics Core 6 + Next (GCN) architecture. 7 + 8 + Core Driver Infrastructure 9 + ========================== 10 + 11 + This section covers core driver infrastructure. 12 + 13 + .. _amdgpu_memory_domains: 14 + 15 + Memory Domains 16 + -------------- 17 + 18 + .. kernel-doc:: include/uapi/drm/amdgpu_drm.h 19 + :doc: memory domains 20 + 21 + Buffer Objects 22 + -------------- 23 + 24 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 25 + :doc: amdgpu_object 26 + 27 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 28 + :internal: 29 + 30 + PRIME Buffer Sharing 31 + -------------------- 32 + 33 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c 34 + :doc: PRIME Buffer Sharing 35 + 36 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c 37 + :internal: 38 + 39 + MMU Notifier 40 + ------------ 41 + 42 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 43 + :doc: MMU Notifier 44 + 45 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 46 + :internal: 47 + 48 + AMDGPU Virtual Memory 49 + --------------------- 50 + 51 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 52 + :doc: GPUVM 53 + 54 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 55 + :internal: 56 + 57 + Interrupt Handling 58 + ------------------ 59 + 60 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c 61 + :doc: Interrupt Handling 62 + 63 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c 64 + :internal: 65 + 66 + GPU Power/Thermal Controls and Monitoring 67 + ========================================= 68 + 69 + This section covers hwmon and power/thermal controls. 70 + 71 + HWMON Interfaces 72 + ---------------- 73 + 74 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 75 + :doc: hwmon 76 + 77 + GPU sysfs Power State Interfaces 78 + -------------------------------- 79 + 80 + GPU power controls are exposed via sysfs files. 81 + 82 + power_dpm_state 83 + ~~~~~~~~~~~~~~~ 84 + 85 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 86 + :doc: power_dpm_state 87 + 88 + power_dpm_force_performance_level 89 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 90 + 91 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 92 + :doc: power_dpm_force_performance_level 93 + 94 + pp_table 95 + ~~~~~~~~ 96 + 97 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 98 + :doc: pp_table 99 + 100 + pp_od_clk_voltage 101 + ~~~~~~~~~~~~~~~~~ 102 + 103 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 104 + :doc: pp_od_clk_voltage 105 + 106 + pp_dpm_sclk pp_dpm_mclk pp_dpm_pcie 107 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 + 109 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 110 + :doc: pp_dpm_sclk pp_dpm_mclk pp_dpm_pcie 111 + 112 + pp_power_profile_mode 113 + ~~~~~~~~~~~~~~~~~~~~~ 114 + 115 + .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 116 + :doc: pp_power_profile_mode 117 +
+1
Documentation/gpu/drivers.rst
··· 4 4 5 5 .. toctree:: 6 6 7 + amdgpu 7 8 i915 8 9 meson 9 10 pl111
+20
Documentation/gpu/drm-mm.rst
··· 395 395 .. kernel-doc:: drivers/gpu/drm/drm_vma_manager.c 396 396 :export: 397 397 398 + .. _prime_buffer_sharing: 399 + 398 400 PRIME Buffer Sharing 399 401 ==================== 400 402 ··· 497 495 :internal: 498 496 499 497 .. kernel-doc:: drivers/gpu/drm/drm_syncobj.c 498 + :export: 499 + 500 + GPU Scheduler 501 + ============= 502 + 503 + Overview 504 + -------- 505 + 506 + .. kernel-doc:: drivers/gpu/drm/scheduler/gpu_scheduler.c 507 + :doc: Overview 508 + 509 + Scheduler Function References 510 + ----------------------------- 511 + 512 + .. kernel-doc:: include/drm/gpu_scheduler.h 513 + :internal: 514 + 515 + .. kernel-doc:: drivers/gpu/drm/scheduler/gpu_scheduler.c 500 516 :export:
+8
drivers/gpu/drm/amd/amdgpu/ObjectID.h
··· 136 136 #define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02 137 137 #define GENERIC_OBJECT_ID_MXM_OPM 0x03 138 138 #define GENERIC_OBJECT_ID_STEREO_PIN 0x04 //This object could show up from Misc Object table, it follows ATOM_OBJECT format, and contains one ATOM_OBJECT_GPIO_CNTL_RECORD for the stereo pin 139 + #define GENERIC_OBJECT_ID_BRACKET_LAYOUT 0x05 139 140 140 141 /****************************************************/ 141 142 /* Graphics Object ENUM ID Definition */ ··· 715 714 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ 716 715 GENERIC_OBJECT_ID_STEREO_PIN << OBJECT_ID_SHIFT) 717 716 717 + #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ 718 + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ 719 + GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) 720 + 721 + #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ 722 + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ 723 + GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) 718 724 /****************************************************/ 719 725 /* Object Cap definition - Shared with BIOS */ 720 726 /****************************************************/
+2
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 968 968 struct amdgpu_irq_src eop_irq; 969 969 struct amdgpu_irq_src priv_reg_irq; 970 970 struct amdgpu_irq_src priv_inst_irq; 971 + struct amdgpu_irq_src cp_ecc_error_irq; 972 + struct amdgpu_irq_src sq_irq; 971 973 /* gfx status */ 972 974 uint32_t gfx_current_status; 973 975 /* ce ram size*/
+6 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 31 31 #include <drm/drm_syncobj.h> 32 32 #include "amdgpu.h" 33 33 #include "amdgpu_trace.h" 34 + #include "amdgpu_gmc.h" 34 35 35 36 static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, 36 37 struct drm_amdgpu_cs_chunk_fence *data, ··· 303 302 *max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us); 304 303 305 304 /* Do the same for visible VRAM if half of it is free */ 306 - if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size) { 305 + if (!amdgpu_gmc_vram_full_visible(&adev->gmc)) { 307 306 u64 total_vis_vram = adev->gmc.visible_vram_size; 308 307 u64 used_vis_vram = 309 308 amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); ··· 360 359 * to move it. Don't move anything if the threshold is zero. 361 360 */ 362 361 if (p->bytes_moved < p->bytes_moved_threshold) { 363 - if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 362 + if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && 364 363 (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) { 365 364 /* And don't move a CPU_ACCESS_REQUIRED BO to limited 366 365 * visible VRAM if we've depleted our allowance to do ··· 382 381 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); 383 382 384 383 p->bytes_moved += ctx.bytes_moved; 385 - if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 384 + if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && 386 385 amdgpu_bo_in_cpu_visible_vram(bo)) 387 386 p->bytes_moved_vis += ctx.bytes_moved; 388 387 ··· 435 434 436 435 /* Good we can try to move this BO somewhere else */ 437 436 update_bytes_moved_vis = 438 - adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 439 - amdgpu_bo_in_cpu_visible_vram(bo); 437 + !amdgpu_gmc_vram_full_visible(&adev->gmc) && 438 + amdgpu_bo_in_cpu_visible_vram(bo); 440 439 amdgpu_ttm_placement_from_domain(bo, other); 441 440 r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); 442 441 p->bytes_moved += ctx.bytes_moved;
+8 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
··· 449 449 struct amdgpu_ctx *ctx; 450 450 struct idr *idp; 451 451 uint32_t id, i; 452 + long max_wait = MAX_WAIT_SCHED_ENTITY_Q_EMPTY; 452 453 453 454 idp = &mgr->ctx_handles; 454 455 456 + mutex_lock(&mgr->lock); 455 457 idr_for_each_entry(idp, ctx, id) { 456 458 457 - if (!ctx->adev) 459 + if (!ctx->adev) { 460 + mutex_unlock(&mgr->lock); 458 461 return; 462 + } 459 463 460 464 for (i = 0; i < ctx->adev->num_rings; i++) { 461 465 462 466 if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring) 463 467 continue; 464 468 465 - if (kref_read(&ctx->refcount) == 1) 466 - drm_sched_entity_do_release(&ctx->adev->rings[i]->sched, 467 - &ctx->rings[i].entity); 468 - else 469 - DRM_ERROR("ctx %p is still alive\n", ctx); 469 + max_wait = drm_sched_entity_do_release(&ctx->adev->rings[i]->sched, 470 + &ctx->rings[i].entity, max_wait); 470 471 } 471 472 } 473 + mutex_unlock(&mgr->lock); 472 474 } 473 475 474 476 void amdgpu_ctx_mgr_entity_cleanup(struct amdgpu_ctx_mgr *mgr)
+10 -9
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 25 25 * Alex Deucher 26 26 * Jerome Glisse 27 27 */ 28 + #include <linux/power_supply.h> 28 29 #include <linux/kthread.h> 29 30 #include <linux/console.h> 30 31 #include <linux/slab.h> ··· 676 675 } 677 676 678 677 /** 679 - * amdgpu_device_gart_location - try to find GTT location 678 + * amdgpu_device_gart_location - try to find GART location 680 679 * 681 680 * @adev: amdgpu device structure holding all necessary informations 682 681 * @mc: memory controller structure holding memory informations 683 682 * 684 - * Function will place try to place GTT before or after VRAM. 683 + * Function will place try to place GART before or after VRAM. 685 684 * 686 - * If GTT size is bigger than space left then we ajust GTT size. 685 + * If GART size is bigger than space left then we ajust GART size. 687 686 * Thus function will never fails. 688 - * 689 - * FIXME: when reducing GTT size align new size on power of 2. 690 687 */ 691 688 void amdgpu_device_gart_location(struct amdgpu_device *adev, 692 689 struct amdgpu_gmc *mc) ··· 697 698 size_bf = mc->vram_start; 698 699 if (size_bf > size_af) { 699 700 if (mc->gart_size > size_bf) { 700 - dev_warn(adev->dev, "limiting GTT\n"); 701 + dev_warn(adev->dev, "limiting GART\n"); 701 702 mc->gart_size = size_bf; 702 703 } 703 704 mc->gart_start = 0; 704 705 } else { 705 706 if (mc->gart_size > size_af) { 706 - dev_warn(adev->dev, "limiting GTT\n"); 707 + dev_warn(adev->dev, "limiting GART\n"); 707 708 mc->gart_size = size_af; 708 709 } 709 710 /* VCE doesn't like it when BOs cross a 4GB segment, so align ··· 712 713 mc->gart_start = ALIGN(mc->vram_end + 1, 0x100000000ULL); 713 714 } 714 715 mc->gart_end = mc->gart_start + mc->gart_size - 1; 715 - dev_info(adev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", 716 + dev_info(adev->dev, "GART: %lluM 0x%016llX - 0x%016llX\n", 716 717 mc->gart_size >> 20, mc->gart_start, mc->gart_end); 717 718 } 718 719 ··· 1925 1926 if (adev->powerplay.pp_feature & PP_GFXOFF_MASK) 1926 1927 amdgpu_device_ip_set_powergating_state(adev, 1927 1928 AMD_IP_BLOCK_TYPE_SMC, 1928 - AMD_CG_STATE_UNGATE); 1929 + AMD_PG_STATE_UNGATE); 1929 1930 1930 1931 /* ungate SMC block first */ 1931 1932 r = amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_SMC, ··· 2291 2292 2292 2293 INIT_DELAYED_WORK(&adev->late_init_work, 2293 2294 amdgpu_device_ip_late_init_func_handler); 2295 + 2296 + adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false; 2294 2297 2295 2298 /* Registers mapping */ 2296 2299 /* TODO: block userspace mapping of io register */
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
··· 402 402 u32 tdp_adjustment; 403 403 u16 load_line_slope; 404 404 bool power_control; 405 - bool ac_power; 406 405 /* special states active */ 407 406 bool thermal_active; 408 407 bool uvd_active; ··· 438 439 struct amd_pp_display_configuration pm_display_cfg;/* set by dc */ 439 440 uint32_t smu_prv_buffer_size; 440 441 struct amdgpu_bo *smu_prv_buffer; 442 + bool ac_power; 441 443 }; 442 444 443 445 #define R600_SSTU_DFLT 0
+12
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 855 855 .runtime_idle = amdgpu_pmops_runtime_idle, 856 856 }; 857 857 858 + static int amdgpu_flush(struct file *f, fl_owner_t id) 859 + { 860 + struct drm_file *file_priv = f->private_data; 861 + struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 862 + 863 + amdgpu_ctx_mgr_entity_fini(&fpriv->ctx_mgr); 864 + 865 + return 0; 866 + } 867 + 868 + 858 869 static const struct file_operations amdgpu_driver_kms_fops = { 859 870 .owner = THIS_MODULE, 860 871 .open = drm_open, 872 + .flush = amdgpu_flush, 861 873 .release = drm_release, 862 874 .unlocked_ioctl = amdgpu_drm_ioctl, 863 875 .mmap = amdgpu_mmap,
+2 -4
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
··· 510 510 * @adev: amdgpu_device pointer 511 511 * @vm: vm to update 512 512 * @bo_va: bo_va to update 513 - * @list: validation list 514 513 * @operation: map, unmap or clear 515 514 * 516 515 * Update the bo_va directly after setting its address. Errors are not ··· 518 519 static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, 519 520 struct amdgpu_vm *vm, 520 521 struct amdgpu_bo_va *bo_va, 521 - struct list_head *list, 522 522 uint32_t operation) 523 523 { 524 524 int r; ··· 610 612 return -ENOENT; 611 613 abo = gem_to_amdgpu_bo(gobj); 612 614 tv.bo = &abo->tbo; 613 - tv.shared = false; 615 + tv.shared = !!(abo->flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID); 614 616 list_add(&tv.head, &list); 615 617 } else { 616 618 gobj = NULL; ··· 671 673 break; 672 674 } 673 675 if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && !amdgpu_vm_debug) 674 - amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va, &list, 676 + amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va, 675 677 args->operation); 676 678 677 679 error_backoff:
+15
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
··· 109 109 const struct amdgpu_gmc_funcs *gmc_funcs; 110 110 }; 111 111 112 + /** 113 + * amdgpu_gmc_vram_full_visible - Check if full VRAM is visible through the BAR 114 + * 115 + * @adev: amdgpu_device pointer 116 + * 117 + * Returns: 118 + * True if full VRAM is visible through the BAR 119 + */ 120 + static inline bool amdgpu_gmc_vram_full_visible(struct amdgpu_gmc *gmc) 121 + { 122 + WARN_ON(gmc->real_vram_size < gmc->visible_vram_size); 123 + 124 + return (gmc->real_vram_size == gmc->visible_vram_size); 125 + } 126 + 112 127 #endif
+2 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
··· 353 353 ring->funcs->type == AMDGPU_RING_TYPE_VCE || 354 354 ring->funcs->type == AMDGPU_RING_TYPE_UVD_ENC || 355 355 ring->funcs->type == AMDGPU_RING_TYPE_VCN_DEC || 356 - ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) 356 + ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC || 357 + ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) 357 358 tmo = tmo_mm; 358 359 else 359 360 tmo = tmo_gfx;
+139 -63
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
··· 25 25 * Alex Deucher 26 26 * Jerome Glisse 27 27 */ 28 + 29 + /** 30 + * DOC: Interrupt Handling 31 + * 32 + * Interrupts generated within GPU hardware raise interrupt requests that are 33 + * passed to amdgpu IRQ handler which is responsible for detecting source and 34 + * type of the interrupt and dispatching matching handlers. If handling an 35 + * interrupt requires calling kernel functions that may sleep processing is 36 + * dispatched to work handlers. 37 + * 38 + * If MSI functionality is not disabled by module parameter then MSI 39 + * support will be enabled. 40 + * 41 + * For GPU interrupt sources that may be driven by another driver, IRQ domain 42 + * support is used (with mapping between virtual and hardware IRQs). 43 + */ 44 + 28 45 #include <linux/irq.h> 29 46 #include <drm/drmP.h> 30 47 #include <drm/drm_crtc_helper.h> ··· 60 43 61 44 #define AMDGPU_WAIT_IDLE_TIMEOUT 200 62 45 63 - /* 64 - * Handle hotplug events outside the interrupt handler proper. 65 - */ 66 46 /** 67 - * amdgpu_hotplug_work_func - display hotplug work handler 47 + * amdgpu_hotplug_work_func - work handler for display hotplug event 68 48 * 69 - * @work: work struct 49 + * @work: work struct pointer 70 50 * 71 - * This is the hot plug event work handler (all asics). 72 - * The work gets scheduled from the irq handler if there 73 - * was a hot plug interrupt. It walks the connector table 74 - * and calls the hotplug handler for each one, then sends 75 - * a drm hotplug event to alert userspace. 51 + * This is the hotplug event work handler (all ASICs). 52 + * The work gets scheduled from the IRQ handler if there 53 + * was a hotplug interrupt. It walks through the connector table 54 + * and calls hotplug handler for each connector. After this, it sends 55 + * a DRM hotplug event to alert userspace. 56 + * 57 + * This design approach is required in order to defer hotplug event handling 58 + * from the IRQ handler to a work handler because hotplug handler has to use 59 + * mutexes which cannot be locked in an IRQ handler (since &mutex_lock may 60 + * sleep). 76 61 */ 77 62 static void amdgpu_hotplug_work_func(struct work_struct *work) 78 63 { ··· 93 74 } 94 75 95 76 /** 96 - * amdgpu_irq_reset_work_func - execute gpu reset 77 + * amdgpu_irq_reset_work_func - execute GPU reset 97 78 * 98 - * @work: work struct 79 + * @work: work struct pointer 99 80 * 100 - * Execute scheduled gpu reset (cayman+). 101 - * This function is called when the irq handler 102 - * thinks we need a gpu reset. 81 + * Execute scheduled GPU reset (Cayman+). 82 + * This function is called when the IRQ handler thinks we need a GPU reset. 103 83 */ 104 84 static void amdgpu_irq_reset_work_func(struct work_struct *work) 105 85 { ··· 109 91 amdgpu_device_gpu_recover(adev, NULL, false); 110 92 } 111 93 112 - /* Disable *all* interrupts */ 94 + /** 95 + * amdgpu_irq_disable_all - disable *all* interrupts 96 + * 97 + * @adev: amdgpu device pointer 98 + * 99 + * Disable all types of interrupts from all sources. 100 + */ 113 101 void amdgpu_irq_disable_all(struct amdgpu_device *adev) 114 102 { 115 103 unsigned long irqflags; ··· 147 123 } 148 124 149 125 /** 150 - * amdgpu_irq_handler - irq handler 126 + * amdgpu_irq_handler - IRQ handler 151 127 * 152 - * @int irq, void *arg: args 128 + * @irq: IRQ number (unused) 129 + * @arg: pointer to DRM device 153 130 * 154 - * This is the irq handler for the amdgpu driver (all asics). 131 + * IRQ handler for amdgpu driver (all ASICs). 132 + * 133 + * Returns: 134 + * result of handling the IRQ, as defined by &irqreturn_t 155 135 */ 156 136 irqreturn_t amdgpu_irq_handler(int irq, void *arg) 157 137 { ··· 170 142 } 171 143 172 144 /** 173 - * amdgpu_msi_ok - asic specific msi checks 145 + * amdgpu_msi_ok - check whether MSI functionality is enabled 174 146 * 175 - * @adev: amdgpu device pointer 147 + * @adev: amdgpu device pointer (unused) 176 148 * 177 - * Handles asic specific MSI checks to determine if 178 - * MSIs should be enabled on a particular chip (all asics). 179 - * Returns true if MSIs should be enabled, false if MSIs 180 - * should not be enabled. 149 + * Checks whether MSI functionality has been disabled via module parameter 150 + * (all ASICs). 151 + * 152 + * Returns: 153 + * *true* if MSIs are allowed to be enabled or *false* otherwise 181 154 */ 182 155 static bool amdgpu_msi_ok(struct amdgpu_device *adev) 183 156 { 184 - /* force MSI on */ 185 157 if (amdgpu_msi == 1) 186 158 return true; 187 159 else if (amdgpu_msi == 0) ··· 191 163 } 192 164 193 165 /** 194 - * amdgpu_irq_init - init driver interrupt info 166 + * amdgpu_irq_init - initialize interrupt handling 195 167 * 196 168 * @adev: amdgpu device pointer 197 169 * 198 - * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics). 199 - * Returns 0 for success, error for failure. 170 + * Sets up work functions for hotplug and reset interrupts, enables MSI 171 + * functionality, initializes vblank, hotplug and reset interrupt handling. 172 + * 173 + * Returns: 174 + * 0 on success or error code on failure 200 175 */ 201 176 int amdgpu_irq_init(struct amdgpu_device *adev) 202 177 { ··· 207 176 208 177 spin_lock_init(&adev->irq.lock); 209 178 210 - /* enable msi */ 179 + /* Enable MSI if not disabled by module parameter */ 211 180 adev->irq.msi_enabled = false; 212 181 213 182 if (amdgpu_msi_ok(adev)) { ··· 220 189 221 190 if (!amdgpu_device_has_dc_support(adev)) { 222 191 if (!adev->enable_virtual_display) 223 - /* Disable vblank irqs aggressively for power-saving */ 192 + /* Disable vblank IRQs aggressively for power-saving */ 224 193 /* XXX: can this be enabled for DC? */ 225 194 adev->ddev->vblank_disable_immediate = true; 226 195 ··· 228 197 if (r) 229 198 return r; 230 199 231 - /* pre DCE11 */ 200 + /* Pre-DCE11 */ 232 201 INIT_WORK(&adev->hotplug_work, 233 202 amdgpu_hotplug_work_func); 234 203 } ··· 251 220 } 252 221 253 222 /** 254 - * amdgpu_irq_fini - tear down driver interrupt info 223 + * amdgpu_irq_fini - shut down interrupt handling 255 224 * 256 225 * @adev: amdgpu device pointer 257 226 * 258 - * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics). 227 + * Tears down work functions for hotplug and reset interrupts, disables MSI 228 + * functionality, shuts down vblank, hotplug and reset interrupt handling, 229 + * turns off interrupts from all sources (all ASICs). 259 230 */ 260 231 void amdgpu_irq_fini(struct amdgpu_device *adev) 261 232 { ··· 297 264 } 298 265 299 266 /** 300 - * amdgpu_irq_add_id - register irq source 267 + * amdgpu_irq_add_id - register IRQ source 301 268 * 302 269 * @adev: amdgpu device pointer 303 - * @src_id: source id for this source 304 - * @source: irq source 270 + * @client_id: client id 271 + * @src_id: source id 272 + * @source: IRQ source pointer 305 273 * 274 + * Registers IRQ source on a client. 275 + * 276 + * Returns: 277 + * 0 on success or error code otherwise 306 278 */ 307 279 int amdgpu_irq_add_id(struct amdgpu_device *adev, 308 280 unsigned client_id, unsigned src_id, ··· 350 312 } 351 313 352 314 /** 353 - * amdgpu_irq_dispatch - dispatch irq to IP blocks 315 + * amdgpu_irq_dispatch - dispatch IRQ to IP blocks 354 316 * 355 317 * @adev: amdgpu device pointer 356 - * @entry: interrupt vector 318 + * @entry: interrupt vector pointer 357 319 * 358 - * Dispatches the irq to the different IP blocks 320 + * Dispatches IRQ to IP blocks. 359 321 */ 360 322 void amdgpu_irq_dispatch(struct amdgpu_device *adev, 361 323 struct amdgpu_iv_entry *entry) ··· 399 361 } 400 362 401 363 /** 402 - * amdgpu_irq_update - update hw interrupt state 364 + * amdgpu_irq_update - update hardware interrupt state 403 365 * 404 366 * @adev: amdgpu device pointer 405 - * @src: interrupt src you want to enable 406 - * @type: type of interrupt you want to update 367 + * @src: interrupt source pointer 368 + * @type: type of interrupt 407 369 * 408 - * Updates the interrupt state for a specific src (all asics). 370 + * Updates interrupt state for the specific source (all ASICs). 409 371 */ 410 372 int amdgpu_irq_update(struct amdgpu_device *adev, 411 373 struct amdgpu_irq_src *src, unsigned type) ··· 416 378 417 379 spin_lock_irqsave(&adev->irq.lock, irqflags); 418 380 419 - /* we need to determine after taking the lock, otherwise 381 + /* We need to determine after taking the lock, otherwise 420 382 we might disable just enabled interrupts again */ 421 383 if (amdgpu_irq_enabled(adev, src, type)) 422 384 state = AMDGPU_IRQ_STATE_ENABLE; ··· 428 390 return r; 429 391 } 430 392 393 + /** 394 + * amdgpu_irq_gpu_reset_resume_helper - update interrupt states on all sources 395 + * 396 + * @adev: amdgpu device pointer 397 + * 398 + * Updates state of all types of interrupts on all sources on resume after 399 + * reset. 400 + */ 431 401 void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev) 432 402 { 433 403 int i, j, k; ··· 459 413 * amdgpu_irq_get - enable interrupt 460 414 * 461 415 * @adev: amdgpu device pointer 462 - * @src: interrupt src you want to enable 463 - * @type: type of interrupt you want to enable 416 + * @src: interrupt source pointer 417 + * @type: type of interrupt 464 418 * 465 - * Enables the interrupt type for a specific src (all asics). 419 + * Enables specified type of interrupt on the specified source (all ASICs). 420 + * 421 + * Returns: 422 + * 0 on success or error code otherwise 466 423 */ 467 424 int amdgpu_irq_get(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 468 425 unsigned type) ··· 489 440 * amdgpu_irq_put - disable interrupt 490 441 * 491 442 * @adev: amdgpu device pointer 492 - * @src: interrupt src you want to disable 493 - * @type: type of interrupt you want to disable 443 + * @src: interrupt source pointer 444 + * @type: type of interrupt 494 445 * 495 - * Disables the interrupt type for a specific src (all asics). 446 + * Enables specified type of interrupt on the specified source (all ASICs). 447 + * 448 + * Returns: 449 + * 0 on success or error code otherwise 496 450 */ 497 451 int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 498 452 unsigned type) ··· 516 464 } 517 465 518 466 /** 519 - * amdgpu_irq_enabled - test if irq is enabled or not 467 + * amdgpu_irq_enabled - check whether interrupt is enabled or not 520 468 * 521 469 * @adev: amdgpu device pointer 522 - * @idx: interrupt src you want to test 470 + * @src: interrupt source pointer 471 + * @type: type of interrupt 523 472 * 524 - * Tests if the given interrupt source is enabled or not 473 + * Checks whether the given type of interrupt is enabled on the given source. 474 + * 475 + * Returns: 476 + * *true* if interrupt is enabled, *false* if interrupt is disabled or on 477 + * invalid parameters 525 478 */ 526 479 bool amdgpu_irq_enabled(struct amdgpu_device *adev, struct amdgpu_irq_src *src, 527 480 unsigned type) ··· 543 486 return !!atomic_read(&src->enabled_types[type]); 544 487 } 545 488 546 - /* gen irq */ 489 + /* XXX: Generic IRQ handling */ 547 490 static void amdgpu_irq_mask(struct irq_data *irqd) 548 491 { 549 492 /* XXX */ ··· 554 497 /* XXX */ 555 498 } 556 499 500 + /* amdgpu hardware interrupt chip descriptor */ 557 501 static struct irq_chip amdgpu_irq_chip = { 558 502 .name = "amdgpu-ih", 559 503 .irq_mask = amdgpu_irq_mask, 560 504 .irq_unmask = amdgpu_irq_unmask, 561 505 }; 562 506 507 + /** 508 + * amdgpu_irqdomain_map - create mapping between virtual and hardware IRQ numbers 509 + * 510 + * @d: amdgpu IRQ domain pointer (unused) 511 + * @irq: virtual IRQ number 512 + * @hwirq: hardware irq number 513 + * 514 + * Current implementation assigns simple interrupt handler to the given virtual 515 + * IRQ. 516 + * 517 + * Returns: 518 + * 0 on success or error code otherwise 519 + */ 563 520 static int amdgpu_irqdomain_map(struct irq_domain *d, 564 521 unsigned int irq, irq_hw_number_t hwirq) 565 522 { ··· 585 514 return 0; 586 515 } 587 516 517 + /* Implementation of methods for amdgpu IRQ domain */ 588 518 static const struct irq_domain_ops amdgpu_hw_irqdomain_ops = { 589 519 .map = amdgpu_irqdomain_map, 590 520 }; 591 521 592 522 /** 593 - * amdgpu_irq_add_domain - create a linear irq domain 523 + * amdgpu_irq_add_domain - create a linear IRQ domain 594 524 * 595 525 * @adev: amdgpu device pointer 596 526 * 597 - * Create an irq domain for GPU interrupt sources 527 + * Creates an IRQ domain for GPU interrupt sources 598 528 * that may be driven by another driver (e.g., ACP). 529 + * 530 + * Returns: 531 + * 0 on success or error code otherwise 599 532 */ 600 533 int amdgpu_irq_add_domain(struct amdgpu_device *adev) 601 534 { ··· 614 539 } 615 540 616 541 /** 617 - * amdgpu_irq_remove_domain - remove the irq domain 542 + * amdgpu_irq_remove_domain - remove the IRQ domain 618 543 * 619 544 * @adev: amdgpu device pointer 620 545 * 621 - * Remove the irq domain for GPU interrupt sources 546 + * Removes the IRQ domain for GPU interrupt sources 622 547 * that may be driven by another driver (e.g., ACP). 623 548 */ 624 549 void amdgpu_irq_remove_domain(struct amdgpu_device *adev) ··· 630 555 } 631 556 632 557 /** 633 - * amdgpu_irq_create_mapping - create a mapping between a domain irq and a 634 - * Linux irq 558 + * amdgpu_irq_create_mapping - create mapping between domain Linux IRQs 635 559 * 636 560 * @adev: amdgpu device pointer 637 561 * @src_id: IH source id 638 562 * 639 - * Create a mapping between a domain irq (GPU IH src id) and a Linux irq 563 + * Creates mapping between a domain IRQ (GPU IH src id) and a Linux IRQ 640 564 * Use this for components that generate a GPU interrupt, but are driven 641 565 * by a different driver (e.g., ACP). 642 - * Returns the Linux irq. 566 + * 567 + * Returns: 568 + * Linux IRQ 643 569 */ 644 570 unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned src_id) 645 571 {
+20 -14
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
··· 329 329 type = AMD_IP_BLOCK_TYPE_GFX; 330 330 for (i = 0; i < adev->gfx.num_gfx_rings; i++) 331 331 ring_mask |= ((adev->gfx.gfx_ring[i].ready ? 1 : 0) << i); 332 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 333 - ib_size_alignment = 8; 332 + ib_start_alignment = 32; 333 + ib_size_alignment = 32; 334 334 break; 335 335 case AMDGPU_HW_IP_COMPUTE: 336 336 type = AMD_IP_BLOCK_TYPE_GFX; 337 337 for (i = 0; i < adev->gfx.num_compute_rings; i++) 338 338 ring_mask |= ((adev->gfx.compute_ring[i].ready ? 1 : 0) << i); 339 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 340 - ib_size_alignment = 8; 339 + ib_start_alignment = 32; 340 + ib_size_alignment = 32; 341 341 break; 342 342 case AMDGPU_HW_IP_DMA: 343 343 type = AMD_IP_BLOCK_TYPE_SDMA; 344 344 for (i = 0; i < adev->sdma.num_instances; i++) 345 345 ring_mask |= ((adev->sdma.instance[i].ring.ready ? 1 : 0) << i); 346 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 347 - ib_size_alignment = 1; 346 + ib_start_alignment = 256; 347 + ib_size_alignment = 4; 348 348 break; 349 349 case AMDGPU_HW_IP_UVD: 350 350 type = AMD_IP_BLOCK_TYPE_UVD; 351 351 for (i = 0; i < adev->uvd.num_uvd_inst; i++) 352 352 ring_mask |= ((adev->uvd.inst[i].ring.ready ? 1 : 0) << i); 353 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 354 - ib_size_alignment = 16; 353 + ib_start_alignment = 64; 354 + ib_size_alignment = 64; 355 355 break; 356 356 case AMDGPU_HW_IP_VCE: 357 357 type = AMD_IP_BLOCK_TYPE_VCE; 358 358 for (i = 0; i < adev->vce.num_rings; i++) 359 359 ring_mask |= ((adev->vce.ring[i].ready ? 1 : 0) << i); 360 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 360 + ib_start_alignment = 4; 361 361 ib_size_alignment = 1; 362 362 break; 363 363 case AMDGPU_HW_IP_UVD_ENC: ··· 367 367 ring_mask |= 368 368 ((adev->uvd.inst[i].ring_enc[j].ready ? 1 : 0) << 369 369 (j + i * adev->uvd.num_enc_rings)); 370 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 371 - ib_size_alignment = 1; 370 + ib_start_alignment = 64; 371 + ib_size_alignment = 64; 372 372 break; 373 373 case AMDGPU_HW_IP_VCN_DEC: 374 374 type = AMD_IP_BLOCK_TYPE_VCN; 375 375 ring_mask = adev->vcn.ring_dec.ready ? 1 : 0; 376 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 376 + ib_start_alignment = 16; 377 377 ib_size_alignment = 16; 378 378 break; 379 379 case AMDGPU_HW_IP_VCN_ENC: 380 380 type = AMD_IP_BLOCK_TYPE_VCN; 381 381 for (i = 0; i < adev->vcn.num_enc_rings; i++) 382 382 ring_mask |= ((adev->vcn.ring_enc[i].ready ? 1 : 0) << i); 383 - ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; 383 + ib_start_alignment = 64; 384 384 ib_size_alignment = 1; 385 + break; 386 + case AMDGPU_HW_IP_VCN_JPEG: 387 + type = AMD_IP_BLOCK_TYPE_VCN; 388 + ring_mask = adev->vcn.ring_jpeg.ready ? 1 : 0; 389 + ib_start_alignment = 16; 390 + ib_size_alignment = 16; 385 391 break; 386 392 default: 387 393 return -EINVAL; ··· 433 427 break; 434 428 case AMDGPU_HW_IP_VCN_DEC: 435 429 case AMDGPU_HW_IP_VCN_ENC: 430 + case AMDGPU_HW_IP_VCN_JPEG: 436 431 type = AMD_IP_BLOCK_TYPE_VCN; 437 432 break; 438 433 default: ··· 937 930 return; 938 931 939 932 pm_runtime_get_sync(dev->dev); 940 - amdgpu_ctx_mgr_entity_fini(&fpriv->ctx_mgr); 941 933 942 934 if (adev->asic_type != CHIP_RAVEN) { 943 935 amdgpu_uvd_free_handles(adev, file_priv);
+123 -81
drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
··· 28 28 * Christian König <christian.koenig@amd.com> 29 29 */ 30 30 31 + /** 32 + * DOC: MMU Notifier 33 + * 34 + * For coherent userptr handling registers an MMU notifier to inform the driver 35 + * about updates on the page tables of a process. 36 + * 37 + * When somebody tries to invalidate the page tables we block the update until 38 + * all operations on the pages in question are completed, then those pages are 39 + * marked as accessed and also dirty if it wasn't a read only access. 40 + * 41 + * New command submissions using the userptrs in question are delayed until all 42 + * page table invalidation are completed and we once more see a coherent process 43 + * address space. 44 + */ 45 + 31 46 #include <linux/firmware.h> 32 47 #include <linux/module.h> 33 48 #include <linux/mmu_notifier.h> ··· 53 38 #include "amdgpu.h" 54 39 #include "amdgpu_amdkfd.h" 55 40 41 + /** 42 + * struct amdgpu_mn 43 + * 44 + * @adev: amdgpu device pointer 45 + * @mm: process address space 46 + * @mn: MMU notifier structur 47 + * @work: destruction work item 48 + * @node: hash table node to find structure by adev and mn 49 + * @lock: rw semaphore protecting the notifier nodes 50 + * @objects: interval tree containing amdgpu_mn_nodes 51 + * @read_lock: mutex for recursive locking of @lock 52 + * @recursion: depth of recursion 53 + * 54 + * Data for each amdgpu device and process address space. 55 + */ 56 56 struct amdgpu_mn { 57 57 /* constant after initialisation */ 58 58 struct amdgpu_device *adev; ··· 88 58 atomic_t recursion; 89 59 }; 90 60 61 + /** 62 + * struct amdgpu_mn_node 63 + * 64 + * @it: interval node defining start-last of the affected address range 65 + * @bos: list of all BOs in the affected address range 66 + * 67 + * Manages all BOs which are affected of a certain range of address space. 68 + */ 91 69 struct amdgpu_mn_node { 92 70 struct interval_tree_node it; 93 71 struct list_head bos; 94 72 }; 95 73 96 74 /** 97 - * amdgpu_mn_destroy - destroy the rmn 75 + * amdgpu_mn_destroy - destroy the MMU notifier 98 76 * 99 77 * @work: previously sheduled work item 100 78 * ··· 110 72 */ 111 73 static void amdgpu_mn_destroy(struct work_struct *work) 112 74 { 113 - struct amdgpu_mn *rmn = container_of(work, struct amdgpu_mn, work); 114 - struct amdgpu_device *adev = rmn->adev; 75 + struct amdgpu_mn *amn = container_of(work, struct amdgpu_mn, work); 76 + struct amdgpu_device *adev = amn->adev; 115 77 struct amdgpu_mn_node *node, *next_node; 116 78 struct amdgpu_bo *bo, *next_bo; 117 79 118 80 mutex_lock(&adev->mn_lock); 119 - down_write(&rmn->lock); 120 - hash_del(&rmn->node); 81 + down_write(&amn->lock); 82 + hash_del(&amn->node); 121 83 rbtree_postorder_for_each_entry_safe(node, next_node, 122 - &rmn->objects.rb_root, it.rb) { 84 + &amn->objects.rb_root, it.rb) { 123 85 list_for_each_entry_safe(bo, next_bo, &node->bos, mn_list) { 124 86 bo->mn = NULL; 125 87 list_del_init(&bo->mn_list); 126 88 } 127 89 kfree(node); 128 90 } 129 - up_write(&rmn->lock); 91 + up_write(&amn->lock); 130 92 mutex_unlock(&adev->mn_lock); 131 - mmu_notifier_unregister_no_release(&rmn->mn, rmn->mm); 132 - kfree(rmn); 93 + mmu_notifier_unregister_no_release(&amn->mn, amn->mm); 94 + kfree(amn); 133 95 } 134 96 135 97 /** 136 98 * amdgpu_mn_release - callback to notify about mm destruction 137 99 * 138 100 * @mn: our notifier 139 - * @mn: the mm this callback is about 101 + * @mm: the mm this callback is about 140 102 * 141 103 * Shedule a work item to lazy destroy our notifier. 142 104 */ 143 105 static void amdgpu_mn_release(struct mmu_notifier *mn, 144 106 struct mm_struct *mm) 145 107 { 146 - struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn); 147 - INIT_WORK(&rmn->work, amdgpu_mn_destroy); 148 - schedule_work(&rmn->work); 108 + struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); 109 + 110 + INIT_WORK(&amn->work, amdgpu_mn_destroy); 111 + schedule_work(&amn->work); 149 112 } 150 113 151 114 152 115 /** 153 - * amdgpu_mn_lock - take the write side lock for this mn 116 + * amdgpu_mn_lock - take the write side lock for this notifier 117 + * 118 + * @mn: our notifier 154 119 */ 155 120 void amdgpu_mn_lock(struct amdgpu_mn *mn) 156 121 { ··· 162 121 } 163 122 164 123 /** 165 - * amdgpu_mn_unlock - drop the write side lock for this mn 124 + * amdgpu_mn_unlock - drop the write side lock for this notifier 125 + * 126 + * @mn: our notifier 166 127 */ 167 128 void amdgpu_mn_unlock(struct amdgpu_mn *mn) 168 129 { ··· 173 130 } 174 131 175 132 /** 176 - * amdgpu_mn_read_lock - take the rmn read lock 133 + * amdgpu_mn_read_lock - take the read side lock for this notifier 177 134 * 178 - * @rmn: our notifier 179 - * 180 - * Take the rmn read side lock. 135 + * @amn: our notifier 181 136 */ 182 - static void amdgpu_mn_read_lock(struct amdgpu_mn *rmn) 137 + static void amdgpu_mn_read_lock(struct amdgpu_mn *amn) 183 138 { 184 - mutex_lock(&rmn->read_lock); 185 - if (atomic_inc_return(&rmn->recursion) == 1) 186 - down_read_non_owner(&rmn->lock); 187 - mutex_unlock(&rmn->read_lock); 139 + mutex_lock(&amn->read_lock); 140 + if (atomic_inc_return(&amn->recursion) == 1) 141 + down_read_non_owner(&amn->lock); 142 + mutex_unlock(&amn->read_lock); 188 143 } 189 144 190 145 /** 191 - * amdgpu_mn_read_unlock - drop the rmn read lock 146 + * amdgpu_mn_read_unlock - drop the read side lock for this notifier 192 147 * 193 - * @rmn: our notifier 194 - * 195 - * Drop the rmn read side lock. 148 + * @amn: our notifier 196 149 */ 197 - static void amdgpu_mn_read_unlock(struct amdgpu_mn *rmn) 150 + static void amdgpu_mn_read_unlock(struct amdgpu_mn *amn) 198 151 { 199 - if (atomic_dec_return(&rmn->recursion) == 0) 200 - up_read_non_owner(&rmn->lock); 152 + if (atomic_dec_return(&amn->recursion) == 0) 153 + up_read_non_owner(&amn->lock); 201 154 } 202 155 203 156 /** 204 157 * amdgpu_mn_invalidate_node - unmap all BOs of a node 205 158 * 206 159 * @node: the node with the BOs to unmap 160 + * @start: start of address range affected 161 + * @end: end of address range affected 207 162 * 208 - * We block for all BOs and unmap them by move them 209 - * into system domain again. 163 + * Block for operations on BOs to finish and mark pages as accessed and 164 + * potentially dirty. 210 165 */ 211 166 static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node, 212 167 unsigned long start, ··· 231 190 * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change 232 191 * 233 192 * @mn: our notifier 234 - * @mn: the mm this callback is about 193 + * @mm: the mm this callback is about 235 194 * @start: start of updated range 236 195 * @end: end of updated range 237 196 * 238 - * We block for all BOs between start and end to be idle and 239 - * unmap them by move them into system domain again. 197 + * Block for operations on BOs to finish and mark pages as accessed and 198 + * potentially dirty. 240 199 */ 241 200 static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn, 242 201 struct mm_struct *mm, 243 202 unsigned long start, 244 203 unsigned long end) 245 204 { 246 - struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn); 205 + struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); 247 206 struct interval_tree_node *it; 248 207 249 208 /* notification is exclusive, but interval is inclusive */ 250 209 end -= 1; 251 210 252 - amdgpu_mn_read_lock(rmn); 211 + amdgpu_mn_read_lock(amn); 253 212 254 - it = interval_tree_iter_first(&rmn->objects, start, end); 213 + it = interval_tree_iter_first(&amn->objects, start, end); 255 214 while (it) { 256 215 struct amdgpu_mn_node *node; 257 216 ··· 279 238 unsigned long start, 280 239 unsigned long end) 281 240 { 282 - struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn); 241 + struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); 283 242 struct interval_tree_node *it; 284 243 285 244 /* notification is exclusive, but interval is inclusive */ 286 245 end -= 1; 287 246 288 - amdgpu_mn_read_lock(rmn); 247 + amdgpu_mn_read_lock(amn); 289 248 290 - it = interval_tree_iter_first(&rmn->objects, start, end); 249 + it = interval_tree_iter_first(&amn->objects, start, end); 291 250 while (it) { 292 251 struct amdgpu_mn_node *node; 293 252 struct amdgpu_bo *bo; ··· 309 268 * amdgpu_mn_invalidate_range_end - callback to notify about mm change 310 269 * 311 270 * @mn: our notifier 312 - * @mn: the mm this callback is about 271 + * @mm: the mm this callback is about 313 272 * @start: start of updated range 314 273 * @end: end of updated range 315 274 * ··· 320 279 unsigned long start, 321 280 unsigned long end) 322 281 { 323 - struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn); 282 + struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); 324 283 325 - amdgpu_mn_read_unlock(rmn); 284 + amdgpu_mn_read_unlock(amn); 326 285 } 327 286 328 287 static const struct mmu_notifier_ops amdgpu_mn_ops[] = { ··· 356 315 enum amdgpu_mn_type type) 357 316 { 358 317 struct mm_struct *mm = current->mm; 359 - struct amdgpu_mn *rmn; 318 + struct amdgpu_mn *amn; 360 319 unsigned long key = AMDGPU_MN_KEY(mm, type); 361 320 int r; 362 321 ··· 366 325 return ERR_PTR(-EINTR); 367 326 } 368 327 369 - hash_for_each_possible(adev->mn_hash, rmn, node, key) 370 - if (AMDGPU_MN_KEY(rmn->mm, rmn->type) == key) 328 + hash_for_each_possible(adev->mn_hash, amn, node, key) 329 + if (AMDGPU_MN_KEY(amn->mm, amn->type) == key) 371 330 goto release_locks; 372 331 373 - rmn = kzalloc(sizeof(*rmn), GFP_KERNEL); 374 - if (!rmn) { 375 - rmn = ERR_PTR(-ENOMEM); 332 + amn = kzalloc(sizeof(*amn), GFP_KERNEL); 333 + if (!amn) { 334 + amn = ERR_PTR(-ENOMEM); 376 335 goto release_locks; 377 336 } 378 337 379 - rmn->adev = adev; 380 - rmn->mm = mm; 381 - init_rwsem(&rmn->lock); 382 - rmn->type = type; 383 - rmn->mn.ops = &amdgpu_mn_ops[type]; 384 - rmn->objects = RB_ROOT_CACHED; 385 - mutex_init(&rmn->read_lock); 386 - atomic_set(&rmn->recursion, 0); 338 + amn->adev = adev; 339 + amn->mm = mm; 340 + init_rwsem(&amn->lock); 341 + amn->type = type; 342 + amn->mn.ops = &amdgpu_mn_ops[type]; 343 + amn->objects = RB_ROOT_CACHED; 344 + mutex_init(&amn->read_lock); 345 + atomic_set(&amn->recursion, 0); 387 346 388 - r = __mmu_notifier_register(&rmn->mn, mm); 347 + r = __mmu_notifier_register(&amn->mn, mm); 389 348 if (r) 390 - goto free_rmn; 349 + goto free_amn; 391 350 392 - hash_add(adev->mn_hash, &rmn->node, AMDGPU_MN_KEY(mm, type)); 351 + hash_add(adev->mn_hash, &amn->node, AMDGPU_MN_KEY(mm, type)); 393 352 394 353 release_locks: 395 354 up_write(&mm->mmap_sem); 396 355 mutex_unlock(&adev->mn_lock); 397 356 398 - return rmn; 357 + return amn; 399 358 400 - free_rmn: 359 + free_amn: 401 360 up_write(&mm->mmap_sem); 402 361 mutex_unlock(&adev->mn_lock); 403 - kfree(rmn); 362 + kfree(amn); 404 363 405 364 return ERR_PTR(r); 406 365 } ··· 420 379 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 421 380 enum amdgpu_mn_type type = 422 381 bo->kfd_bo ? AMDGPU_MN_TYPE_HSA : AMDGPU_MN_TYPE_GFX; 423 - struct amdgpu_mn *rmn; 382 + struct amdgpu_mn *amn; 424 383 struct amdgpu_mn_node *node = NULL, *new_node; 425 384 struct list_head bos; 426 385 struct interval_tree_node *it; 427 386 428 - rmn = amdgpu_mn_get(adev, type); 429 - if (IS_ERR(rmn)) 430 - return PTR_ERR(rmn); 387 + amn = amdgpu_mn_get(adev, type); 388 + if (IS_ERR(amn)) 389 + return PTR_ERR(amn); 431 390 432 391 new_node = kmalloc(sizeof(*new_node), GFP_KERNEL); 433 392 if (!new_node) ··· 435 394 436 395 INIT_LIST_HEAD(&bos); 437 396 438 - down_write(&rmn->lock); 397 + down_write(&amn->lock); 439 398 440 - while ((it = interval_tree_iter_first(&rmn->objects, addr, end))) { 399 + while ((it = interval_tree_iter_first(&amn->objects, addr, end))) { 441 400 kfree(node); 442 401 node = container_of(it, struct amdgpu_mn_node, it); 443 - interval_tree_remove(&node->it, &rmn->objects); 402 + interval_tree_remove(&node->it, &amn->objects); 444 403 addr = min(it->start, addr); 445 404 end = max(it->last, end); 446 405 list_splice(&node->bos, &bos); ··· 451 410 else 452 411 kfree(new_node); 453 412 454 - bo->mn = rmn; 413 + bo->mn = amn; 455 414 456 415 node->it.start = addr; 457 416 node->it.last = end; ··· 459 418 list_splice(&bos, &node->bos); 460 419 list_add(&bo->mn_list, &node->bos); 461 420 462 - interval_tree_insert(&node->it, &rmn->objects); 421 + interval_tree_insert(&node->it, &amn->objects); 463 422 464 - up_write(&rmn->lock); 423 + up_write(&amn->lock); 465 424 466 425 return 0; 467 426 } ··· 476 435 void amdgpu_mn_unregister(struct amdgpu_bo *bo) 477 436 { 478 437 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 479 - struct amdgpu_mn *rmn; 438 + struct amdgpu_mn *amn; 480 439 struct list_head *head; 481 440 482 441 mutex_lock(&adev->mn_lock); 483 442 484 - rmn = bo->mn; 485 - if (rmn == NULL) { 443 + amn = bo->mn; 444 + if (amn == NULL) { 486 445 mutex_unlock(&adev->mn_lock); 487 446 return; 488 447 } 489 448 490 - down_write(&rmn->lock); 449 + down_write(&amn->lock); 491 450 492 451 /* save the next list entry for later */ 493 452 head = bo->mn_list.next; ··· 497 456 498 457 if (list_empty(head)) { 499 458 struct amdgpu_mn_node *node; 459 + 500 460 node = container_of(head, struct amdgpu_mn_node, bos); 501 - interval_tree_remove(&node->it, &rmn->objects); 461 + interval_tree_remove(&node->it, &amn->objects); 502 462 kfree(node); 503 463 } 504 464 505 - up_write(&rmn->lock); 465 + up_write(&amn->lock); 506 466 mutex_unlock(&adev->mn_lock); 507 467 } 508 468
+306 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
··· 38 38 #include "amdgpu_trace.h" 39 39 #include "amdgpu_amdkfd.h" 40 40 41 + /** 42 + * DOC: amdgpu_object 43 + * 44 + * This defines the interfaces to operate on an &amdgpu_bo buffer object which 45 + * represents memory used by driver (VRAM, system memory, etc.). The driver 46 + * provides DRM/GEM APIs to userspace. DRM/GEM APIs then use these interfaces 47 + * to create/destroy/set buffer object which are then managed by the kernel TTM 48 + * memory manager. 49 + * The interfaces are also used internally by kernel clients, including gfx, 50 + * uvd, etc. for kernel managed allocations used by the GPU. 51 + * 52 + */ 53 + 41 54 static bool amdgpu_need_backup(struct amdgpu_device *adev) 42 55 { 43 56 if (adev->flags & AMD_IS_APU) ··· 86 73 kfree(bo); 87 74 } 88 75 76 + /** 77 + * amdgpu_ttm_bo_is_amdgpu_bo - check if the buffer object is an &amdgpu_bo 78 + * @bo: buffer object to be checked 79 + * 80 + * Uses destroy function associated with the object to determine if this is 81 + * an &amdgpu_bo. 82 + * 83 + * Returns: 84 + * true if the object belongs to &amdgpu_bo, false if not. 85 + */ 89 86 bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo) 90 87 { 91 88 if (bo->destroy == &amdgpu_ttm_bo_destroy) ··· 103 80 return false; 104 81 } 105 82 83 + /** 84 + * amdgpu_ttm_placement_from_domain - set buffer's placement 85 + * @abo: &amdgpu_bo buffer object whose placement is to be set 86 + * @domain: requested domain 87 + * 88 + * Sets buffer's placement according to requested domain and the buffer's 89 + * flags. 90 + */ 106 91 void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain) 107 92 { 108 93 struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); ··· 215 184 * 216 185 * Note: For bo_ptr new BO is only created if bo_ptr points to NULL. 217 186 * 218 - * Returns 0 on success, negative error code otherwise. 187 + * Returns: 188 + * 0 on success, negative error code otherwise. 219 189 */ 220 190 int amdgpu_bo_create_reserved(struct amdgpu_device *adev, 221 191 unsigned long size, int align, ··· 293 261 * 294 262 * Note: For bo_ptr new BO is only created if bo_ptr points to NULL. 295 263 * 296 - * Returns 0 on success, negative error code otherwise. 264 + * Returns: 265 + * 0 on success, negative error code otherwise. 297 266 */ 298 267 int amdgpu_bo_create_kernel(struct amdgpu_device *adev, 299 268 unsigned long size, int align, ··· 318 285 * amdgpu_bo_free_kernel - free BO for kernel use 319 286 * 320 287 * @bo: amdgpu BO to free 288 + * @gpu_addr: pointer to where the BO's GPU memory space address was stored 289 + * @cpu_addr: pointer to where the BO's CPU memory space address was stored 321 290 * 322 291 * unmaps and unpin a BO for kernel internal use. 323 292 */ ··· 463 428 if (unlikely(r != 0)) 464 429 return r; 465 430 466 - if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 431 + if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && 467 432 bo->tbo.mem.mem_type == TTM_PL_VRAM && 468 433 bo->tbo.mem.start < adev->gmc.visible_vram_size >> PAGE_SHIFT) 469 434 amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, ··· 533 498 return r; 534 499 } 535 500 501 + /** 502 + * amdgpu_bo_create - create an &amdgpu_bo buffer object 503 + * @adev: amdgpu device object 504 + * @bp: parameters to be used for the buffer object 505 + * @bo_ptr: pointer to the buffer object pointer 506 + * 507 + * Creates an &amdgpu_bo buffer object; and if requested, also creates a 508 + * shadow object. 509 + * Shadow object is used to backup the original buffer object, and is always 510 + * in GTT. 511 + * 512 + * Returns: 513 + * 0 for success or a negative error code on failure. 514 + */ 536 515 int amdgpu_bo_create(struct amdgpu_device *adev, 537 516 struct amdgpu_bo_param *bp, 538 517 struct amdgpu_bo **bo_ptr) ··· 576 527 return r; 577 528 } 578 529 530 + /** 531 + * amdgpu_bo_backup_to_shadow - Backs up an &amdgpu_bo buffer object 532 + * @adev: amdgpu device object 533 + * @ring: amdgpu_ring for the engine handling the buffer operations 534 + * @bo: &amdgpu_bo buffer to be backed up 535 + * @resv: reservation object with embedded fence 536 + * @fence: dma_fence associated with the operation 537 + * @direct: whether to submit the job directly 538 + * 539 + * Copies an &amdgpu_bo buffer object to its shadow object. 540 + * Not used for now. 541 + * 542 + * Returns: 543 + * 0 for success or a negative error code on failure. 544 + */ 579 545 int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev, 580 546 struct amdgpu_ring *ring, 581 547 struct amdgpu_bo *bo, ··· 623 559 return r; 624 560 } 625 561 562 + /** 563 + * amdgpu_bo_validate - validate an &amdgpu_bo buffer object 564 + * @bo: pointer to the buffer object 565 + * 566 + * Sets placement according to domain; and changes placement and caching 567 + * policy of the buffer object according to the placement. 568 + * This is used for validating shadow bos. It calls ttm_bo_validate() to 569 + * make sure the buffer is resident where it needs to be. 570 + * 571 + * Returns: 572 + * 0 for success or a negative error code on failure. 573 + */ 626 574 int amdgpu_bo_validate(struct amdgpu_bo *bo) 627 575 { 628 576 struct ttm_operation_ctx ctx = { false, false }; ··· 657 581 return r; 658 582 } 659 583 584 + /** 585 + * amdgpu_bo_restore_from_shadow - restore an &amdgpu_bo buffer object 586 + * @adev: amdgpu device object 587 + * @ring: amdgpu_ring for the engine handling the buffer operations 588 + * @bo: &amdgpu_bo buffer to be restored 589 + * @resv: reservation object with embedded fence 590 + * @fence: dma_fence associated with the operation 591 + * @direct: whether to submit the job directly 592 + * 593 + * Copies a buffer object's shadow content back to the object. 594 + * This is used for recovering a buffer from its shadow in case of a gpu 595 + * reset where vram context may be lost. 596 + * 597 + * Returns: 598 + * 0 for success or a negative error code on failure. 599 + */ 660 600 int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev, 661 601 struct amdgpu_ring *ring, 662 602 struct amdgpu_bo *bo, ··· 705 613 return r; 706 614 } 707 615 616 + /** 617 + * amdgpu_bo_kmap - map an &amdgpu_bo buffer object 618 + * @bo: &amdgpu_bo buffer object to be mapped 619 + * @ptr: kernel virtual address to be returned 620 + * 621 + * Calls ttm_bo_kmap() to set up the kernel virtual mapping; calls 622 + * amdgpu_bo_kptr() to get the kernel virtual address. 623 + * 624 + * Returns: 625 + * 0 for success or a negative error code on failure. 626 + */ 708 627 int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) 709 628 { 710 629 void *kptr; ··· 746 643 return 0; 747 644 } 748 645 646 + /** 647 + * amdgpu_bo_kptr - returns a kernel virtual address of the buffer object 648 + * @bo: &amdgpu_bo buffer object 649 + * 650 + * Calls ttm_kmap_obj_virtual() to get the kernel virtual address 651 + * 652 + * Returns: 653 + * the virtual address of a buffer object area. 654 + */ 749 655 void *amdgpu_bo_kptr(struct amdgpu_bo *bo) 750 656 { 751 657 bool is_iomem; ··· 762 650 return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); 763 651 } 764 652 653 + /** 654 + * amdgpu_bo_kunmap - unmap an &amdgpu_bo buffer object 655 + * @bo: &amdgpu_bo buffer object to be unmapped 656 + * 657 + * Unmaps a kernel map set up by amdgpu_bo_kmap(). 658 + */ 765 659 void amdgpu_bo_kunmap(struct amdgpu_bo *bo) 766 660 { 767 661 if (bo->kmap.bo) 768 662 ttm_bo_kunmap(&bo->kmap); 769 663 } 770 664 665 + /** 666 + * amdgpu_bo_ref - reference an &amdgpu_bo buffer object 667 + * @bo: &amdgpu_bo buffer object 668 + * 669 + * References the contained &ttm_buffer_object. 670 + * 671 + * Returns: 672 + * a refcounted pointer to the &amdgpu_bo buffer object. 673 + */ 771 674 struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo) 772 675 { 773 676 if (bo == NULL) ··· 792 665 return bo; 793 666 } 794 667 668 + /** 669 + * amdgpu_bo_unref - unreference an &amdgpu_bo buffer object 670 + * @bo: &amdgpu_bo buffer object 671 + * 672 + * Unreferences the contained &ttm_buffer_object and clear the pointer 673 + */ 795 674 void amdgpu_bo_unref(struct amdgpu_bo **bo) 796 675 { 797 676 struct ttm_buffer_object *tbo; ··· 811 678 *bo = NULL; 812 679 } 813 680 681 + /** 682 + * amdgpu_bo_pin_restricted - pin an &amdgpu_bo buffer object 683 + * @bo: &amdgpu_bo buffer object to be pinned 684 + * @domain: domain to be pinned to 685 + * @min_offset: the start of requested address range 686 + * @max_offset: the end of requested address range 687 + * @gpu_addr: GPU offset of the &amdgpu_bo buffer object 688 + * 689 + * Pins the buffer object according to requested domain and address range. If 690 + * the memory is unbound gart memory, binds the pages into gart table. Adjusts 691 + * pin_count and pin_size accordingly. 692 + * 693 + * Pinning means to lock pages in memory along with keeping them at a fixed 694 + * offset. It is required when a buffer can not be moved, for example, when 695 + * a display buffer is being scanned out. 696 + * 697 + * Compared with amdgpu_bo_pin(), this function gives more flexibility on 698 + * where to pin a buffer if there are specific restrictions on where a buffer 699 + * must be located. 700 + * 701 + * Returns: 702 + * 0 for success or a negative error code on failure. 703 + */ 814 704 int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, 815 705 u64 min_offset, u64 max_offset, 816 706 u64 *gpu_addr) ··· 928 772 return r; 929 773 } 930 774 775 + /** 776 + * amdgpu_bo_pin - pin an &amdgpu_bo buffer object 777 + * @bo: &amdgpu_bo buffer object to be pinned 778 + * @domain: domain to be pinned to 779 + * @gpu_addr: GPU offset of the &amdgpu_bo buffer object 780 + * 781 + * A simple wrapper to amdgpu_bo_pin_restricted(). 782 + * Provides a simpler API for buffers that do not have any strict restrictions 783 + * on where a buffer must be located. 784 + * 785 + * Returns: 786 + * 0 for success or a negative error code on failure. 787 + */ 931 788 int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr) 932 789 { 933 790 return amdgpu_bo_pin_restricted(bo, domain, 0, 0, gpu_addr); 934 791 } 935 792 793 + /** 794 + * amdgpu_bo_unpin - unpin an &amdgpu_bo buffer object 795 + * @bo: &amdgpu_bo buffer object to be unpinned 796 + * 797 + * Decreases the pin_count, and clears the flags if pin_count reaches 0. 798 + * Changes placement and pin size accordingly. 799 + * 800 + * Returns: 801 + * 0 for success or a negative error code on failure. 802 + */ 936 803 int amdgpu_bo_unpin(struct amdgpu_bo *bo) 937 804 { 938 805 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); ··· 991 812 return r; 992 813 } 993 814 815 + /** 816 + * amdgpu_bo_evict_vram - evict VRAM buffers 817 + * @adev: amdgpu device object 818 + * 819 + * Evicts all VRAM buffers on the lru list of the memory type. 820 + * Mainly used for evicting vram at suspend time. 821 + * 822 + * Returns: 823 + * 0 for success or a negative error code on failure. 824 + */ 994 825 int amdgpu_bo_evict_vram(struct amdgpu_device *adev) 995 826 { 996 827 /* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */ ··· 1023 834 "DDR4", 1024 835 }; 1025 836 837 + /** 838 + * amdgpu_bo_init - initialize memory manager 839 + * @adev: amdgpu device object 840 + * 841 + * Calls amdgpu_ttm_init() to initialize amdgpu memory manager. 842 + * 843 + * Returns: 844 + * 0 for success or a negative error code on failure. 845 + */ 1026 846 int amdgpu_bo_init(struct amdgpu_device *adev) 1027 847 { 1028 848 /* reserve PAT memory space to WC for VRAM */ ··· 1049 851 return amdgpu_ttm_init(adev); 1050 852 } 1051 853 854 + /** 855 + * amdgpu_bo_late_init - late init 856 + * @adev: amdgpu device object 857 + * 858 + * Calls amdgpu_ttm_late_init() to free resources used earlier during 859 + * initialization. 860 + * 861 + * Returns: 862 + * 0 for success or a negative error code on failure. 863 + */ 1052 864 int amdgpu_bo_late_init(struct amdgpu_device *adev) 1053 865 { 1054 866 amdgpu_ttm_late_init(adev); ··· 1066 858 return 0; 1067 859 } 1068 860 861 + /** 862 + * amdgpu_bo_fini - tear down memory manager 863 + * @adev: amdgpu device object 864 + * 865 + * Reverses amdgpu_bo_init() to tear down memory manager. 866 + */ 1069 867 void amdgpu_bo_fini(struct amdgpu_device *adev) 1070 868 { 1071 869 amdgpu_ttm_fini(adev); ··· 1079 865 arch_io_free_memtype_wc(adev->gmc.aper_base, adev->gmc.aper_size); 1080 866 } 1081 867 868 + /** 869 + * amdgpu_bo_fbdev_mmap - mmap fbdev memory 870 + * @bo: &amdgpu_bo buffer object 871 + * @vma: vma as input from the fbdev mmap method 872 + * 873 + * Calls ttm_fbdev_mmap() to mmap fbdev memory if it is backed by a bo. 874 + * 875 + * Returns: 876 + * 0 for success or a negative error code on failure. 877 + */ 1082 878 int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, 1083 879 struct vm_area_struct *vma) 1084 880 { 1085 881 return ttm_fbdev_mmap(vma, &bo->tbo); 1086 882 } 1087 883 884 + /** 885 + * amdgpu_bo_set_tiling_flags - set tiling flags 886 + * @bo: &amdgpu_bo buffer object 887 + * @tiling_flags: new flags 888 + * 889 + * Sets buffer object's tiling flags with the new one. Used by GEM ioctl or 890 + * kernel driver to set the tiling flags on a buffer. 891 + * 892 + * Returns: 893 + * 0 for success or a negative error code on failure. 894 + */ 1088 895 int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags) 1089 896 { 1090 897 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); ··· 1118 883 return 0; 1119 884 } 1120 885 886 + /** 887 + * amdgpu_bo_get_tiling_flags - get tiling flags 888 + * @bo: &amdgpu_bo buffer object 889 + * @tiling_flags: returned flags 890 + * 891 + * Gets buffer object's tiling flags. Used by GEM ioctl or kernel driver to 892 + * set the tiling flags on a buffer. 893 + */ 1121 894 void amdgpu_bo_get_tiling_flags(struct amdgpu_bo *bo, u64 *tiling_flags) 1122 895 { 1123 896 lockdep_assert_held(&bo->tbo.resv->lock.base); ··· 1134 891 *tiling_flags = bo->tiling_flags; 1135 892 } 1136 893 894 + /** 895 + * amdgpu_bo_set_metadata - set metadata 896 + * @bo: &amdgpu_bo buffer object 897 + * @metadata: new metadata 898 + * @metadata_size: size of the new metadata 899 + * @flags: flags of the new metadata 900 + * 901 + * Sets buffer object's metadata, its size and flags. 902 + * Used via GEM ioctl. 903 + * 904 + * Returns: 905 + * 0 for success or a negative error code on failure. 906 + */ 1137 907 int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, 1138 908 uint32_t metadata_size, uint64_t flags) 1139 909 { ··· 1176 920 return 0; 1177 921 } 1178 922 923 + /** 924 + * amdgpu_bo_get_metadata - get metadata 925 + * @bo: &amdgpu_bo buffer object 926 + * @buffer: returned metadata 927 + * @buffer_size: size of the buffer 928 + * @metadata_size: size of the returned metadata 929 + * @flags: flags of the returned metadata 930 + * 931 + * Gets buffer object's metadata, its size and flags. buffer_size shall not be 932 + * less than metadata_size. 933 + * Used via GEM ioctl. 934 + * 935 + * Returns: 936 + * 0 for success or a negative error code on failure. 937 + */ 1179 938 int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, 1180 939 size_t buffer_size, uint32_t *metadata_size, 1181 940 uint64_t *flags) ··· 1214 943 return 0; 1215 944 } 1216 945 946 + /** 947 + * amdgpu_bo_move_notify - notification about a memory move 948 + * @bo: pointer to a buffer object 949 + * @evict: if this move is evicting the buffer from the graphics address space 950 + * @new_mem: new information of the bufer object 951 + * 952 + * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs 953 + * bookkeeping. 954 + * TTM driver callback which is called when ttm moves a buffer. 955 + */ 1217 956 void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, 1218 957 bool evict, 1219 958 struct ttm_mem_reg *new_mem) ··· 1252 971 trace_amdgpu_ttm_bo_move(abo, new_mem->mem_type, old_mem->mem_type); 1253 972 } 1254 973 974 + /** 975 + * amdgpu_bo_fault_reserve_notify - notification about a memory fault 976 + * @bo: pointer to a buffer object 977 + * 978 + * Notifies the driver we are taking a fault on this BO and have reserved it, 979 + * also performs bookkeeping. 980 + * TTM driver callback for dealing with vm faults. 981 + * 982 + * Returns: 983 + * 0 for success or a negative error code on failure. 984 + */ 1255 985 int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) 1256 986 { 1257 987 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); ··· 1336 1044 * amdgpu_bo_gpu_offset - return GPU offset of bo 1337 1045 * @bo: amdgpu object for which we query the offset 1338 1046 * 1339 - * Returns current GPU offset of the object. 1340 - * 1341 1047 * Note: object should either be pinned or reserved when calling this 1342 1048 * function, it might be useful to add check for this for debugging. 1049 + * 1050 + * Returns: 1051 + * current GPU offset of the object. 1343 1052 */ 1344 1053 u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) 1345 1054 { ··· 1356 1063 return bo->tbo.offset; 1357 1064 } 1358 1065 1066 + /** 1067 + * amdgpu_bo_get_preferred_pin_domain - get preferred domain for scanout 1068 + * @adev: amdgpu device object 1069 + * @domain: allowed :ref:`memory domains <amdgpu_memory_domains>` 1070 + * 1071 + * Returns: 1072 + * Which of the allowed domains is preferred for pinning the BO for scanout. 1073 + */ 1359 1074 uint32_t amdgpu_bo_get_preferred_pin_domain(struct amdgpu_device *adev, 1360 1075 uint32_t domain) 1361 1076 {
+48 -18
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
··· 68 68 if (adev->pm.dpm_enabled) { 69 69 mutex_lock(&adev->pm.mutex); 70 70 if (power_supply_is_system_supplied() > 0) 71 - adev->pm.dpm.ac_power = true; 71 + adev->pm.ac_power = true; 72 72 else 73 - adev->pm.dpm.ac_power = false; 73 + adev->pm.ac_power = false; 74 74 if (adev->powerplay.pp_funcs->enable_bapm) 75 - amdgpu_dpm_enable_bapm(adev, adev->pm.dpm.ac_power); 75 + amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power); 76 76 mutex_unlock(&adev->pm.mutex); 77 77 } 78 78 } ··· 80 80 /** 81 81 * DOC: power_dpm_state 82 82 * 83 - * This is a legacy interface and is only provided for backwards compatibility. 84 - * The amdgpu driver provides a sysfs API for adjusting certain power 85 - * related parameters. The file power_dpm_state is used for this. 83 + * The power_dpm_state file is a legacy interface and is only provided for 84 + * backwards compatibility. The amdgpu driver provides a sysfs API for adjusting 85 + * certain power related parameters. The file power_dpm_state is used for this. 86 86 * It accepts the following arguments: 87 + * 87 88 * - battery 89 + * 88 90 * - balanced 91 + * 89 92 * - performance 90 93 * 91 94 * battery ··· 172 169 * The amdgpu driver provides a sysfs API for adjusting certain power 173 170 * related parameters. The file power_dpm_force_performance_level is 174 171 * used for this. It accepts the following arguments: 172 + * 175 173 * - auto 174 + * 176 175 * - low 176 + * 177 177 * - high 178 + * 178 179 * - manual 179 - * - GPU fan 180 + * 180 181 * - profile_standard 182 + * 181 183 * - profile_min_sclk 184 + * 182 185 * - profile_min_mclk 186 + * 183 187 * - profile_peak 184 188 * 185 189 * auto ··· 473 463 * this. 474 464 * 475 465 * Reading the file will display: 466 + * 476 467 * - a list of engine clock levels and voltages labeled OD_SCLK 468 + * 477 469 * - a list of memory clock levels and voltages labeled OD_MCLK 470 + * 478 471 * - a list of valid ranges for sclk, mclk, and voltage labeled OD_RANGE 479 472 * 480 473 * To manually adjust these settings, first select manual using ··· 1298 1285 * DOC: hwmon 1299 1286 * 1300 1287 * The amdgpu driver exposes the following sensor interfaces: 1288 + * 1301 1289 * - GPU temperature (via the on-die sensor) 1290 + * 1302 1291 * - GPU voltage 1292 + * 1303 1293 * - Northbridge voltage (APUs only) 1294 + * 1304 1295 * - GPU power 1296 + * 1305 1297 * - GPU fan 1306 1298 * 1307 1299 * hwmon interfaces for GPU temperature: 1300 + * 1308 1301 * - temp1_input: the on die GPU temperature in millidegrees Celsius 1302 + * 1309 1303 * - temp1_crit: temperature critical max value in millidegrees Celsius 1304 + * 1310 1305 * - temp1_crit_hyst: temperature hysteresis for critical limit in millidegrees Celsius 1311 1306 * 1312 1307 * hwmon interfaces for GPU voltage: 1308 + * 1313 1309 * - in0_input: the voltage on the GPU in millivolts 1310 + * 1314 1311 * - in1_input: the voltage on the Northbridge in millivolts 1315 1312 * 1316 1313 * hwmon interfaces for GPU power: 1314 + * 1317 1315 * - power1_average: average power used by the GPU in microWatts 1316 + * 1318 1317 * - power1_cap_min: minimum cap supported in microWatts 1318 + * 1319 1319 * - power1_cap_max: maximum cap supported in microWatts 1320 + * 1320 1321 * - power1_cap: selected power cap in microWatts 1321 1322 * 1322 1323 * hwmon interfaces for GPU fan: 1324 + * 1323 1325 * - pwm1: pulse width modulation fan level (0-255) 1324 - * - pwm1_enable: pulse width modulation fan control method 1325 - * 0: no fan speed control 1326 - * 1: manual fan speed control using pwm interface 1327 - * 2: automatic fan speed control 1326 + * 1327 + * - pwm1_enable: pulse width modulation fan control method (0: no fan speed control, 1: manual fan speed control using pwm interface, 2: automatic fan speed control) 1328 + * 1328 1329 * - pwm1_min: pulse width modulation fan control minimum level (0) 1330 + * 1329 1331 * - pwm1_max: pulse width modulation fan control maximum level (255) 1332 + * 1330 1333 * - fan1_input: fan speed in RPM 1331 1334 * 1332 1335 * You can use hwmon tools like sensors to view this information on your system. ··· 1907 1878 amdgpu_fence_wait_empty(ring); 1908 1879 } 1909 1880 1881 + mutex_lock(&adev->pm.mutex); 1882 + /* update battery/ac status */ 1883 + if (power_supply_is_system_supplied() > 0) 1884 + adev->pm.ac_power = true; 1885 + else 1886 + adev->pm.ac_power = false; 1887 + mutex_unlock(&adev->pm.mutex); 1888 + 1910 1889 if (adev->powerplay.pp_funcs->dispatch_tasks) { 1911 1890 if (!amdgpu_device_has_dc_support(adev)) { 1912 1891 mutex_lock(&adev->pm.mutex); ··· 1935 1898 } else { 1936 1899 mutex_lock(&adev->pm.mutex); 1937 1900 amdgpu_dpm_get_active_displays(adev); 1938 - /* update battery/ac status */ 1939 - if (power_supply_is_system_supplied() > 0) 1940 - adev->pm.dpm.ac_power = true; 1941 - else 1942 - adev->pm.dpm.ac_power = false; 1943 - 1944 1901 amdgpu_dpm_change_power_state_locked(adev); 1945 - 1946 1902 mutex_unlock(&adev->pm.mutex); 1947 1903 } 1948 1904 }
+119
drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
··· 23 23 * 24 24 * Authors: Alex Deucher 25 25 */ 26 + 27 + /** 28 + * DOC: PRIME Buffer Sharing 29 + * 30 + * The following callback implementations are used for :ref:`sharing GEM buffer 31 + * objects between different devices via PRIME <prime_buffer_sharing>`. 32 + */ 33 + 26 34 #include <drm/drmP.h> 27 35 28 36 #include "amdgpu.h" ··· 40 32 41 33 static const struct dma_buf_ops amdgpu_dmabuf_ops; 42 34 35 + /** 36 + * amdgpu_gem_prime_get_sg_table - &drm_driver.gem_prime_get_sg_table 37 + * implementation 38 + * @obj: GEM buffer object 39 + * 40 + * Returns: 41 + * A scatter/gather table for the pinned pages of the buffer object's memory. 42 + */ 43 43 struct sg_table *amdgpu_gem_prime_get_sg_table(struct drm_gem_object *obj) 44 44 { 45 45 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); ··· 56 40 return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages); 57 41 } 58 42 43 + /** 44 + * amdgpu_gem_prime_vmap - &dma_buf_ops.vmap implementation 45 + * @obj: GEM buffer object 46 + * 47 + * Sets up an in-kernel virtual mapping of the buffer object's memory. 48 + * 49 + * Returns: 50 + * The virtual address of the mapping or an error pointer. 51 + */ 59 52 void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj) 60 53 { 61 54 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); ··· 78 53 return bo->dma_buf_vmap.virtual; 79 54 } 80 55 56 + /** 57 + * amdgpu_gem_prime_vunmap - &dma_buf_ops.vunmap implementation 58 + * @obj: GEM buffer object 59 + * @vaddr: virtual address (unused) 60 + * 61 + * Tears down the in-kernel virtual mapping of the buffer object's memory. 62 + */ 81 63 void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) 82 64 { 83 65 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); ··· 92 60 ttm_bo_kunmap(&bo->dma_buf_vmap); 93 61 } 94 62 63 + /** 64 + * amdgpu_gem_prime_mmap - &drm_driver.gem_prime_mmap implementation 65 + * @obj: GEM buffer object 66 + * @vma: virtual memory area 67 + * 68 + * Sets up a userspace mapping of the buffer object's memory in the given 69 + * virtual memory area. 70 + * 71 + * Returns: 72 + * 0 on success or negative error code. 73 + */ 95 74 int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) 96 75 { 97 76 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); ··· 137 94 return ret; 138 95 } 139 96 97 + /** 98 + * amdgpu_gem_prime_import_sg_table - &drm_driver.gem_prime_import_sg_table 99 + * implementation 100 + * @dev: DRM device 101 + * @attach: DMA-buf attachment 102 + * @sg: Scatter/gather table 103 + * 104 + * Import shared DMA buffer memory exported by another device. 105 + * 106 + * Returns: 107 + * A new GEM buffer object of the given DRM device, representing the memory 108 + * described by the given DMA-buf attachment and scatter/gather table. 109 + */ 140 110 struct drm_gem_object * 141 111 amdgpu_gem_prime_import_sg_table(struct drm_device *dev, 142 112 struct dma_buf_attachment *attach, ··· 188 132 return ERR_PTR(ret); 189 133 } 190 134 135 + /** 136 + * amdgpu_gem_map_attach - &dma_buf_ops.attach implementation 137 + * @dma_buf: shared DMA buffer 138 + * @target_dev: target device 139 + * @attach: DMA-buf attachment 140 + * 141 + * Makes sure that the shared DMA buffer can be accessed by the target device. 142 + * For now, simply pins it to the GTT domain, where it should be accessible by 143 + * all DMA devices. 144 + * 145 + * Returns: 146 + * 0 on success or negative error code. 147 + */ 191 148 static int amdgpu_gem_map_attach(struct dma_buf *dma_buf, 192 149 struct dma_buf_attachment *attach) 193 150 { ··· 249 180 return r; 250 181 } 251 182 183 + /** 184 + * amdgpu_gem_map_detach - &dma_buf_ops.detach implementation 185 + * @dma_buf: shared DMA buffer 186 + * @attach: DMA-buf attachment 187 + * 188 + * This is called when a shared DMA buffer no longer needs to be accessible by 189 + * the other device. For now, simply unpins the buffer from GTT. 190 + */ 252 191 static void amdgpu_gem_map_detach(struct dma_buf *dma_buf, 253 192 struct dma_buf_attachment *attach) 254 193 { ··· 278 201 drm_gem_map_detach(dma_buf, attach); 279 202 } 280 203 204 + /** 205 + * amdgpu_gem_prime_res_obj - &drm_driver.gem_prime_res_obj implementation 206 + * @obj: GEM buffer object 207 + * 208 + * Returns: 209 + * The buffer object's reservation object. 210 + */ 281 211 struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *obj) 282 212 { 283 213 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); ··· 292 208 return bo->tbo.resv; 293 209 } 294 210 211 + /** 212 + * amdgpu_gem_begin_cpu_access - &dma_buf_ops.begin_cpu_access implementation 213 + * @dma_buf: shared DMA buffer 214 + * @direction: direction of DMA transfer 215 + * 216 + * This is called before CPU access to the shared DMA buffer's memory. If it's 217 + * a read access, the buffer is moved to the GTT domain if possible, for optimal 218 + * CPU read performance. 219 + * 220 + * Returns: 221 + * 0 on success or negative error code. 222 + */ 295 223 static int amdgpu_gem_begin_cpu_access(struct dma_buf *dma_buf, 296 224 enum dma_data_direction direction) 297 225 { ··· 346 250 .vunmap = drm_gem_dmabuf_vunmap, 347 251 }; 348 252 253 + /** 254 + * amdgpu_gem_prime_export - &drm_driver.gem_prime_export implementation 255 + * @dev: DRM device 256 + * @gobj: GEM buffer object 257 + * @flags: flags like DRM_CLOEXEC and DRM_RDWR 258 + * 259 + * The main work is done by the &drm_gem_prime_export helper, which in turn 260 + * uses &amdgpu_gem_prime_res_obj. 261 + * 262 + * Returns: 263 + * Shared DMA buffer representing the GEM buffer object from the given device. 264 + */ 349 265 struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev, 350 266 struct drm_gem_object *gobj, 351 267 int flags) ··· 378 270 return buf; 379 271 } 380 272 273 + /** 274 + * amdgpu_gem_prime_import - &drm_driver.gem_prime_import implementation 275 + * @dev: DRM device 276 + * @dma_buf: Shared DMA buffer 277 + * 278 + * The main work is done by the &drm_gem_prime_import helper, which in turn 279 + * uses &amdgpu_gem_prime_import_sg_table. 280 + * 281 + * Returns: 282 + * GEM buffer object representing the shared DMA buffer for the given device. 283 + */ 381 284 struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, 382 285 struct dma_buf *dma_buf) 383 286 {
+7
drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
··· 96 96 case AMDGPU_HW_IP_VCN_ENC: 97 97 *out_ring = &adev->vcn.ring_enc[ring]; 98 98 break; 99 + case AMDGPU_HW_IP_VCN_JPEG: 100 + *out_ring = &adev->vcn.ring_jpeg; 101 + break; 99 102 default: 100 103 *out_ring = NULL; 101 104 DRM_ERROR("unknown HW IP type: %d\n", mapper->hw_ip); ··· 263 260 case AMDGPU_HW_IP_VCN_ENC: 264 261 ip_num_rings = adev->vcn.num_enc_rings; 265 262 break; 263 + case AMDGPU_HW_IP_VCN_JPEG: 264 + ip_num_rings = 1; 265 + break; 266 266 default: 267 267 DRM_DEBUG("unknown ip type: %d\n", hw_ip); 268 268 return -EINVAL; ··· 293 287 case AMDGPU_HW_IP_UVD_ENC: 294 288 case AMDGPU_HW_IP_VCN_DEC: 295 289 case AMDGPU_HW_IP_VCN_ENC: 290 + case AMDGPU_HW_IP_VCN_JPEG: 296 291 r = amdgpu_identity_map(adev, mapper, ring, out_ring); 297 292 break; 298 293 case AMDGPU_HW_IP_DMA:
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
··· 304 304 0xffffffffffffffff : ring->buf_mask; 305 305 /* Allocate ring buffer */ 306 306 if (ring->ring_obj == NULL) { 307 - r = amdgpu_bo_create_kernel(adev, ring->ring_size, PAGE_SIZE, 307 + r = amdgpu_bo_create_kernel(adev, ring->ring_size + ring->funcs->extra_dw, PAGE_SIZE, 308 308 AMDGPU_GEM_DOMAIN_GTT, 309 309 &ring->ring_obj, 310 310 &ring->gpu_addr,
+3 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
··· 53 53 AMDGPU_RING_TYPE_KIQ, 54 54 AMDGPU_RING_TYPE_UVD_ENC, 55 55 AMDGPU_RING_TYPE_VCN_DEC, 56 - AMDGPU_RING_TYPE_VCN_ENC 56 + AMDGPU_RING_TYPE_VCN_ENC, 57 + AMDGPU_RING_TYPE_VCN_JPEG 57 58 }; 58 59 59 60 struct amdgpu_device; ··· 113 112 u32 nop; 114 113 bool support_64bit_ptrs; 115 114 unsigned vmhub; 115 + unsigned extra_dw; 116 116 117 117 /* ring read/write ptr handling */ 118 118 u64 (*get_rptr)(struct amdgpu_ring *ring);
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 277 277 if (!adev->mman.buffer_funcs_enabled) { 278 278 /* Move to system memory */ 279 279 amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU); 280 - } else if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && 280 + } else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && 281 281 !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && 282 282 amdgpu_bo_in_cpu_visible_vram(abo)) { 283 283
+38 -21
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
··· 127 127 unsigned long bo_size; 128 128 const char *fw_name; 129 129 const struct common_firmware_header *hdr; 130 - unsigned version_major, version_minor, family_id; 130 + unsigned family_id; 131 131 int i, j, r; 132 132 133 133 INIT_DELAYED_WORK(&adev->uvd.inst->idle_work, amdgpu_uvd_idle_work_handler); ··· 208 208 209 209 hdr = (const struct common_firmware_header *)adev->uvd.fw->data; 210 210 family_id = le32_to_cpu(hdr->ucode_version) & 0xff; 211 - version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; 212 - version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; 213 - DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", 214 - version_major, version_minor, family_id); 215 211 216 - /* 217 - * Limit the number of UVD handles depending on microcode major 218 - * and minor versions. The firmware version which has 40 UVD 219 - * instances support is 1.80. So all subsequent versions should 220 - * also have the same support. 221 - */ 222 - if ((version_major > 0x01) || 223 - ((version_major == 0x01) && (version_minor >= 0x50))) 212 + if (adev->asic_type < CHIP_VEGA20) { 213 + unsigned version_major, version_minor; 214 + 215 + version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; 216 + version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; 217 + DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", 218 + version_major, version_minor, family_id); 219 + 220 + /* 221 + * Limit the number of UVD handles depending on microcode major 222 + * and minor versions. The firmware version which has 40 UVD 223 + * instances support is 1.80. So all subsequent versions should 224 + * also have the same support. 225 + */ 226 + if ((version_major > 0x01) || 227 + ((version_major == 0x01) && (version_minor >= 0x50))) 228 + adev->uvd.max_handles = AMDGPU_MAX_UVD_HANDLES; 229 + 230 + adev->uvd.fw_version = ((version_major << 24) | (version_minor << 16) | 231 + (family_id << 8)); 232 + 233 + if ((adev->asic_type == CHIP_POLARIS10 || 234 + adev->asic_type == CHIP_POLARIS11) && 235 + (adev->uvd.fw_version < FW_1_66_16)) 236 + DRM_ERROR("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n", 237 + version_major, version_minor); 238 + } else { 239 + unsigned int enc_major, enc_minor, dec_minor; 240 + 241 + dec_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; 242 + enc_minor = (le32_to_cpu(hdr->ucode_version) >> 24) & 0x3f; 243 + enc_major = (le32_to_cpu(hdr->ucode_version) >> 30) & 0x3; 244 + DRM_INFO("Found UVD firmware ENC: %hu.%hu DEC: .%hu Family ID: %hu\n", 245 + enc_major, enc_minor, dec_minor, family_id); 246 + 224 247 adev->uvd.max_handles = AMDGPU_MAX_UVD_HANDLES; 225 248 226 - adev->uvd.fw_version = ((version_major << 24) | (version_minor << 16) | 227 - (family_id << 8)); 228 - 229 - if ((adev->asic_type == CHIP_POLARIS10 || 230 - adev->asic_type == CHIP_POLARIS11) && 231 - (adev->uvd.fw_version < FW_1_66_16)) 232 - DRM_ERROR("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n", 233 - version_major, version_minor); 249 + adev->uvd.fw_version = le32_to_cpu(hdr->ucode_version); 250 + } 234 251 235 252 bo_size = AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE 236 253 + AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles;
+128
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
··· 119 119 for (i = 0; i < adev->vcn.num_enc_rings; ++i) 120 120 amdgpu_ring_fini(&adev->vcn.ring_enc[i]); 121 121 122 + amdgpu_ring_fini(&adev->vcn.ring_jpeg); 123 + 122 124 release_firmware(adev->vcn.fw); 123 125 124 126 return 0; ··· 576 574 } 577 575 error: 578 576 dma_fence_put(fence); 577 + return r; 578 + } 579 + 580 + int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) 581 + { 582 + struct amdgpu_device *adev = ring->adev; 583 + uint32_t tmp = 0; 584 + unsigned i; 585 + int r; 586 + 587 + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD); 588 + r = amdgpu_ring_alloc(ring, 3); 589 + 590 + if (r) { 591 + DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", 592 + ring->idx, r); 593 + return r; 594 + } 595 + 596 + amdgpu_ring_write(ring, 597 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0, 0, 0)); 598 + amdgpu_ring_write(ring, 0xDEADBEEF); 599 + amdgpu_ring_commit(ring); 600 + 601 + for (i = 0; i < adev->usec_timeout; i++) { 602 + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID)); 603 + if (tmp == 0xDEADBEEF) 604 + break; 605 + DRM_UDELAY(1); 606 + } 607 + 608 + if (i < adev->usec_timeout) { 609 + DRM_DEBUG("ring test on %d succeeded in %d usecs\n", 610 + ring->idx, i); 611 + } else { 612 + DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", 613 + ring->idx, tmp); 614 + r = -EINVAL; 615 + } 616 + 617 + return r; 618 + } 619 + 620 + static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle, 621 + struct dma_fence **fence) 622 + { 623 + struct amdgpu_device *adev = ring->adev; 624 + struct amdgpu_job *job; 625 + struct amdgpu_ib *ib; 626 + struct dma_fence *f = NULL; 627 + const unsigned ib_size_dw = 16; 628 + int i, r; 629 + 630 + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); 631 + if (r) 632 + return r; 633 + 634 + ib = &job->ibs[0]; 635 + 636 + ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH), 0, 0, PACKETJ_TYPE0); 637 + ib->ptr[1] = 0xDEADBEEF; 638 + for (i = 2; i < 16; i += 2) { 639 + ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); 640 + ib->ptr[i+1] = 0; 641 + } 642 + ib->length_dw = 16; 643 + 644 + r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); 645 + job->fence = dma_fence_get(f); 646 + if (r) 647 + goto err; 648 + 649 + amdgpu_job_free(job); 650 + if (fence) 651 + *fence = dma_fence_get(f); 652 + dma_fence_put(f); 653 + 654 + return 0; 655 + 656 + err: 657 + amdgpu_job_free(job); 658 + return r; 659 + } 660 + 661 + int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) 662 + { 663 + struct amdgpu_device *adev = ring->adev; 664 + uint32_t tmp = 0; 665 + unsigned i; 666 + struct dma_fence *fence = NULL; 667 + long r = 0; 668 + 669 + r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence); 670 + if (r) { 671 + DRM_ERROR("amdgpu: failed to set jpeg register (%ld).\n", r); 672 + goto error; 673 + } 674 + 675 + r = dma_fence_wait_timeout(fence, false, timeout); 676 + if (r == 0) { 677 + DRM_ERROR("amdgpu: IB test timed out.\n"); 678 + r = -ETIMEDOUT; 679 + goto error; 680 + } else if (r < 0) { 681 + DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); 682 + goto error; 683 + } else 684 + r = 0; 685 + 686 + for (i = 0; i < adev->usec_timeout; i++) { 687 + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH)); 688 + if (tmp == 0xDEADBEEF) 689 + break; 690 + DRM_UDELAY(1); 691 + } 692 + 693 + if (i < adev->usec_timeout) 694 + DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); 695 + else { 696 + DRM_ERROR("ib test failed (0x%08X)\n", tmp); 697 + r = -EINVAL; 698 + } 699 + 700 + dma_fence_put(fence); 701 + 702 + error: 579 703 return r; 580 704 }
+4
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
··· 66 66 const struct firmware *fw; /* VCN firmware */ 67 67 struct amdgpu_ring ring_dec; 68 68 struct amdgpu_ring ring_enc[AMDGPU_VCN_MAX_ENC_RINGS]; 69 + struct amdgpu_ring ring_jpeg; 69 70 struct amdgpu_irq_src irq; 70 71 unsigned num_enc_rings; 71 72 }; ··· 83 82 84 83 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring); 85 84 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout); 85 + 86 + int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring); 87 + int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout); 86 88 87 89 #endif
+227 -47
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 33 33 #include "amdgpu.h" 34 34 #include "amdgpu_trace.h" 35 35 #include "amdgpu_amdkfd.h" 36 + #include "amdgpu_gmc.h" 36 37 37 - /* 38 - * GPUVM 38 + /** 39 + * DOC: GPUVM 40 + * 39 41 * GPUVM is similar to the legacy gart on older asics, however 40 42 * rather than there being a single global gart table 41 43 * for the entire GPU, there are multiple VM page tables active ··· 65 63 #undef START 66 64 #undef LAST 67 65 68 - /* Local structure. Encapsulate some VM table update parameters to reduce 66 + /** 67 + * struct amdgpu_pte_update_params - Local structure 68 + * 69 + * Encapsulate some VM table update parameters to reduce 69 70 * the number of function parameters 71 + * 70 72 */ 71 73 struct amdgpu_pte_update_params { 72 - /* amdgpu device we do this update for */ 74 + 75 + /** 76 + * @adev: amdgpu device we do this update for 77 + */ 73 78 struct amdgpu_device *adev; 74 - /* optional amdgpu_vm we do this update for */ 79 + 80 + /** 81 + * @vm: optional amdgpu_vm we do this update for 82 + */ 75 83 struct amdgpu_vm *vm; 76 - /* address where to copy page table entries from */ 84 + 85 + /** 86 + * @src: address where to copy page table entries from 87 + */ 77 88 uint64_t src; 78 - /* indirect buffer to fill with commands */ 89 + 90 + /** 91 + * @ib: indirect buffer to fill with commands 92 + */ 79 93 struct amdgpu_ib *ib; 80 - /* Function which actually does the update */ 94 + 95 + /** 96 + * @func: Function which actually does the update 97 + */ 81 98 void (*func)(struct amdgpu_pte_update_params *params, 82 99 struct amdgpu_bo *bo, uint64_t pe, 83 100 uint64_t addr, unsigned count, uint32_t incr, 84 101 uint64_t flags); 85 - /* The next two are used during VM update by CPU 86 - * DMA addresses to use for mapping 87 - * Kernel pointer of PD/PT BO that needs to be updated 102 + /** 103 + * @pages_addr: 104 + * 105 + * DMA addresses to use for mapping, used during VM update by CPU 88 106 */ 89 107 dma_addr_t *pages_addr; 108 + 109 + /** 110 + * @kptr: 111 + * 112 + * Kernel pointer of PD/PT BO that needs to be updated, 113 + * used during VM update by CPU 114 + */ 90 115 void *kptr; 91 116 }; 92 117 93 - /* Helper to disable partial resident texture feature from a fence callback */ 118 + /** 119 + * struct amdgpu_prt_cb - Helper to disable partial resident texture feature from a fence callback 120 + */ 94 121 struct amdgpu_prt_cb { 122 + 123 + /** 124 + * @adev: amdgpu device 125 + */ 95 126 struct amdgpu_device *adev; 127 + 128 + /** 129 + * @cb: callback 130 + */ 96 131 struct dma_fence_cb cb; 97 132 }; 98 133 134 + /** 135 + * amdgpu_vm_bo_base_init - Adds bo to the list of bos associated with the vm 136 + * 137 + * @base: base structure for tracking BO usage in a VM 138 + * @vm: vm to which bo is to be added 139 + * @bo: amdgpu buffer object 140 + * 141 + * Initialize a bo_va_base structure and add it to the appropriate lists 142 + * 143 + */ 99 144 static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base, 100 145 struct amdgpu_vm *vm, 101 146 struct amdgpu_bo *bo) ··· 175 126 * amdgpu_vm_level_shift - return the addr shift for each level 176 127 * 177 128 * @adev: amdgpu_device pointer 129 + * @level: VMPT level 178 130 * 179 - * Returns the number of bits the pfn needs to be right shifted for a level. 131 + * Returns: 132 + * The number of bits the pfn needs to be right shifted for a level. 180 133 */ 181 134 static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev, 182 135 unsigned level) ··· 206 155 * amdgpu_vm_num_entries - return the number of entries in a PD/PT 207 156 * 208 157 * @adev: amdgpu_device pointer 158 + * @level: VMPT level 209 159 * 210 - * Calculate the number of entries in a page directory or page table. 160 + * Returns: 161 + * The number of entries in a page directory or page table. 211 162 */ 212 163 static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev, 213 164 unsigned level) ··· 232 179 * amdgpu_vm_bo_size - returns the size of the BOs in bytes 233 180 * 234 181 * @adev: amdgpu_device pointer 182 + * @level: VMPT level 235 183 * 236 - * Calculate the size of the BO for a page directory or page table in bytes. 184 + * Returns: 185 + * The size of the BO for a page directory or page table in bytes. 237 186 */ 238 187 static unsigned amdgpu_vm_bo_size(struct amdgpu_device *adev, unsigned level) 239 188 { ··· 273 218 * @param: parameter for the validation callback 274 219 * 275 220 * Validate the page table BOs on command submission if neccessary. 221 + * 222 + * Returns: 223 + * Validation result. 276 224 */ 277 225 int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, 278 226 int (*validate)(void *p, struct amdgpu_bo *bo), ··· 331 273 * @vm: VM to check 332 274 * 333 275 * Check if all VM PDs/PTs are ready for updates 276 + * 277 + * Returns: 278 + * True if eviction list is empty. 334 279 */ 335 280 bool amdgpu_vm_ready(struct amdgpu_vm *vm) 336 281 { ··· 344 283 * amdgpu_vm_clear_bo - initially clear the PDs/PTs 345 284 * 346 285 * @adev: amdgpu_device pointer 286 + * @vm: VM to clear BO from 347 287 * @bo: BO to clear 348 288 * @level: level this BO is at 289 + * @pte_support_ats: indicate ATS support from PTE 349 290 * 350 291 * Root PD needs to be reserved when calling this. 292 + * 293 + * Returns: 294 + * 0 on success, errno otherwise. 351 295 */ 352 296 static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, 353 297 struct amdgpu_vm *vm, struct amdgpu_bo *bo, ··· 448 382 * 449 383 * @adev: amdgpu_device pointer 450 384 * @vm: requested vm 385 + * @parent: parent PT 451 386 * @saddr: start of the address range 452 387 * @eaddr: end of the address range 388 + * @level: VMPT level 389 + * @ats: indicate ATS support from PTE 453 390 * 454 391 * Make sure the page directories and page tables are allocated 392 + * 393 + * Returns: 394 + * 0 on success, errno otherwise. 455 395 */ 456 396 static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, 457 397 struct amdgpu_vm *vm, ··· 566 494 * @size: Size from start address we need. 567 495 * 568 496 * Make sure the page tables are allocated. 497 + * 498 + * Returns: 499 + * 0 on success, errno otherwise. 569 500 */ 570 501 int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, 571 502 struct amdgpu_vm *vm, ··· 634 559 } 635 560 } 636 561 562 + /** 563 + * amdgpu_vm_need_pipeline_sync - Check if pipe sync is needed for job. 564 + * 565 + * @ring: ring on which the job will be submitted 566 + * @job: job to submit 567 + * 568 + * Returns: 569 + * True if sync is needed. 570 + */ 637 571 bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, 638 572 struct amdgpu_job *job) 639 573 { ··· 670 586 return vm_flush_needed || gds_switch_needed; 671 587 } 672 588 673 - static bool amdgpu_vm_is_large_bar(struct amdgpu_device *adev) 674 - { 675 - return (adev->gmc.real_vram_size == adev->gmc.visible_vram_size); 676 - } 677 - 678 589 /** 679 590 * amdgpu_vm_flush - hardware flush the vm 680 591 * 681 592 * @ring: ring to use for flush 682 - * @vmid: vmid number to use 683 - * @pd_addr: address of the page directory 593 + * @job: related job 594 + * @need_pipe_sync: is pipe sync needed 684 595 * 685 596 * Emit a VM flush when it is necessary. 597 + * 598 + * Returns: 599 + * 0 on success, errno otherwise. 686 600 */ 687 601 int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync) 688 602 { ··· 788 706 * Returns the found bo_va or NULL if none is found 789 707 * 790 708 * Object has to be reserved! 709 + * 710 + * Returns: 711 + * Found bo_va or NULL. 791 712 */ 792 713 struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, 793 714 struct amdgpu_bo *bo) ··· 872 787 * @addr: the unmapped addr 873 788 * 874 789 * Look up the physical address of the page that the pte resolves 875 - * to and return the pointer for the page table entry. 790 + * to. 791 + * 792 + * Returns: 793 + * The pointer for the page table entry. 876 794 */ 877 795 static uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr) 878 796 { ··· 928 840 } 929 841 } 930 842 843 + 844 + /** 845 + * amdgpu_vm_wait_pd - Wait for PT BOs to be free. 846 + * 847 + * @adev: amdgpu_device pointer 848 + * @vm: related vm 849 + * @owner: fence owner 850 + * 851 + * Returns: 852 + * 0 on success, errno otherwise. 853 + */ 931 854 static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm, 932 855 void *owner) 933 856 { ··· 992 893 /* 993 894 * amdgpu_vm_invalidate_level - mark all PD levels as invalid 994 895 * 896 + * @adev: amdgpu_device pointer 897 + * @vm: related vm 995 898 * @parent: parent PD 899 + * @level: VMPT level 996 900 * 997 901 * Mark all PD level as invalid after an error. 998 902 */ ··· 1030 928 * @vm: requested vm 1031 929 * 1032 930 * Makes sure all directories are up to date. 1033 - * Returns 0 for success, error for failure. 931 + * 932 + * Returns: 933 + * 0 for success, error for failure. 1034 934 */ 1035 935 int amdgpu_vm_update_directories(struct amdgpu_device *adev, 1036 936 struct amdgpu_vm *vm) ··· 1219 1115 * amdgpu_vm_update_ptes - make sure that page tables are valid 1220 1116 * 1221 1117 * @params: see amdgpu_pte_update_params definition 1222 - * @vm: requested vm 1223 1118 * @start: start of GPU address range 1224 1119 * @end: end of GPU address range 1225 1120 * @dst: destination address to map to, the next dst inside the function 1226 1121 * @flags: mapping flags 1227 1122 * 1228 1123 * Update the page tables in the range @start - @end. 1229 - * Returns 0 for success, -EINVAL for failure. 1124 + * 1125 + * Returns: 1126 + * 0 for success, -EINVAL for failure. 1230 1127 */ 1231 1128 static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, 1232 1129 uint64_t start, uint64_t end, ··· 1281 1176 * @end: last PTE to handle 1282 1177 * @dst: addr those PTEs should point to 1283 1178 * @flags: hw mapping flags 1284 - * Returns 0 for success, -EINVAL for failure. 1179 + * 1180 + * Returns: 1181 + * 0 for success, -EINVAL for failure. 1285 1182 */ 1286 1183 static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params, 1287 1184 uint64_t start, uint64_t end, ··· 1355 1248 * @fence: optional resulting fence 1356 1249 * 1357 1250 * Fill in the page table entries between @start and @last. 1358 - * Returns 0 for success, -EINVAL for failure. 1251 + * 1252 + * Returns: 1253 + * 0 for success, -EINVAL for failure. 1359 1254 */ 1360 1255 static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, 1361 1256 struct dma_fence *exclusive, ··· 1433 1324 ndw += ncmds * 10; 1434 1325 1435 1326 /* extra commands for begin/end fragments */ 1436 - ndw += 2 * 10 * adev->vm_manager.fragment_size; 1327 + if (vm->root.base.bo->shadow) 1328 + ndw += 2 * 10 * adev->vm_manager.fragment_size * 2; 1329 + else 1330 + ndw += 2 * 10 * adev->vm_manager.fragment_size; 1437 1331 1438 1332 params.func = amdgpu_vm_do_set_ptes; 1439 1333 } ··· 1512 1400 * 1513 1401 * Split the mapping into smaller chunks so that each update fits 1514 1402 * into a SDMA IB. 1515 - * Returns 0 for success, -EINVAL for failure. 1403 + * 1404 + * Returns: 1405 + * 0 for success, -EINVAL for failure. 1516 1406 */ 1517 1407 static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, 1518 1408 struct dma_fence *exclusive, ··· 1625 1511 * @clear: if true clear the entries 1626 1512 * 1627 1513 * Fill in the page table entries for @bo_va. 1628 - * Returns 0 for success, -EINVAL for failure. 1514 + * 1515 + * Returns: 1516 + * 0 for success, -EINVAL for failure. 1629 1517 */ 1630 1518 int amdgpu_vm_bo_update(struct amdgpu_device *adev, 1631 1519 struct amdgpu_bo_va *bo_va, ··· 1722 1606 1723 1607 /** 1724 1608 * amdgpu_vm_update_prt_state - update the global PRT state 1609 + * 1610 + * @adev: amdgpu_device pointer 1725 1611 */ 1726 1612 static void amdgpu_vm_update_prt_state(struct amdgpu_device *adev) 1727 1613 { ··· 1738 1620 1739 1621 /** 1740 1622 * amdgpu_vm_prt_get - add a PRT user 1623 + * 1624 + * @adev: amdgpu_device pointer 1741 1625 */ 1742 1626 static void amdgpu_vm_prt_get(struct amdgpu_device *adev) 1743 1627 { ··· 1752 1632 1753 1633 /** 1754 1634 * amdgpu_vm_prt_put - drop a PRT user 1635 + * 1636 + * @adev: amdgpu_device pointer 1755 1637 */ 1756 1638 static void amdgpu_vm_prt_put(struct amdgpu_device *adev) 1757 1639 { ··· 1763 1641 1764 1642 /** 1765 1643 * amdgpu_vm_prt_cb - callback for updating the PRT status 1644 + * 1645 + * @fence: fence for the callback 1646 + * @_cb: the callback function 1766 1647 */ 1767 1648 static void amdgpu_vm_prt_cb(struct dma_fence *fence, struct dma_fence_cb *_cb) 1768 1649 { ··· 1777 1652 1778 1653 /** 1779 1654 * amdgpu_vm_add_prt_cb - add callback for updating the PRT status 1655 + * 1656 + * @adev: amdgpu_device pointer 1657 + * @fence: fence for the callback 1780 1658 */ 1781 1659 static void amdgpu_vm_add_prt_cb(struct amdgpu_device *adev, 1782 1660 struct dma_fence *fence) ··· 1871 1743 * or if an error occurred) 1872 1744 * 1873 1745 * Make sure all freed BOs are cleared in the PT. 1874 - * Returns 0 for success. 1875 - * 1876 1746 * PTs have to be reserved and mutex must be locked! 1747 + * 1748 + * Returns: 1749 + * 0 for success. 1750 + * 1877 1751 */ 1878 1752 int amdgpu_vm_clear_freed(struct amdgpu_device *adev, 1879 1753 struct amdgpu_vm *vm, ··· 1920 1790 * 1921 1791 * @adev: amdgpu_device pointer 1922 1792 * @vm: requested vm 1923 - * @sync: sync object to add fences to 1924 1793 * 1925 1794 * Make sure all BOs which are moved are updated in the PTs. 1926 - * Returns 0 for success. 1795 + * 1796 + * Returns: 1797 + * 0 for success. 1927 1798 * 1928 1799 * PTs have to be reserved! 1929 1800 */ ··· 1979 1848 * 1980 1849 * Add @bo into the requested vm. 1981 1850 * Add @bo to the list of bos associated with the vm 1982 - * Returns newly added bo_va or NULL for failure 1851 + * 1852 + * Returns: 1853 + * Newly added bo_va or NULL for failure 1983 1854 * 1984 1855 * Object has to be reserved! 1985 1856 */ ··· 2044 1911 * @bo_va: bo_va to store the address 2045 1912 * @saddr: where to map the BO 2046 1913 * @offset: requested offset in the BO 1914 + * @size: BO size in bytes 2047 1915 * @flags: attributes of pages (read/write/valid/etc.) 2048 1916 * 2049 1917 * Add a mapping of the BO at the specefied addr into the VM. 2050 - * Returns 0 for success, error for failure. 1918 + * 1919 + * Returns: 1920 + * 0 for success, error for failure. 2051 1921 * 2052 1922 * Object has to be reserved and unreserved outside! 2053 1923 */ ··· 2108 1972 * @bo_va: bo_va to store the address 2109 1973 * @saddr: where to map the BO 2110 1974 * @offset: requested offset in the BO 1975 + * @size: BO size in bytes 2111 1976 * @flags: attributes of pages (read/write/valid/etc.) 2112 1977 * 2113 1978 * Add a mapping of the BO at the specefied addr into the VM. Replace existing 2114 1979 * mappings as we do so. 2115 - * Returns 0 for success, error for failure. 1980 + * 1981 + * Returns: 1982 + * 0 for success, error for failure. 2116 1983 * 2117 1984 * Object has to be reserved and unreserved outside! 2118 1985 */ ··· 2172 2033 * @saddr: where to the BO is mapped 2173 2034 * 2174 2035 * Remove a mapping of the BO at the specefied addr from the VM. 2175 - * Returns 0 for success, error for failure. 2036 + * 2037 + * Returns: 2038 + * 0 for success, error for failure. 2176 2039 * 2177 2040 * Object has to be reserved and unreserved outside! 2178 2041 */ ··· 2228 2087 * @size: size of the range 2229 2088 * 2230 2089 * Remove all mappings in a range, split them as appropriate. 2231 - * Returns 0 for success, error for failure. 2090 + * 2091 + * Returns: 2092 + * 0 for success, error for failure. 2232 2093 */ 2233 2094 int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, 2234 2095 struct amdgpu_vm *vm, ··· 2327 2184 * amdgpu_vm_bo_lookup_mapping - find mapping by address 2328 2185 * 2329 2186 * @vm: the requested VM 2187 + * @addr: the address 2330 2188 * 2331 2189 * Find a mapping by it's address. 2190 + * 2191 + * Returns: 2192 + * The amdgpu_bo_va_mapping matching for addr or NULL 2193 + * 2332 2194 */ 2333 2195 struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, 2334 2196 uint64_t addr) ··· 2385 2237 * amdgpu_vm_bo_invalidate - mark the bo as invalid 2386 2238 * 2387 2239 * @adev: amdgpu_device pointer 2388 - * @vm: requested vm 2389 2240 * @bo: amdgpu buffer object 2241 + * @evicted: is the BO evicted 2390 2242 * 2391 2243 * Mark @bo as invalid. 2392 2244 */ ··· 2426 2278 } 2427 2279 } 2428 2280 2281 + /** 2282 + * amdgpu_vm_get_block_size - calculate VM page table size as power of two 2283 + * 2284 + * @vm_size: VM size 2285 + * 2286 + * Returns: 2287 + * VM page table as power of two 2288 + */ 2429 2289 static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size) 2430 2290 { 2431 2291 /* Total bits covered by PD + PTs */ ··· 2452 2296 * 2453 2297 * @adev: amdgpu_device pointer 2454 2298 * @vm_size: the default vm size if it's set auto 2299 + * @fragment_size_default: Default PTE fragment size 2300 + * @max_level: max VMPT level 2301 + * @max_bits: max address space size in bits 2302 + * 2455 2303 */ 2456 2304 void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size, 2457 2305 uint32_t fragment_size_default, unsigned max_level, ··· 2523 2363 * @adev: amdgpu_device pointer 2524 2364 * @vm: requested vm 2525 2365 * @vm_context: Indicates if it GFX or Compute context 2366 + * @pasid: Process address space identifier 2526 2367 * 2527 2368 * Init @vm fields. 2369 + * 2370 + * Returns: 2371 + * 0 for success, error for failure. 2528 2372 */ 2529 2373 int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, 2530 2374 int vm_context, unsigned int pasid) ··· 2579 2415 } 2580 2416 DRM_DEBUG_DRIVER("VM update mode is %s\n", 2581 2417 vm->use_cpu_for_update ? "CPU" : "SDMA"); 2582 - WARN_ONCE((vm->use_cpu_for_update & !amdgpu_vm_is_large_bar(adev)), 2418 + WARN_ONCE((vm->use_cpu_for_update & !amdgpu_gmc_vram_full_visible(&adev->gmc)), 2583 2419 "CPU update of VM recommended only for large BAR system\n"); 2584 2420 vm->last_update = NULL; 2585 2421 ··· 2649 2485 /** 2650 2486 * amdgpu_vm_make_compute - Turn a GFX VM into a compute VM 2651 2487 * 2488 + * @adev: amdgpu_device pointer 2489 + * @vm: requested vm 2490 + * 2652 2491 * This only works on GFX VMs that don't have any BOs added and no 2653 2492 * page tables allocated yet. 2654 2493 * ··· 2664 2497 * setting. May leave behind an unused shadow BO for the page 2665 2498 * directory when switching from SDMA updates to CPU updates. 2666 2499 * 2667 - * Returns 0 for success, -errno for errors. 2500 + * Returns: 2501 + * 0 for success, -errno for errors. 2668 2502 */ 2669 2503 int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) 2670 2504 { ··· 2699 2531 vm->pte_support_ats = pte_support_ats; 2700 2532 DRM_DEBUG_DRIVER("VM update mode is %s\n", 2701 2533 vm->use_cpu_for_update ? "CPU" : "SDMA"); 2702 - WARN_ONCE((vm->use_cpu_for_update & !amdgpu_vm_is_large_bar(adev)), 2534 + WARN_ONCE((vm->use_cpu_for_update & !amdgpu_gmc_vram_full_visible(&adev->gmc)), 2703 2535 "CPU update of VM recommended only for large BAR system\n"); 2704 2536 2705 2537 if (vm->pasid) { ··· 2820 2652 * @adev: amdgpu_device pointer 2821 2653 * @pasid: PASID do identify the VM 2822 2654 * 2823 - * This function is expected to be called in interrupt context. Returns 2824 - * true if there was fault credit, false otherwise 2655 + * This function is expected to be called in interrupt context. 2656 + * 2657 + * Returns: 2658 + * True if there was fault credit, false otherwise 2825 2659 */ 2826 2660 bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, 2827 2661 unsigned int pasid) ··· 2877 2707 */ 2878 2708 #ifdef CONFIG_X86_64 2879 2709 if (amdgpu_vm_update_mode == -1) { 2880 - if (amdgpu_vm_is_large_bar(adev)) 2710 + if (amdgpu_gmc_vram_full_visible(&adev->gmc)) 2881 2711 adev->vm_manager.vm_update_mode = 2882 2712 AMDGPU_VM_USE_CPU_FOR_COMPUTE; 2883 2713 else ··· 2907 2737 amdgpu_vmid_mgr_fini(adev); 2908 2738 } 2909 2739 2740 + /** 2741 + * amdgpu_vm_ioctl - Manages VMID reservation for vm hubs. 2742 + * 2743 + * @dev: drm device pointer 2744 + * @data: drm_amdgpu_vm 2745 + * @filp: drm file pointer 2746 + * 2747 + * Returns: 2748 + * 0 for success, -errno for errors. 2749 + */ 2910 2750 int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) 2911 2751 { 2912 2752 union drm_amdgpu_vm *args = data;
+1 -1
drivers/gpu/drm/amd/amdgpu/atom.c
··· 1221 1221 ectx.abort = false; 1222 1222 ectx.last_jump = 0; 1223 1223 if (ws) 1224 - ectx.ws = kcalloc(4, ws, GFP_KERNEL); 1224 + ectx.ws = kcalloc(4, ws, GFP_ATOMIC); 1225 1225 else 1226 1226 ectx.ws = NULL; 1227 1227
+6 -6
drivers/gpu/drm/amd/amdgpu/ci_dpm.c
··· 951 951 else 952 952 pi->battery_state = false; 953 953 954 - if (adev->pm.dpm.ac_power) 954 + if (adev->pm.ac_power) 955 955 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 956 956 else 957 957 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc; 958 958 959 - if (adev->pm.dpm.ac_power == false) { 959 + if (adev->pm.ac_power == false) { 960 960 for (i = 0; i < ps->performance_level_count; i++) { 961 961 if (ps->performance_levels[i].mclk > max_limits->mclk) 962 962 ps->performance_levels[i].mclk = max_limits->mclk; ··· 4078 4078 const struct amdgpu_clock_and_voltage_limits *max_limits; 4079 4079 int i; 4080 4080 4081 - if (adev->pm.dpm.ac_power) 4081 + if (adev->pm.ac_power) 4082 4082 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 4083 4083 else 4084 4084 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc; ··· 4127 4127 const struct amdgpu_clock_and_voltage_limits *max_limits; 4128 4128 int i; 4129 4129 4130 - if (adev->pm.dpm.ac_power) 4130 + if (adev->pm.ac_power) 4131 4131 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 4132 4132 else 4133 4133 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc; ··· 4160 4160 const struct amdgpu_clock_and_voltage_limits *max_limits; 4161 4161 int i; 4162 4162 4163 - if (adev->pm.dpm.ac_power) 4163 + if (adev->pm.ac_power) 4164 4164 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 4165 4165 else 4166 4166 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc; ··· 4191 4191 const struct amdgpu_clock_and_voltage_limits *max_limits; 4192 4192 int i; 4193 4193 4194 - if (adev->pm.dpm.ac_power) 4194 + if (adev->pm.ac_power) 4195 4195 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 4196 4196 else 4197 4197 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
+4 -4
drivers/gpu/drm/amd/amdgpu/cik.c
··· 2003 2003 amdgpu_device_ip_block_add(adev, &gmc_v7_0_ip_block); 2004 2004 amdgpu_device_ip_block_add(adev, &cik_ih_ip_block); 2005 2005 if (amdgpu_dpm == -1) 2006 - amdgpu_device_ip_block_add(adev, &ci_smu_ip_block); 2007 - else 2008 2006 amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); 2007 + else 2008 + amdgpu_device_ip_block_add(adev, &ci_smu_ip_block); 2009 2009 if (adev->enable_virtual_display) 2010 2010 amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); 2011 2011 #if defined(CONFIG_DRM_AMD_DC) ··· 2024 2024 amdgpu_device_ip_block_add(adev, &gmc_v7_0_ip_block); 2025 2025 amdgpu_device_ip_block_add(adev, &cik_ih_ip_block); 2026 2026 if (amdgpu_dpm == -1) 2027 - amdgpu_device_ip_block_add(adev, &ci_smu_ip_block); 2028 - else 2029 2027 amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); 2028 + else 2029 + amdgpu_device_ip_block_add(adev, &ci_smu_ip_block); 2030 2030 if (adev->enable_virtual_display) 2031 2031 amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); 2032 2032 #if defined(CONFIG_DRM_AMD_DC)
+203 -14
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
··· 866 866 struct amdgpu_device *adev = ring->adev; 867 867 struct amdgpu_ib ib; 868 868 struct dma_fence *f = NULL; 869 - uint32_t scratch; 870 - uint32_t tmp = 0; 869 + 870 + unsigned int index; 871 + uint64_t gpu_addr; 872 + uint32_t tmp; 871 873 long r; 872 874 873 - r = amdgpu_gfx_scratch_get(adev, &scratch); 875 + r = amdgpu_device_wb_get(adev, &index); 874 876 if (r) { 875 - DRM_ERROR("amdgpu: failed to get scratch reg (%ld).\n", r); 877 + dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); 876 878 return r; 877 879 } 878 - WREG32(scratch, 0xCAFEDEAD); 880 + 881 + gpu_addr = adev->wb.gpu_addr + (index * 4); 882 + adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); 879 883 memset(&ib, 0, sizeof(ib)); 880 - r = amdgpu_ib_get(adev, NULL, 256, &ib); 884 + r = amdgpu_ib_get(adev, NULL, 16, &ib); 881 885 if (r) { 882 886 DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); 883 887 goto err1; 884 888 } 885 - ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); 886 - ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START)); 887 - ib.ptr[2] = 0xDEADBEEF; 888 - ib.length_dw = 3; 889 + ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3); 890 + ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; 891 + ib.ptr[2] = lower_32_bits(gpu_addr); 892 + ib.ptr[3] = upper_32_bits(gpu_addr); 893 + ib.ptr[4] = 0xDEADBEEF; 894 + ib.length_dw = 5; 889 895 890 896 r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f); 891 897 if (r) ··· 906 900 DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); 907 901 goto err2; 908 902 } 909 - tmp = RREG32(scratch); 903 + 904 + tmp = adev->wb.wb[index]; 910 905 if (tmp == 0xDEADBEEF) { 911 906 DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); 912 907 r = 0; 913 908 } else { 914 - DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n", 915 - scratch, tmp); 909 + DRM_ERROR("ib test on ring %d failed\n", ring->idx); 916 910 r = -EINVAL; 917 911 } 912 + 918 913 err2: 919 914 amdgpu_ib_free(adev, &ib, NULL); 920 915 dma_fence_put(f); 921 916 err1: 922 - amdgpu_gfx_scratch_free(adev, scratch); 917 + amdgpu_device_wb_free(adev, index); 923 918 return r; 924 919 } 925 920 ··· 2054 2047 &adev->gfx.priv_inst_irq); 2055 2048 if (r) 2056 2049 return r; 2050 + 2051 + /* Add CP EDC/ECC irq */ 2052 + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 197, 2053 + &adev->gfx.cp_ecc_error_irq); 2054 + if (r) 2055 + return r; 2056 + 2057 + /* SQ interrupts. */ 2058 + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 239, 2059 + &adev->gfx.sq_irq); 2060 + if (r) { 2061 + DRM_ERROR("amdgpu_irq_add() for SQ failed: %d\n", r); 2062 + return r; 2063 + } 2057 2064 2058 2065 adev->gfx.gfx_current_status = AMDGPU_GFX_NORMAL_MODE; 2059 2066 ··· 5132 5111 amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); 5133 5112 amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); 5134 5113 5114 + amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0); 5115 + 5116 + amdgpu_irq_put(adev, &adev->gfx.sq_irq, 0); 5117 + 5135 5118 /* disable KCQ to avoid CPC touch memory not valid anymore */ 5136 5119 for (i = 0; i < adev->gfx.num_compute_rings; i++) 5137 5120 gfx_v8_0_kcq_disable(&adev->gfx.kiq.ring, &adev->gfx.compute_ring[i]); ··· 5566 5541 r = gfx_v8_0_do_edc_gpr_workarounds(adev); 5567 5542 if (r) 5568 5543 return r; 5544 + 5545 + r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0); 5546 + if (r) { 5547 + DRM_ERROR("amdgpu_irq_get() failed to get IRQ for EDC, r: %d.\n", r); 5548 + return r; 5549 + } 5550 + 5551 + r = amdgpu_irq_get(adev, &adev->gfx.sq_irq, 0); 5552 + if (r) { 5553 + DRM_ERROR( 5554 + "amdgpu_irq_get() failed to get IRQ for SQ, r: %d.\n", 5555 + r); 5556 + return r; 5557 + } 5569 5558 5570 5559 amdgpu_device_ip_set_powergating_state(adev, 5571 5560 AMD_IP_BLOCK_TYPE_GFX, ··· 6826 6787 return 0; 6827 6788 } 6828 6789 6790 + static int gfx_v8_0_set_cp_ecc_int_state(struct amdgpu_device *adev, 6791 + struct amdgpu_irq_src *source, 6792 + unsigned int type, 6793 + enum amdgpu_interrupt_state state) 6794 + { 6795 + int enable_flag; 6796 + 6797 + switch (state) { 6798 + case AMDGPU_IRQ_STATE_DISABLE: 6799 + enable_flag = 0; 6800 + break; 6801 + 6802 + case AMDGPU_IRQ_STATE_ENABLE: 6803 + enable_flag = 1; 6804 + break; 6805 + 6806 + default: 6807 + return -EINVAL; 6808 + } 6809 + 6810 + WREG32_FIELD(CP_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, enable_flag); 6811 + WREG32_FIELD(CP_INT_CNTL_RING0, CP_ECC_ERROR_INT_ENABLE, enable_flag); 6812 + WREG32_FIELD(CP_INT_CNTL_RING1, CP_ECC_ERROR_INT_ENABLE, enable_flag); 6813 + WREG32_FIELD(CP_INT_CNTL_RING2, CP_ECC_ERROR_INT_ENABLE, enable_flag); 6814 + WREG32_FIELD(CPC_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, enable_flag); 6815 + WREG32_FIELD(CP_ME1_PIPE0_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6816 + enable_flag); 6817 + WREG32_FIELD(CP_ME1_PIPE1_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6818 + enable_flag); 6819 + WREG32_FIELD(CP_ME1_PIPE2_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6820 + enable_flag); 6821 + WREG32_FIELD(CP_ME1_PIPE3_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6822 + enable_flag); 6823 + WREG32_FIELD(CP_ME2_PIPE0_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6824 + enable_flag); 6825 + WREG32_FIELD(CP_ME2_PIPE1_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6826 + enable_flag); 6827 + WREG32_FIELD(CP_ME2_PIPE2_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6828 + enable_flag); 6829 + WREG32_FIELD(CP_ME2_PIPE3_INT_CNTL, CP_ECC_ERROR_INT_ENABLE, 6830 + enable_flag); 6831 + 6832 + return 0; 6833 + } 6834 + 6835 + static int gfx_v8_0_set_sq_int_state(struct amdgpu_device *adev, 6836 + struct amdgpu_irq_src *source, 6837 + unsigned int type, 6838 + enum amdgpu_interrupt_state state) 6839 + { 6840 + int enable_flag; 6841 + 6842 + switch (state) { 6843 + case AMDGPU_IRQ_STATE_DISABLE: 6844 + enable_flag = 1; 6845 + break; 6846 + 6847 + case AMDGPU_IRQ_STATE_ENABLE: 6848 + enable_flag = 0; 6849 + break; 6850 + 6851 + default: 6852 + return -EINVAL; 6853 + } 6854 + 6855 + WREG32_FIELD(SQ_INTERRUPT_MSG_CTRL, STALL, 6856 + enable_flag); 6857 + 6858 + return 0; 6859 + } 6860 + 6829 6861 static int gfx_v8_0_eop_irq(struct amdgpu_device *adev, 6830 6862 struct amdgpu_irq_src *source, 6831 6863 struct amdgpu_iv_entry *entry) ··· 6944 6834 { 6945 6835 DRM_ERROR("Illegal instruction in command stream\n"); 6946 6836 schedule_work(&adev->reset_work); 6837 + return 0; 6838 + } 6839 + 6840 + static int gfx_v8_0_cp_ecc_error_irq(struct amdgpu_device *adev, 6841 + struct amdgpu_irq_src *source, 6842 + struct amdgpu_iv_entry *entry) 6843 + { 6844 + DRM_ERROR("CP EDC/ECC error detected."); 6845 + return 0; 6846 + } 6847 + 6848 + static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, 6849 + struct amdgpu_irq_src *source, 6850 + struct amdgpu_iv_entry *entry) 6851 + { 6852 + u8 enc, se_id; 6853 + char type[20]; 6854 + 6855 + /* Parse all fields according to SQ_INTERRUPT* registers */ 6856 + enc = (entry->src_data[0] >> 26) & 0x3; 6857 + se_id = (entry->src_data[0] >> 24) & 0x3; 6858 + 6859 + switch (enc) { 6860 + case 0: 6861 + DRM_INFO("SQ general purpose intr detected:" 6862 + "se_id %d, immed_overflow %d, host_reg_overflow %d," 6863 + "host_cmd_overflow %d, cmd_timestamp %d," 6864 + "reg_timestamp %d, thread_trace_buff_full %d," 6865 + "wlt %d, thread_trace %d.\n", 6866 + se_id, 6867 + (entry->src_data[0] >> 7) & 0x1, 6868 + (entry->src_data[0] >> 6) & 0x1, 6869 + (entry->src_data[0] >> 5) & 0x1, 6870 + (entry->src_data[0] >> 4) & 0x1, 6871 + (entry->src_data[0] >> 3) & 0x1, 6872 + (entry->src_data[0] >> 2) & 0x1, 6873 + (entry->src_data[0] >> 1) & 0x1, 6874 + entry->src_data[0] & 0x1 6875 + ); 6876 + break; 6877 + case 1: 6878 + case 2: 6879 + 6880 + if (enc == 1) 6881 + sprintf(type, "instruction intr"); 6882 + else 6883 + sprintf(type, "EDC/ECC error"); 6884 + 6885 + DRM_INFO( 6886 + "SQ %s detected: " 6887 + "se_id %d, cu_id %d, simd_id %d, wave_id %d, vm_id %d\n", 6888 + type, se_id, 6889 + (entry->src_data[0] >> 20) & 0xf, 6890 + (entry->src_data[0] >> 18) & 0x3, 6891 + (entry->src_data[0] >> 14) & 0xf, 6892 + (entry->src_data[0] >> 10) & 0xf 6893 + ); 6894 + break; 6895 + default: 6896 + DRM_ERROR("SQ invalid encoding type\n."); 6897 + return -EINVAL; 6898 + } 6899 + 6947 6900 return 0; 6948 6901 } 6949 6902 ··· 7210 7037 .process = gfx_v8_0_kiq_irq, 7211 7038 }; 7212 7039 7040 + static const struct amdgpu_irq_src_funcs gfx_v8_0_cp_ecc_error_irq_funcs = { 7041 + .set = gfx_v8_0_set_cp_ecc_int_state, 7042 + .process = gfx_v8_0_cp_ecc_error_irq, 7043 + }; 7044 + 7045 + static const struct amdgpu_irq_src_funcs gfx_v8_0_sq_irq_funcs = { 7046 + .set = gfx_v8_0_set_sq_int_state, 7047 + .process = gfx_v8_0_sq_irq, 7048 + }; 7049 + 7213 7050 static void gfx_v8_0_set_irq_funcs(struct amdgpu_device *adev) 7214 7051 { 7215 7052 adev->gfx.eop_irq.num_types = AMDGPU_CP_IRQ_LAST; ··· 7233 7050 7234 7051 adev->gfx.kiq.irq.num_types = AMDGPU_CP_KIQ_IRQ_LAST; 7235 7052 adev->gfx.kiq.irq.funcs = &gfx_v8_0_kiq_irq_funcs; 7053 + 7054 + adev->gfx.cp_ecc_error_irq.num_types = 1; 7055 + adev->gfx.cp_ecc_error_irq.funcs = &gfx_v8_0_cp_ecc_error_irq_funcs; 7056 + 7057 + adev->gfx.sq_irq.num_types = 1; 7058 + adev->gfx.sq_irq.funcs = &gfx_v8_0_sq_irq_funcs; 7236 7059 } 7237 7060 7238 7061 static void gfx_v8_0_set_rlc_funcs(struct amdgpu_device *adev)
+1 -1
drivers/gpu/drm/amd/amdgpu/kv_dpm.c
··· 1921 1921 int ret; 1922 1922 1923 1923 if (pi->bapm_enable) { 1924 - ret = amdgpu_kv_smc_bapm_enable(adev, adev->pm.dpm.ac_power); 1924 + ret = amdgpu_kv_smc_bapm_enable(adev, adev->pm.ac_power); 1925 1925 if (ret) { 1926 1926 DRM_ERROR("amdgpu_kv_smc_bapm_enable failed\n"); 1927 1927 return ret;
+2 -2
drivers/gpu/drm/amd/amdgpu/si_dpm.c
··· 3480 3480 disable_sclk_switching = true; 3481 3481 } 3482 3482 3483 - if (adev->pm.dpm.ac_power) 3483 + if (adev->pm.ac_power) 3484 3484 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 3485 3485 else 3486 3486 max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc; ··· 3489 3489 if (ps->performance_levels[i].vddc > ps->performance_levels[i+1].vddc) 3490 3490 ps->performance_levels[i].vddc = ps->performance_levels[i+1].vddc; 3491 3491 } 3492 - if (adev->pm.dpm.ac_power == false) { 3492 + if (adev->pm.ac_power == false) { 3493 3493 for (i = 0; i < ps->performance_level_count; i++) { 3494 3494 if (ps->performance_levels[i].mclk > max_limits->mclk) 3495 3495 ps->performance_levels[i].mclk = max_limits->mclk;
+23
drivers/gpu/drm/amd/amdgpu/soc15d.h
··· 53 53 54 54 #define PACKET3_COMPUTE(op, n) (PACKET3(op, n) | 1 << 1) 55 55 56 + #define PACKETJ_CONDITION_CHECK0 0 57 + #define PACKETJ_CONDITION_CHECK1 1 58 + #define PACKETJ_CONDITION_CHECK2 2 59 + #define PACKETJ_CONDITION_CHECK3 3 60 + #define PACKETJ_CONDITION_CHECK4 4 61 + #define PACKETJ_CONDITION_CHECK5 5 62 + #define PACKETJ_CONDITION_CHECK6 6 63 + #define PACKETJ_CONDITION_CHECK7 7 64 + 65 + #define PACKETJ_TYPE0 0 66 + #define PACKETJ_TYPE1 1 67 + #define PACKETJ_TYPE2 2 68 + #define PACKETJ_TYPE3 3 69 + #define PACKETJ_TYPE4 4 70 + #define PACKETJ_TYPE5 5 71 + #define PACKETJ_TYPE6 6 72 + #define PACKETJ_TYPE7 7 73 + 74 + #define PACKETJ(reg, r, cond, type) ((reg & 0x3FFFF) | \ 75 + ((r & 0x3F) << 18) | \ 76 + ((cond & 0xF) << 24) | \ 77 + ((type & 0xF) << 28)) 78 + 56 79 /* Packet 3 types */ 57 80 #define PACKET3_NOP 0x10 58 81 #define PACKET3_SET_BASE 0x11
+457
drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
··· 38 38 static int vcn_v1_0_stop(struct amdgpu_device *adev); 39 39 static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); 40 40 static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); 41 + static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev); 41 42 static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); 43 + static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr); 42 44 43 45 /** 44 46 * vcn_v1_0_early_init - set function pointers ··· 57 55 58 56 vcn_v1_0_set_dec_ring_funcs(adev); 59 57 vcn_v1_0_set_enc_ring_funcs(adev); 58 + vcn_v1_0_set_jpeg_ring_funcs(adev); 60 59 vcn_v1_0_set_irq_funcs(adev); 61 60 62 61 return 0; ··· 89 86 return r; 90 87 } 91 88 89 + /* VCN JPEG TRAP */ 90 + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->vcn.irq); 91 + if (r) 92 + return r; 93 + 92 94 r = amdgpu_vcn_sw_init(adev); 93 95 if (r) 94 96 return r; ··· 115 107 if (r) 116 108 return r; 117 109 } 110 + 111 + ring = &adev->vcn.ring_jpeg; 112 + sprintf(ring->name, "vcn_jpeg"); 113 + r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.irq, 0); 114 + if (r) 115 + return r; 118 116 119 117 return r; 120 118 } ··· 174 160 ring->ready = false; 175 161 goto done; 176 162 } 163 + } 164 + 165 + ring = &adev->vcn.ring_jpeg; 166 + ring->ready = true; 167 + r = amdgpu_ring_test_ring(ring); 168 + if (r) { 169 + ring->ready = false; 170 + goto done; 177 171 } 178 172 179 173 done: ··· 751 729 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 752 730 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4); 753 731 732 + ring = &adev->vcn.ring_jpeg; 733 + WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0); 734 + WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 735 + WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr)); 736 + WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr)); 737 + WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, 0); 738 + WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, 0); 739 + WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L); 740 + 741 + /* initialize wptr */ 742 + ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); 743 + 744 + /* copy patch commands to the jpeg ring */ 745 + vcn_v1_0_jpeg_ring_set_patch_ring(ring, 746 + (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission)); 747 + 754 748 return 0; 755 749 } 756 750 ··· 1164 1126 amdgpu_ring_write(ring, val); 1165 1127 } 1166 1128 1129 + 1130 + /** 1131 + * vcn_v1_0_jpeg_ring_get_rptr - get read pointer 1132 + * 1133 + * @ring: amdgpu_ring pointer 1134 + * 1135 + * Returns the current hardware read pointer 1136 + */ 1137 + static uint64_t vcn_v1_0_jpeg_ring_get_rptr(struct amdgpu_ring *ring) 1138 + { 1139 + struct amdgpu_device *adev = ring->adev; 1140 + 1141 + return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR); 1142 + } 1143 + 1144 + /** 1145 + * vcn_v1_0_jpeg_ring_get_wptr - get write pointer 1146 + * 1147 + * @ring: amdgpu_ring pointer 1148 + * 1149 + * Returns the current hardware write pointer 1150 + */ 1151 + static uint64_t vcn_v1_0_jpeg_ring_get_wptr(struct amdgpu_ring *ring) 1152 + { 1153 + struct amdgpu_device *adev = ring->adev; 1154 + 1155 + return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); 1156 + } 1157 + 1158 + /** 1159 + * vcn_v1_0_jpeg_ring_set_wptr - set write pointer 1160 + * 1161 + * @ring: amdgpu_ring pointer 1162 + * 1163 + * Commits the write pointer to the hardware 1164 + */ 1165 + static void vcn_v1_0_jpeg_ring_set_wptr(struct amdgpu_ring *ring) 1166 + { 1167 + struct amdgpu_device *adev = ring->adev; 1168 + 1169 + WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); 1170 + } 1171 + 1172 + /** 1173 + * vcn_v1_0_jpeg_ring_insert_start - insert a start command 1174 + * 1175 + * @ring: amdgpu_ring pointer 1176 + * 1177 + * Write a start command to the ring. 1178 + */ 1179 + static void vcn_v1_0_jpeg_ring_insert_start(struct amdgpu_ring *ring) 1180 + { 1181 + struct amdgpu_device *adev = ring->adev; 1182 + 1183 + amdgpu_ring_write(ring, 1184 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 1185 + amdgpu_ring_write(ring, 0x68e04); 1186 + 1187 + amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 1188 + amdgpu_ring_write(ring, 0x80010000); 1189 + } 1190 + 1191 + /** 1192 + * vcn_v1_0_jpeg_ring_insert_end - insert a end command 1193 + * 1194 + * @ring: amdgpu_ring pointer 1195 + * 1196 + * Write a end command to the ring. 1197 + */ 1198 + static void vcn_v1_0_jpeg_ring_insert_end(struct amdgpu_ring *ring) 1199 + { 1200 + struct amdgpu_device *adev = ring->adev; 1201 + 1202 + amdgpu_ring_write(ring, 1203 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 1204 + amdgpu_ring_write(ring, 0x68e04); 1205 + 1206 + amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 1207 + amdgpu_ring_write(ring, 0x00010000); 1208 + } 1209 + 1210 + /** 1211 + * vcn_v1_0_jpeg_ring_emit_fence - emit an fence & trap command 1212 + * 1213 + * @ring: amdgpu_ring pointer 1214 + * @fence: fence to emit 1215 + * 1216 + * Write a fence and a trap command to the ring. 1217 + */ 1218 + static void vcn_v1_0_jpeg_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, 1219 + unsigned flags) 1220 + { 1221 + struct amdgpu_device *adev = ring->adev; 1222 + 1223 + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); 1224 + 1225 + amdgpu_ring_write(ring, 1226 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0)); 1227 + amdgpu_ring_write(ring, seq); 1228 + 1229 + amdgpu_ring_write(ring, 1230 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0)); 1231 + amdgpu_ring_write(ring, seq); 1232 + 1233 + amdgpu_ring_write(ring, 1234 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 1235 + amdgpu_ring_write(ring, lower_32_bits(addr)); 1236 + 1237 + amdgpu_ring_write(ring, 1238 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 1239 + amdgpu_ring_write(ring, upper_32_bits(addr)); 1240 + 1241 + amdgpu_ring_write(ring, 1242 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0)); 1243 + amdgpu_ring_write(ring, 0x8); 1244 + 1245 + amdgpu_ring_write(ring, 1246 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); 1247 + amdgpu_ring_write(ring, 0); 1248 + 1249 + amdgpu_ring_write(ring, 1250 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 1251 + amdgpu_ring_write(ring, 0x01400200); 1252 + 1253 + amdgpu_ring_write(ring, 1254 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 1255 + amdgpu_ring_write(ring, seq); 1256 + 1257 + amdgpu_ring_write(ring, 1258 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 1259 + amdgpu_ring_write(ring, lower_32_bits(addr)); 1260 + 1261 + amdgpu_ring_write(ring, 1262 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 1263 + amdgpu_ring_write(ring, upper_32_bits(addr)); 1264 + 1265 + amdgpu_ring_write(ring, 1266 + PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2)); 1267 + amdgpu_ring_write(ring, 0xffffffff); 1268 + 1269 + amdgpu_ring_write(ring, 1270 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 1271 + amdgpu_ring_write(ring, 0x3fbc); 1272 + 1273 + amdgpu_ring_write(ring, 1274 + PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 1275 + amdgpu_ring_write(ring, 0x1); 1276 + } 1277 + 1278 + /** 1279 + * vcn_v1_0_jpeg_ring_emit_ib - execute indirect buffer 1280 + * 1281 + * @ring: amdgpu_ring pointer 1282 + * @ib: indirect buffer to execute 1283 + * 1284 + * Write ring commands to execute the indirect buffer. 1285 + */ 1286 + static void vcn_v1_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring, 1287 + struct amdgpu_ib *ib, 1288 + unsigned vmid, bool ctx_switch) 1289 + { 1290 + struct amdgpu_device *adev = ring->adev; 1291 + 1292 + amdgpu_ring_write(ring, 1293 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); 1294 + amdgpu_ring_write(ring, (vmid | (vmid << 4))); 1295 + 1296 + amdgpu_ring_write(ring, 1297 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0)); 1298 + amdgpu_ring_write(ring, (vmid | (vmid << 4))); 1299 + 1300 + amdgpu_ring_write(ring, 1301 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 1302 + amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); 1303 + 1304 + amdgpu_ring_write(ring, 1305 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 1306 + amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); 1307 + 1308 + amdgpu_ring_write(ring, 1309 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0)); 1310 + amdgpu_ring_write(ring, ib->length_dw); 1311 + 1312 + amdgpu_ring_write(ring, 1313 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 1314 + amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); 1315 + 1316 + amdgpu_ring_write(ring, 1317 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 1318 + amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr)); 1319 + 1320 + amdgpu_ring_write(ring, 1321 + PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2)); 1322 + amdgpu_ring_write(ring, 0); 1323 + 1324 + amdgpu_ring_write(ring, 1325 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 1326 + amdgpu_ring_write(ring, 0x01400200); 1327 + 1328 + amdgpu_ring_write(ring, 1329 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 1330 + amdgpu_ring_write(ring, 0x2); 1331 + 1332 + amdgpu_ring_write(ring, 1333 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); 1334 + amdgpu_ring_write(ring, 0x2); 1335 + } 1336 + 1337 + static void vcn_v1_0_jpeg_ring_emit_reg_wait(struct amdgpu_ring *ring, 1338 + uint32_t reg, uint32_t val, 1339 + uint32_t mask) 1340 + { 1341 + struct amdgpu_device *adev = ring->adev; 1342 + uint32_t reg_offset = (reg << 2); 1343 + 1344 + amdgpu_ring_write(ring, 1345 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 1346 + amdgpu_ring_write(ring, 0x01400200); 1347 + 1348 + amdgpu_ring_write(ring, 1349 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 1350 + amdgpu_ring_write(ring, val); 1351 + 1352 + amdgpu_ring_write(ring, 1353 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 1354 + if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 1355 + ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 1356 + amdgpu_ring_write(ring, 0); 1357 + amdgpu_ring_write(ring, 1358 + PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3)); 1359 + } else { 1360 + amdgpu_ring_write(ring, reg_offset); 1361 + amdgpu_ring_write(ring, 1362 + PACKETJ(0, 0, 0, PACKETJ_TYPE3)); 1363 + } 1364 + amdgpu_ring_write(ring, mask); 1365 + } 1366 + 1367 + static void vcn_v1_0_jpeg_ring_emit_vm_flush(struct amdgpu_ring *ring, 1368 + unsigned vmid, uint64_t pd_addr) 1369 + { 1370 + struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub]; 1371 + uint32_t data0, data1, mask; 1372 + 1373 + pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); 1374 + 1375 + /* wait for register write */ 1376 + data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2; 1377 + data1 = lower_32_bits(pd_addr); 1378 + mask = 0xffffffff; 1379 + vcn_v1_0_jpeg_ring_emit_reg_wait(ring, data0, data1, mask); 1380 + } 1381 + 1382 + static void vcn_v1_0_jpeg_ring_emit_wreg(struct amdgpu_ring *ring, 1383 + uint32_t reg, uint32_t val) 1384 + { 1385 + struct amdgpu_device *adev = ring->adev; 1386 + uint32_t reg_offset = (reg << 2); 1387 + 1388 + amdgpu_ring_write(ring, 1389 + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 1390 + if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 1391 + ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 1392 + amdgpu_ring_write(ring, 0); 1393 + amdgpu_ring_write(ring, 1394 + PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0)); 1395 + } else { 1396 + amdgpu_ring_write(ring, reg_offset); 1397 + amdgpu_ring_write(ring, 1398 + PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 1399 + } 1400 + amdgpu_ring_write(ring, val); 1401 + } 1402 + 1403 + static void vcn_v1_0_jpeg_ring_nop(struct amdgpu_ring *ring, uint32_t count) 1404 + { 1405 + int i; 1406 + 1407 + WARN_ON(ring->wptr % 2 || count % 2); 1408 + 1409 + for (i = 0; i < count / 2; i++) { 1410 + amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6)); 1411 + amdgpu_ring_write(ring, 0); 1412 + } 1413 + } 1414 + 1415 + static void vcn_v1_0_jpeg_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val) 1416 + { 1417 + struct amdgpu_device *adev = ring->adev; 1418 + ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0); 1419 + if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 1420 + ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 1421 + ring->ring[(*ptr)++] = 0; 1422 + ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0); 1423 + } else { 1424 + ring->ring[(*ptr)++] = reg_offset; 1425 + ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0); 1426 + } 1427 + ring->ring[(*ptr)++] = val; 1428 + } 1429 + 1430 + static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr) 1431 + { 1432 + struct amdgpu_device *adev = ring->adev; 1433 + 1434 + uint32_t reg, reg_offset, val, mask, i; 1435 + 1436 + // 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW 1437 + reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW); 1438 + reg_offset = (reg << 2); 1439 + val = lower_32_bits(ring->gpu_addr); 1440 + vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val); 1441 + 1442 + // 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH 1443 + reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH); 1444 + reg_offset = (reg << 2); 1445 + val = upper_32_bits(ring->gpu_addr); 1446 + vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val); 1447 + 1448 + // 3rd to 5th: issue MEM_READ commands 1449 + for (i = 0; i <= 2; i++) { 1450 + ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2); 1451 + ring->ring[ptr++] = 0; 1452 + } 1453 + 1454 + // 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability 1455 + reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL); 1456 + reg_offset = (reg << 2); 1457 + val = 0x13; 1458 + vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val); 1459 + 1460 + // 7th: program mmUVD_JRBC_RB_REF_DATA 1461 + reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA); 1462 + reg_offset = (reg << 2); 1463 + val = 0x1; 1464 + vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val); 1465 + 1466 + // 8th: issue conditional register read mmUVD_JRBC_RB_CNTL 1467 + reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL); 1468 + reg_offset = (reg << 2); 1469 + val = 0x1; 1470 + mask = 0x1; 1471 + 1472 + ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0); 1473 + ring->ring[ptr++] = 0x01400200; 1474 + ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0); 1475 + ring->ring[ptr++] = val; 1476 + ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0); 1477 + if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 1478 + ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 1479 + ring->ring[ptr++] = 0; 1480 + ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3); 1481 + } else { 1482 + ring->ring[ptr++] = reg_offset; 1483 + ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3); 1484 + } 1485 + ring->ring[ptr++] = mask; 1486 + 1487 + //9th to 21st: insert no-op 1488 + for (i = 0; i <= 12; i++) { 1489 + ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); 1490 + ring->ring[ptr++] = 0; 1491 + } 1492 + 1493 + //22nd: reset mmUVD_JRBC_RB_RPTR 1494 + reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_RPTR); 1495 + reg_offset = (reg << 2); 1496 + val = 0; 1497 + vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val); 1498 + 1499 + //23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch 1500 + reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL); 1501 + reg_offset = (reg << 2); 1502 + val = 0x12; 1503 + vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val); 1504 + } 1505 + 1167 1506 static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev, 1168 1507 struct amdgpu_irq_src *source, 1169 1508 unsigned type, ··· 1564 1149 break; 1565 1150 case 120: 1566 1151 amdgpu_fence_process(&adev->vcn.ring_enc[1]); 1152 + break; 1153 + case 126: 1154 + amdgpu_fence_process(&adev->vcn.ring_jpeg); 1567 1155 break; 1568 1156 default: 1569 1157 DRM_ERROR("Unhandled interrupt: %d %d\n", ··· 1691 1273 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 1692 1274 }; 1693 1275 1276 + static const struct amdgpu_ring_funcs vcn_v1_0_jpeg_ring_vm_funcs = { 1277 + .type = AMDGPU_RING_TYPE_VCN_JPEG, 1278 + .align_mask = 0xf, 1279 + .nop = PACKET0(0x81ff, 0), 1280 + .support_64bit_ptrs = false, 1281 + .vmhub = AMDGPU_MMHUB, 1282 + .extra_dw = 64, 1283 + .get_rptr = vcn_v1_0_jpeg_ring_get_rptr, 1284 + .get_wptr = vcn_v1_0_jpeg_ring_get_wptr, 1285 + .set_wptr = vcn_v1_0_jpeg_ring_set_wptr, 1286 + .emit_frame_size = 1287 + 6 + 6 + /* hdp invalidate / flush */ 1288 + SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 1289 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 1290 + 8 + /* vcn_v1_0_dec_ring_emit_vm_flush */ 1291 + 14 + 14 + /* vcn_v1_0_dec_ring_emit_fence x2 vm fence */ 1292 + 6, 1293 + .emit_ib_size = 22, /* vcn_v1_0_dec_ring_emit_ib */ 1294 + .emit_ib = vcn_v1_0_jpeg_ring_emit_ib, 1295 + .emit_fence = vcn_v1_0_jpeg_ring_emit_fence, 1296 + .emit_vm_flush = vcn_v1_0_jpeg_ring_emit_vm_flush, 1297 + .test_ring = amdgpu_vcn_jpeg_ring_test_ring, 1298 + .test_ib = amdgpu_vcn_jpeg_ring_test_ib, 1299 + .insert_nop = vcn_v1_0_jpeg_ring_nop, 1300 + .insert_start = vcn_v1_0_jpeg_ring_insert_start, 1301 + .insert_end = vcn_v1_0_jpeg_ring_insert_end, 1302 + .pad_ib = amdgpu_ring_generic_pad_ib, 1303 + .begin_use = amdgpu_vcn_ring_begin_use, 1304 + .end_use = amdgpu_vcn_ring_end_use, 1305 + .emit_wreg = vcn_v1_0_jpeg_ring_emit_wreg, 1306 + .emit_reg_wait = vcn_v1_0_jpeg_ring_emit_reg_wait, 1307 + }; 1308 + 1694 1309 static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) 1695 1310 { 1696 1311 adev->vcn.ring_dec.funcs = &vcn_v1_0_dec_ring_vm_funcs; ··· 1738 1287 adev->vcn.ring_enc[i].funcs = &vcn_v1_0_enc_ring_vm_funcs; 1739 1288 1740 1289 DRM_INFO("VCN encode is enabled in VM mode\n"); 1290 + } 1291 + 1292 + static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev) 1293 + { 1294 + adev->vcn.ring_jpeg.funcs = &vcn_v1_0_jpeg_ring_vm_funcs; 1295 + DRM_INFO("VCN jpeg decode is enabled in VM mode\n"); 1741 1296 } 1742 1297 1743 1298 static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = {
+1 -10
drivers/gpu/drm/amd/display/Kconfig
··· 9 9 support for AMDGPU. This adds required support for Vega and 10 10 Raven ASICs. 11 11 12 - config DRM_AMD_DC_FBC 13 - bool "AMD FBC - Enable Frame Buffer Compression" 14 - depends on DRM_AMD_DC 15 - help 16 - Choose this option if you want to use frame buffer compression 17 - support. 18 - This is a power optimisation feature, check its availability 19 - on your hardware before enabling this option. 20 - 21 - 22 12 config DRM_AMD_DC_DCN1_0 23 13 bool "DCN 1.0 Raven family" 24 14 depends on DRM_AMD_DC && X86 15 + default y 25 16 help 26 17 Choose this option if you want to have 27 18 RV family for display engine
+7 -6
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 347 347 drm_kms_helper_hotplug_event(dev); 348 348 } 349 349 350 - #if defined(CONFIG_DRM_AMD_DC_FBC) 351 350 /* Allocate memory for FBC compressed data */ 352 351 static void amdgpu_dm_fbc_init(struct drm_connector *connector) 353 352 { ··· 387 388 } 388 389 389 390 } 390 - #endif 391 391 392 392 393 393 /* Init display KMS ··· 3424 3426 struct edid *edid = amdgpu_dm_connector->edid; 3425 3427 3426 3428 encoder = helper->best_encoder(connector); 3427 - amdgpu_dm_connector_ddc_get_modes(connector, edid); 3428 - amdgpu_dm_connector_add_common_modes(encoder, connector); 3429 3429 3430 - #if defined(CONFIG_DRM_AMD_DC_FBC) 3430 + if (!edid || !drm_edid_is_valid(edid)) { 3431 + drm_add_modes_noedid(connector, 640, 480); 3432 + } else { 3433 + amdgpu_dm_connector_ddc_get_modes(connector, edid); 3434 + amdgpu_dm_connector_add_common_modes(encoder, connector); 3435 + } 3431 3436 amdgpu_dm_fbc_init(connector); 3432 - #endif 3437 + 3433 3438 return amdgpu_dm_connector->num_modes; 3434 3439 } 3435 3440
+1 -4
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
··· 72 72 struct work_struct work; 73 73 }; 74 74 75 - #if defined(CONFIG_DRM_AMD_DC_FBC) 76 75 struct dm_comressor_info { 77 76 void *cpu_addr; 78 77 struct amdgpu_bo *bo_ptr; 79 78 uint64_t gpu_addr; 80 79 }; 81 - #endif 82 80 83 81 84 82 struct amdgpu_display_manager { ··· 127 129 * Caches device atomic state for suspend/resume 128 130 */ 129 131 struct drm_atomic_state *cached_state; 130 - #if defined(CONFIG_DRM_AMD_DC_FBC) 132 + 131 133 struct dm_comressor_info compressor; 132 - #endif 133 134 }; 134 135 135 136 struct amdgpu_dm_connector {
+28
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
··· 497 497 DRM_ERROR("EDID err: %d, on connector: %s", 498 498 edid_status, 499 499 aconnector->base.name); 500 + if (link->aux_mode) { 501 + union test_request test_request = {0}; 502 + union test_response test_response = {0}; 503 + 504 + dm_helpers_dp_read_dpcd(ctx, 505 + link, 506 + DP_TEST_REQUEST, 507 + &test_request.raw, 508 + sizeof(union test_request)); 509 + 510 + if (!test_request.bits.EDID_READ) 511 + return edid_status; 512 + 513 + test_response.bits.EDID_CHECKSUM_WRITE = 1; 514 + 515 + dm_helpers_dp_write_dpcd(ctx, 516 + link, 517 + DP_TEST_EDID_CHECKSUM, 518 + &sink->dc_edid.raw_edid[sink->dc_edid.length-1], 519 + 1); 520 + 521 + dm_helpers_dp_write_dpcd(ctx, 522 + link, 523 + DP_TEST_RESPONSE, 524 + &test_response.raw, 525 + sizeof(test_response)); 526 + 527 + } 500 528 501 529 return edid_status; 502 530 }
-8
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
··· 35 35 #include "amdgpu_dm_irq.h" 36 36 #include "amdgpu_pm.h" 37 37 38 - unsigned long long dm_get_timestamp(struct dc_context *ctx) 39 - { 40 - struct timespec64 time; 41 - 42 - getrawmonotonic64(&time); 43 - return timespec64_to_ns(&time); 44 - } 45 - 46 38 unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, 47 39 unsigned long long current_time_stamp, 48 40 unsigned long long last_time_stamp)
+2
drivers/gpu/drm/amd/display/dc/basics/log_helpers.c
··· 78 78 if (i == NUM_ELEMENTS(signal_type_info_tbl)) 79 79 goto fail; 80 80 81 + dm_logger_append_heading(&entry); 82 + 81 83 dm_logger_append(&entry, "[%s][ConnIdx:%d] ", 82 84 signal_type_info_tbl[i].name, 83 85 link->link_index);
+42 -41
drivers/gpu/drm/amd/display/dc/basics/logger.c
··· 32 32 static const struct dc_log_type_info log_type_info_tbl[] = { 33 33 {LOG_ERROR, "Error"}, 34 34 {LOG_WARNING, "Warning"}, 35 - {LOG_DEBUG, "Debug"}, 35 + {LOG_DEBUG, "Debug"}, 36 36 {LOG_DC, "DC_Interface"}, 37 + {LOG_DTN, "DTN"}, 37 38 {LOG_SURFACE, "Surface"}, 38 39 {LOG_HW_HOTPLUG, "HW_Hotplug"}, 39 40 {LOG_HW_LINK_TRAINING, "HW_LKTN"}, ··· 61 60 {LOG_EVENT_LINK_LOSS, "LinkLoss"}, 62 61 {LOG_EVENT_UNDERFLOW, "Underflow"}, 63 62 {LOG_IF_TRACE, "InterfaceTrace"}, 64 - {LOG_DTN, "DTN"}, 63 + {LOG_PERF_TRACE, "PerfTrace"}, 65 64 {LOG_DISPLAYSTATS, "DisplayStats"} 66 65 }; 67 66 ··· 129 128 } 130 129 131 130 /* ------------------------------------------------------------------------ */ 131 + void dm_logger_append_heading(struct log_entry *entry) 132 + { 133 + int j; 134 + 135 + for (j = 0; j < NUM_ELEMENTS(log_type_info_tbl); j++) { 136 + 137 + const struct dc_log_type_info *info = &log_type_info_tbl[j]; 138 + 139 + if (info->type == entry->type) 140 + dm_logger_append(entry, "[%s]\t", info->name); 141 + } 142 + } 132 143 133 144 145 + /* Print everything unread existing in log_buffer to debug console*/ 146 + void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn) 147 + { 148 + char *string_start = &logger->log_buffer[logger->buffer_read_offset]; 149 + 150 + if (should_warn) 151 + dm_output_to_console( 152 + "---------------- FLUSHING LOG BUFFER ----------------\n"); 153 + while (logger->buffer_read_offset < logger->buffer_write_offset) { 154 + 155 + if (logger->log_buffer[logger->buffer_read_offset] == '\0') { 156 + dm_output_to_console("%s", string_start); 157 + string_start = logger->log_buffer + logger->buffer_read_offset + 1; 158 + } 159 + logger->buffer_read_offset++; 160 + } 161 + if (should_warn) 162 + dm_output_to_console( 163 + "-------------- END FLUSHING LOG BUFFER --------------\n\n"); 164 + } 165 + /* ------------------------------------------------------------------------ */ 166 + 167 + /* Warning: Be careful that 'msg' is null terminated and the total size is 168 + * less than DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE (256) including '\0' 169 + */ 134 170 static bool dal_logger_should_log( 135 171 struct dal_logger *logger, 136 172 enum dc_log_type log_type) ··· 197 159 } 198 160 } 199 161 200 - /* Print everything unread existing in log_buffer to debug console*/ 201 - void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn) 202 - { 203 - char *string_start = &logger->log_buffer[logger->buffer_read_offset]; 204 - 205 - if (should_warn) 206 - dm_output_to_console( 207 - "---------------- FLUSHING LOG BUFFER ----------------\n"); 208 - while (logger->buffer_read_offset < logger->buffer_write_offset) { 209 - 210 - if (logger->log_buffer[logger->buffer_read_offset] == '\0') { 211 - dm_output_to_console("%s", string_start); 212 - string_start = logger->log_buffer + logger->buffer_read_offset + 1; 213 - } 214 - logger->buffer_read_offset++; 215 - } 216 - if (should_warn) 217 - dm_output_to_console( 218 - "-------------- END FLUSHING LOG BUFFER --------------\n\n"); 219 - } 220 162 221 163 static void log_to_internal_buffer(struct log_entry *entry) 222 164 { ··· 247 229 } 248 230 } 249 231 250 - static void log_heading(struct log_entry *entry) 251 - { 252 - int j; 253 - 254 - for (j = 0; j < NUM_ELEMENTS(log_type_info_tbl); j++) { 255 - 256 - const struct dc_log_type_info *info = &log_type_info_tbl[j]; 257 - 258 - if (info->type == entry->type) 259 - dm_logger_append(entry, "[%s]\t", info->name); 260 - } 261 - } 262 - 263 232 static void append_entry( 264 233 struct log_entry *entry, 265 234 char *buffer, ··· 264 259 entry->buf_offset += buf_size; 265 260 } 266 261 267 - /* ------------------------------------------------------------------------ */ 268 262 269 - /* Warning: Be careful that 'msg' is null terminated and the total size is 270 - * less than DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE (256) including '\0' 271 - */ 272 263 void dm_logger_write( 273 264 struct dal_logger *logger, 274 265 enum dc_log_type log_type, ··· 288 287 289 288 entry.type = log_type; 290 289 291 - log_heading(&entry); 290 + dm_logger_append_heading(&entry); 292 291 293 292 size = dm_log_to_buffer( 294 293 buffer, LOG_MAX_LINE_SIZE - 1, msg, args); ··· 373 372 374 373 logger->open_count++; 375 374 376 - log_heading(entry); 375 + dm_logger_append_heading(entry); 377 376 } 378 377 379 378 void dm_logger_close(struct log_entry *entry)
+18 -1
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 169 169 return false; 170 170 } 171 171 172 + /** 173 + ***************************************************************************** 174 + * Function: dc_stream_adjust_vmin_vmax 175 + * 176 + * @brief 177 + * Looks up the pipe context of dc_stream_state and updates the 178 + * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh 179 + * Rate, which is a power-saving feature that targets reducing panel 180 + * refresh rate while the screen is static 181 + * 182 + * @param [in] dc: dc reference 183 + * @param [in] stream: Initial dc stream state 184 + * @param [in] adjust: Updated parameters for vertical_total_min and 185 + * vertical_total_max 186 + ***************************************************************************** 187 + */ 172 188 bool dc_stream_adjust_vmin_vmax(struct dc *dc, 173 189 struct dc_stream_state **streams, int num_streams, 174 190 int vmin, int vmax) ··· 481 465 dc_ctx->driver_context = init_params->driver; 482 466 dc_ctx->dc = dc; 483 467 dc_ctx->asic_id = init_params->asic_id; 468 + dc_ctx->dc_sink_id_count = 0; 484 469 dc->ctx = dc_ctx; 485 470 486 471 dc->current_state = dc_create_state(); ··· 1565 1548 struct dc_sink *dc_sink; 1566 1549 enum dc_edid_status edid_status; 1567 1550 1568 - if (len > MAX_EDID_BUFFER_SIZE) { 1551 + if (len > DC_MAX_EDID_BUFFER_SIZE) { 1569 1552 dm_error("Max EDID buffer size breached!\n"); 1570 1553 return NULL; 1571 1554 }
+18 -22
drivers/gpu/drm/amd/display/dc/core/dc_link.c
··· 1861 1861 break; 1862 1862 } 1863 1863 1864 - if (pipe_ctx->stream_res.audio && status == DC_OK) { 1865 - struct dc *core_dc = pipe_ctx->stream->ctx->dc; 1866 - /* notify audio driver for audio modes of monitor */ 1867 - struct pp_smu_funcs_rv *pp_smu = core_dc->res_pool->pp_smu; 1868 - unsigned int i, num_audio = 1; 1869 - for (i = 0; i < MAX_PIPES; i++) { 1870 - /*current_state not updated yet*/ 1871 - if (core_dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) 1872 - num_audio++; 1873 - } 1874 - 1875 - pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); 1876 - 1877 - if (num_audio == 1 && pp_smu != NULL && pp_smu->set_pme_wa_enable != NULL) 1878 - /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1879 - pp_smu->set_pme_wa_enable(&pp_smu->pp_smu); 1880 - /* un-mute audio */ 1881 - /* TODO: audio should be per stream rather than per link */ 1882 - pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 1883 - pipe_ctx->stream_res.stream_enc, false); 1884 - } 1885 - 1886 1864 return status; 1887 1865 } 1888 1866 ··· 2393 2415 } 2394 2416 } 2395 2417 2418 + core_dc->hwss.enable_audio_stream(pipe_ctx); 2419 + 2396 2420 /* turn off otg test pattern if enable */ 2397 2421 pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, 2398 2422 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, ··· 2433 2453 core_dc->hwss.set_avmute(pipe_ctx, enable); 2434 2454 } 2435 2455 2456 + /** 2457 + ***************************************************************************** 2458 + * Function: dc_link_enable_hpd_filter 2459 + * 2460 + * @brief 2461 + * If enable is true, programs HPD filter on associated HPD line using 2462 + * delay_on_disconnect/delay_on_connect values dependent on 2463 + * link->connector_signal 2464 + * 2465 + * If enable is false, programs HPD filter on associated HPD line with no 2466 + * delays on connect or disconnect 2467 + * 2468 + * @param [in] link: pointer to the dc link 2469 + * @param [in] enable: boolean specifying whether to enable hbd 2470 + ***************************************************************************** 2471 + */ 2436 2472 void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) 2437 2473 { 2438 2474 struct gpio *hpd;
+287 -127
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 522 522 } 523 523 } 524 524 525 - static void calculate_recout(struct pipe_ctx *pipe_ctx, struct view *recout_skip) 525 + static void calculate_recout(struct pipe_ctx *pipe_ctx, struct rect *recout_full) 526 526 { 527 527 const struct dc_plane_state *plane_state = pipe_ctx->plane_state; 528 528 const struct dc_stream_state *stream = pipe_ctx->stream; 529 529 struct rect surf_src = plane_state->src_rect; 530 530 struct rect surf_clip = plane_state->clip_rect; 531 - int recout_full_x, recout_full_y; 532 531 bool pri_split = pipe_ctx->bottom_pipe && 533 532 pipe_ctx->bottom_pipe->plane_state == pipe_ctx->plane_state; 534 533 bool sec_split = pipe_ctx->top_pipe && ··· 596 597 } 597 598 } 598 599 /* Unclipped recout offset = stream dst offset + ((surf dst offset - stream surf_src offset) 599 - * * 1/ stream scaling ratio) - (surf surf_src offset * 1/ full scl 600 - * ratio) 600 + * * 1/ stream scaling ratio) - (surf surf_src offset * 1/ full scl 601 + * ratio) 601 602 */ 602 - recout_full_x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x) 603 + recout_full->x = stream->dst.x + (plane_state->dst_rect.x - stream->src.x) 603 604 * stream->dst.width / stream->src.width - 604 605 surf_src.x * plane_state->dst_rect.width / surf_src.width 605 606 * stream->dst.width / stream->src.width; 606 - recout_full_y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y) 607 + recout_full->y = stream->dst.y + (plane_state->dst_rect.y - stream->src.y) 607 608 * stream->dst.height / stream->src.height - 608 609 surf_src.y * plane_state->dst_rect.height / surf_src.height 609 610 * stream->dst.height / stream->src.height; 610 611 611 - recout_skip->width = pipe_ctx->plane_res.scl_data.recout.x - recout_full_x; 612 - recout_skip->height = pipe_ctx->plane_res.scl_data.recout.y - recout_full_y; 612 + recout_full->width = plane_state->dst_rect.width 613 + * stream->dst.width / stream->src.width; 614 + recout_full->height = plane_state->dst_rect.height 615 + * stream->dst.height / stream->src.height; 613 616 } 614 617 615 618 static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx) ··· 663 662 pipe_ctx->plane_res.scl_data.ratios.vert_c, 19); 664 663 } 665 664 666 - static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *recout_skip) 665 + static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct rect *recout_full) 667 666 { 668 667 struct scaler_data *data = &pipe_ctx->plane_res.scl_data; 669 668 struct rect src = pipe_ctx->plane_state->src_rect; ··· 681 680 flip_vert_scan_dir = true; 682 681 else if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) 683 682 flip_horz_scan_dir = true; 684 - if (pipe_ctx->plane_state->horizontal_mirror) 685 - flip_horz_scan_dir = !flip_horz_scan_dir; 686 683 687 684 if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 || 688 685 pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) { 689 686 rect_swap_helper(&src); 690 687 rect_swap_helper(&data->viewport_c); 691 688 rect_swap_helper(&data->viewport); 692 - } 689 + } else if (pipe_ctx->plane_state->horizontal_mirror) 690 + flip_horz_scan_dir = !flip_horz_scan_dir; 693 691 694 692 /* 695 693 * Init calculated according to formula: ··· 708 708 data->inits.v_c = dc_fixpt_truncate(dc_fixpt_add(data->inits.v_c, dc_fixpt_div_int( 709 709 dc_fixpt_add_int(data->ratios.vert_c, data->taps.v_taps_c + 1), 2)), 19); 710 710 711 + if (!flip_horz_scan_dir) { 712 + /* Adjust for viewport end clip-off */ 713 + if ((data->viewport.x + data->viewport.width) < (src.x + src.width)) { 714 + int vp_clip = src.x + src.width - data->viewport.width - data->viewport.x; 715 + int int_part = dc_fixpt_floor( 716 + dc_fixpt_sub(data->inits.h, data->ratios.horz)); 711 717 712 - 713 - /* Adjust for viewport end clip-off */ 714 - if ((data->viewport.x + data->viewport.width) < (src.x + src.width) && !flip_horz_scan_dir) { 715 - int vp_clip = src.x + src.width - data->viewport.width - data->viewport.x; 716 - int int_part = dc_fixpt_floor( 717 - dc_fixpt_sub(data->inits.h, data->ratios.horz)); 718 - 719 - int_part = int_part > 0 ? int_part : 0; 720 - data->viewport.width += int_part < vp_clip ? int_part : vp_clip; 721 - } 722 - if ((data->viewport.y + data->viewport.height) < (src.y + src.height) && !flip_vert_scan_dir) { 723 - int vp_clip = src.y + src.height - data->viewport.height - data->viewport.y; 724 - int int_part = dc_fixpt_floor( 725 - dc_fixpt_sub(data->inits.v, data->ratios.vert)); 726 - 727 - int_part = int_part > 0 ? int_part : 0; 728 - data->viewport.height += int_part < vp_clip ? int_part : vp_clip; 729 - } 730 - if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div && !flip_horz_scan_dir) { 731 - int vp_clip = (src.x + src.width) / vpc_div - 732 - data->viewport_c.width - data->viewport_c.x; 733 - int int_part = dc_fixpt_floor( 734 - dc_fixpt_sub(data->inits.h_c, data->ratios.horz_c)); 735 - 736 - int_part = int_part > 0 ? int_part : 0; 737 - data->viewport_c.width += int_part < vp_clip ? int_part : vp_clip; 738 - } 739 - if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div && !flip_vert_scan_dir) { 740 - int vp_clip = (src.y + src.height) / vpc_div - 741 - data->viewport_c.height - data->viewport_c.y; 742 - int int_part = dc_fixpt_floor( 743 - dc_fixpt_sub(data->inits.v_c, data->ratios.vert_c)); 744 - 745 - int_part = int_part > 0 ? int_part : 0; 746 - data->viewport_c.height += int_part < vp_clip ? int_part : vp_clip; 747 - } 748 - 749 - /* Adjust for non-0 viewport offset */ 750 - if (data->viewport.x && !flip_horz_scan_dir) { 751 - int int_part; 752 - 753 - data->inits.h = dc_fixpt_add(data->inits.h, dc_fixpt_mul_int( 754 - data->ratios.horz, recout_skip->width)); 755 - int_part = dc_fixpt_floor(data->inits.h) - data->viewport.x; 756 - if (int_part < data->taps.h_taps) { 757 - int int_adj = data->viewport.x >= (data->taps.h_taps - int_part) ? 758 - (data->taps.h_taps - int_part) : data->viewport.x; 759 - data->viewport.x -= int_adj; 760 - data->viewport.width += int_adj; 761 - int_part += int_adj; 762 - } else if (int_part > data->taps.h_taps) { 763 - data->viewport.x += int_part - data->taps.h_taps; 764 - data->viewport.width -= int_part - data->taps.h_taps; 765 - int_part = data->taps.h_taps; 718 + int_part = int_part > 0 ? int_part : 0; 719 + data->viewport.width += int_part < vp_clip ? int_part : vp_clip; 766 720 } 767 - data->inits.h.value &= 0xffffffff; 768 - data->inits.h = dc_fixpt_add_int(data->inits.h, int_part); 769 - } 721 + if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div) { 722 + int vp_clip = (src.x + src.width) / vpc_div - 723 + data->viewport_c.width - data->viewport_c.x; 724 + int int_part = dc_fixpt_floor( 725 + dc_fixpt_sub(data->inits.h_c, data->ratios.horz_c)); 770 726 771 - if (data->viewport_c.x && !flip_horz_scan_dir) { 772 - int int_part; 773 - 774 - data->inits.h_c = dc_fixpt_add(data->inits.h_c, dc_fixpt_mul_int( 775 - data->ratios.horz_c, recout_skip->width)); 776 - int_part = dc_fixpt_floor(data->inits.h_c) - data->viewport_c.x; 777 - if (int_part < data->taps.h_taps_c) { 778 - int int_adj = data->viewport_c.x >= (data->taps.h_taps_c - int_part) ? 779 - (data->taps.h_taps_c - int_part) : data->viewport_c.x; 780 - data->viewport_c.x -= int_adj; 781 - data->viewport_c.width += int_adj; 782 - int_part += int_adj; 783 - } else if (int_part > data->taps.h_taps_c) { 784 - data->viewport_c.x += int_part - data->taps.h_taps_c; 785 - data->viewport_c.width -= int_part - data->taps.h_taps_c; 786 - int_part = data->taps.h_taps_c; 727 + int_part = int_part > 0 ? int_part : 0; 728 + data->viewport_c.width += int_part < vp_clip ? int_part : vp_clip; 787 729 } 788 - data->inits.h_c.value &= 0xffffffff; 789 - data->inits.h_c = dc_fixpt_add_int(data->inits.h_c, int_part); 790 - } 791 730 792 - if (data->viewport.y && !flip_vert_scan_dir) { 793 - int int_part; 731 + /* Adjust for non-0 viewport offset */ 732 + if (data->viewport.x) { 733 + int int_part; 794 734 795 - data->inits.v = dc_fixpt_add(data->inits.v, dc_fixpt_mul_int( 796 - data->ratios.vert, recout_skip->height)); 797 - int_part = dc_fixpt_floor(data->inits.v) - data->viewport.y; 798 - if (int_part < data->taps.v_taps) { 799 - int int_adj = data->viewport.y >= (data->taps.v_taps - int_part) ? 800 - (data->taps.v_taps - int_part) : data->viewport.y; 801 - data->viewport.y -= int_adj; 802 - data->viewport.height += int_adj; 803 - int_part += int_adj; 804 - } else if (int_part > data->taps.v_taps) { 805 - data->viewport.y += int_part - data->taps.v_taps; 806 - data->viewport.height -= int_part - data->taps.v_taps; 807 - int_part = data->taps.v_taps; 735 + data->inits.h = dc_fixpt_add(data->inits.h, dc_fixpt_mul_int( 736 + data->ratios.horz, data->recout.x - recout_full->x)); 737 + int_part = dc_fixpt_floor(data->inits.h) - data->viewport.x; 738 + if (int_part < data->taps.h_taps) { 739 + int int_adj = data->viewport.x >= (data->taps.h_taps - int_part) ? 740 + (data->taps.h_taps - int_part) : data->viewport.x; 741 + data->viewport.x -= int_adj; 742 + data->viewport.width += int_adj; 743 + int_part += int_adj; 744 + } else if (int_part > data->taps.h_taps) { 745 + data->viewport.x += int_part - data->taps.h_taps; 746 + data->viewport.width -= int_part - data->taps.h_taps; 747 + int_part = data->taps.h_taps; 748 + } 749 + data->inits.h.value &= 0xffffffff; 750 + data->inits.h = dc_fixpt_add_int(data->inits.h, int_part); 808 751 } 809 - data->inits.v.value &= 0xffffffff; 810 - data->inits.v = dc_fixpt_add_int(data->inits.v, int_part); 811 - } 812 752 813 - if (data->viewport_c.y && !flip_vert_scan_dir) { 814 - int int_part; 753 + if (data->viewport_c.x) { 754 + int int_part; 815 755 816 - data->inits.v_c = dc_fixpt_add(data->inits.v_c, dc_fixpt_mul_int( 817 - data->ratios.vert_c, recout_skip->height)); 818 - int_part = dc_fixpt_floor(data->inits.v_c) - data->viewport_c.y; 819 - if (int_part < data->taps.v_taps_c) { 820 - int int_adj = data->viewport_c.y >= (data->taps.v_taps_c - int_part) ? 821 - (data->taps.v_taps_c - int_part) : data->viewport_c.y; 822 - data->viewport_c.y -= int_adj; 823 - data->viewport_c.height += int_adj; 824 - int_part += int_adj; 825 - } else if (int_part > data->taps.v_taps_c) { 826 - data->viewport_c.y += int_part - data->taps.v_taps_c; 827 - data->viewport_c.height -= int_part - data->taps.v_taps_c; 828 - int_part = data->taps.v_taps_c; 756 + data->inits.h_c = dc_fixpt_add(data->inits.h_c, dc_fixpt_mul_int( 757 + data->ratios.horz_c, data->recout.x - recout_full->x)); 758 + int_part = dc_fixpt_floor(data->inits.h_c) - data->viewport_c.x; 759 + if (int_part < data->taps.h_taps_c) { 760 + int int_adj = data->viewport_c.x >= (data->taps.h_taps_c - int_part) ? 761 + (data->taps.h_taps_c - int_part) : data->viewport_c.x; 762 + data->viewport_c.x -= int_adj; 763 + data->viewport_c.width += int_adj; 764 + int_part += int_adj; 765 + } else if (int_part > data->taps.h_taps_c) { 766 + data->viewport_c.x += int_part - data->taps.h_taps_c; 767 + data->viewport_c.width -= int_part - data->taps.h_taps_c; 768 + int_part = data->taps.h_taps_c; 769 + } 770 + data->inits.h_c.value &= 0xffffffff; 771 + data->inits.h_c = dc_fixpt_add_int(data->inits.h_c, int_part); 829 772 } 830 - data->inits.v_c.value &= 0xffffffff; 831 - data->inits.v_c = dc_fixpt_add_int(data->inits.v_c, int_part); 773 + } else { 774 + /* Adjust for non-0 viewport offset */ 775 + if (data->viewport.x) { 776 + int int_part = dc_fixpt_floor( 777 + dc_fixpt_sub(data->inits.h, data->ratios.horz)); 778 + 779 + int_part = int_part > 0 ? int_part : 0; 780 + data->viewport.width += int_part < data->viewport.x ? int_part : data->viewport.x; 781 + data->viewport.x -= int_part < data->viewport.x ? int_part : data->viewport.x; 782 + } 783 + if (data->viewport_c.x) { 784 + int int_part = dc_fixpt_floor( 785 + dc_fixpt_sub(data->inits.h_c, data->ratios.horz_c)); 786 + 787 + int_part = int_part > 0 ? int_part : 0; 788 + data->viewport_c.width += int_part < data->viewport_c.x ? int_part : data->viewport_c.x; 789 + data->viewport_c.x -= int_part < data->viewport_c.x ? int_part : data->viewport_c.x; 790 + } 791 + 792 + /* Adjust for viewport end clip-off */ 793 + if ((data->viewport.x + data->viewport.width) < (src.x + src.width)) { 794 + int int_part; 795 + int end_offset = src.x + src.width 796 + - data->viewport.x - data->viewport.width; 797 + 798 + /* 799 + * this is init if vp had no offset, keep in mind this is from the 800 + * right side of vp due to scan direction 801 + */ 802 + data->inits.h = dc_fixpt_add(data->inits.h, dc_fixpt_mul_int( 803 + data->ratios.horz, data->recout.x - recout_full->x)); 804 + /* 805 + * this is the difference between first pixel of viewport available to read 806 + * and init position, takning into account scan direction 807 + */ 808 + int_part = dc_fixpt_floor(data->inits.h) - end_offset; 809 + if (int_part < data->taps.h_taps) { 810 + int int_adj = end_offset >= (data->taps.h_taps - int_part) ? 811 + (data->taps.h_taps - int_part) : end_offset; 812 + data->viewport.width += int_adj; 813 + int_part += int_adj; 814 + } else if (int_part > data->taps.h_taps) { 815 + data->viewport.width += int_part - data->taps.h_taps; 816 + int_part = data->taps.h_taps; 817 + } 818 + data->inits.h.value &= 0xffffffff; 819 + data->inits.h = dc_fixpt_add_int(data->inits.h, int_part); 820 + } 821 + 822 + if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div) { 823 + int int_part; 824 + int end_offset = (src.x + src.width) / vpc_div 825 + - data->viewport_c.x - data->viewport_c.width; 826 + 827 + /* 828 + * this is init if vp had no offset, keep in mind this is from the 829 + * right side of vp due to scan direction 830 + */ 831 + data->inits.h_c = dc_fixpt_add(data->inits.h_c, dc_fixpt_mul_int( 832 + data->ratios.horz_c, data->recout.x - recout_full->x)); 833 + /* 834 + * this is the difference between first pixel of viewport available to read 835 + * and init position, takning into account scan direction 836 + */ 837 + int_part = dc_fixpt_floor(data->inits.h_c) - end_offset; 838 + if (int_part < data->taps.h_taps_c) { 839 + int int_adj = end_offset >= (data->taps.h_taps_c - int_part) ? 840 + (data->taps.h_taps_c - int_part) : end_offset; 841 + data->viewport_c.width += int_adj; 842 + int_part += int_adj; 843 + } else if (int_part > data->taps.h_taps_c) { 844 + data->viewport_c.width += int_part - data->taps.h_taps_c; 845 + int_part = data->taps.h_taps_c; 846 + } 847 + data->inits.h_c.value &= 0xffffffff; 848 + data->inits.h_c = dc_fixpt_add_int(data->inits.h_c, int_part); 849 + } 850 + 851 + } 852 + if (!flip_vert_scan_dir) { 853 + /* Adjust for viewport end clip-off */ 854 + if ((data->viewport.y + data->viewport.height) < (src.y + src.height)) { 855 + int vp_clip = src.y + src.height - data->viewport.height - data->viewport.y; 856 + int int_part = dc_fixpt_floor( 857 + dc_fixpt_sub(data->inits.v, data->ratios.vert)); 858 + 859 + int_part = int_part > 0 ? int_part : 0; 860 + data->viewport.height += int_part < vp_clip ? int_part : vp_clip; 861 + } 862 + if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div) { 863 + int vp_clip = (src.y + src.height) / vpc_div - 864 + data->viewport_c.height - data->viewport_c.y; 865 + int int_part = dc_fixpt_floor( 866 + dc_fixpt_sub(data->inits.v_c, data->ratios.vert_c)); 867 + 868 + int_part = int_part > 0 ? int_part : 0; 869 + data->viewport_c.height += int_part < vp_clip ? int_part : vp_clip; 870 + } 871 + 872 + /* Adjust for non-0 viewport offset */ 873 + if (data->viewport.y) { 874 + int int_part; 875 + 876 + data->inits.v = dc_fixpt_add(data->inits.v, dc_fixpt_mul_int( 877 + data->ratios.vert, data->recout.y - recout_full->y)); 878 + int_part = dc_fixpt_floor(data->inits.v) - data->viewport.y; 879 + if (int_part < data->taps.v_taps) { 880 + int int_adj = data->viewport.y >= (data->taps.v_taps - int_part) ? 881 + (data->taps.v_taps - int_part) : data->viewport.y; 882 + data->viewport.y -= int_adj; 883 + data->viewport.height += int_adj; 884 + int_part += int_adj; 885 + } else if (int_part > data->taps.v_taps) { 886 + data->viewport.y += int_part - data->taps.v_taps; 887 + data->viewport.height -= int_part - data->taps.v_taps; 888 + int_part = data->taps.v_taps; 889 + } 890 + data->inits.v.value &= 0xffffffff; 891 + data->inits.v = dc_fixpt_add_int(data->inits.v, int_part); 892 + } 893 + 894 + if (data->viewport_c.y) { 895 + int int_part; 896 + 897 + data->inits.v_c = dc_fixpt_add(data->inits.v_c, dc_fixpt_mul_int( 898 + data->ratios.vert_c, data->recout.y - recout_full->y)); 899 + int_part = dc_fixpt_floor(data->inits.v_c) - data->viewport_c.y; 900 + if (int_part < data->taps.v_taps_c) { 901 + int int_adj = data->viewport_c.y >= (data->taps.v_taps_c - int_part) ? 902 + (data->taps.v_taps_c - int_part) : data->viewport_c.y; 903 + data->viewport_c.y -= int_adj; 904 + data->viewport_c.height += int_adj; 905 + int_part += int_adj; 906 + } else if (int_part > data->taps.v_taps_c) { 907 + data->viewport_c.y += int_part - data->taps.v_taps_c; 908 + data->viewport_c.height -= int_part - data->taps.v_taps_c; 909 + int_part = data->taps.v_taps_c; 910 + } 911 + data->inits.v_c.value &= 0xffffffff; 912 + data->inits.v_c = dc_fixpt_add_int(data->inits.v_c, int_part); 913 + } 914 + } else { 915 + /* Adjust for non-0 viewport offset */ 916 + if (data->viewport.y) { 917 + int int_part = dc_fixpt_floor( 918 + dc_fixpt_sub(data->inits.v, data->ratios.vert)); 919 + 920 + int_part = int_part > 0 ? int_part : 0; 921 + data->viewport.height += int_part < data->viewport.y ? int_part : data->viewport.y; 922 + data->viewport.y -= int_part < data->viewport.y ? int_part : data->viewport.y; 923 + } 924 + if (data->viewport_c.y) { 925 + int int_part = dc_fixpt_floor( 926 + dc_fixpt_sub(data->inits.v_c, data->ratios.vert_c)); 927 + 928 + int_part = int_part > 0 ? int_part : 0; 929 + data->viewport_c.height += int_part < data->viewport_c.y ? int_part : data->viewport_c.y; 930 + data->viewport_c.y -= int_part < data->viewport_c.y ? int_part : data->viewport_c.y; 931 + } 932 + 933 + /* Adjust for viewport end clip-off */ 934 + if ((data->viewport.y + data->viewport.height) < (src.y + src.height)) { 935 + int int_part; 936 + int end_offset = src.y + src.height 937 + - data->viewport.y - data->viewport.height; 938 + 939 + /* 940 + * this is init if vp had no offset, keep in mind this is from the 941 + * right side of vp due to scan direction 942 + */ 943 + data->inits.v = dc_fixpt_add(data->inits.v, dc_fixpt_mul_int( 944 + data->ratios.vert, data->recout.y - recout_full->y)); 945 + /* 946 + * this is the difference between first pixel of viewport available to read 947 + * and init position, taking into account scan direction 948 + */ 949 + int_part = dc_fixpt_floor(data->inits.v) - end_offset; 950 + if (int_part < data->taps.v_taps) { 951 + int int_adj = end_offset >= (data->taps.v_taps - int_part) ? 952 + (data->taps.v_taps - int_part) : end_offset; 953 + data->viewport.height += int_adj; 954 + int_part += int_adj; 955 + } else if (int_part > data->taps.v_taps) { 956 + data->viewport.height += int_part - data->taps.v_taps; 957 + int_part = data->taps.v_taps; 958 + } 959 + data->inits.v.value &= 0xffffffff; 960 + data->inits.v = dc_fixpt_add_int(data->inits.v, int_part); 961 + } 962 + 963 + if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div) { 964 + int int_part; 965 + int end_offset = (src.y + src.height) / vpc_div 966 + - data->viewport_c.y - data->viewport_c.height; 967 + 968 + /* 969 + * this is init if vp had no offset, keep in mind this is from the 970 + * right side of vp due to scan direction 971 + */ 972 + data->inits.v_c = dc_fixpt_add(data->inits.v_c, dc_fixpt_mul_int( 973 + data->ratios.vert_c, data->recout.y - recout_full->y)); 974 + /* 975 + * this is the difference between first pixel of viewport available to read 976 + * and init position, taking into account scan direction 977 + */ 978 + int_part = dc_fixpt_floor(data->inits.v_c) - end_offset; 979 + if (int_part < data->taps.v_taps_c) { 980 + int int_adj = end_offset >= (data->taps.v_taps_c - int_part) ? 981 + (data->taps.v_taps_c - int_part) : end_offset; 982 + data->viewport_c.height += int_adj; 983 + int_part += int_adj; 984 + } else if (int_part > data->taps.v_taps_c) { 985 + data->viewport_c.height += int_part - data->taps.v_taps_c; 986 + int_part = data->taps.v_taps_c; 987 + } 988 + data->inits.v_c.value &= 0xffffffff; 989 + data->inits.v_c = dc_fixpt_add_int(data->inits.v_c, int_part); 990 + } 832 991 } 833 992 834 993 /* Interlaced inits based on final vert inits */ ··· 1005 846 { 1006 847 const struct dc_plane_state *plane_state = pipe_ctx->plane_state; 1007 848 struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 1008 - struct view recout_skip = { 0 }; 849 + struct rect recout_full = { 0 }; 1009 850 bool res = false; 1010 851 DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); 1011 852 /* Important: scaling ratio calculation requires pixel format, ··· 1025 866 if (pipe_ctx->plane_res.scl_data.viewport.height < 16 || pipe_ctx->plane_res.scl_data.viewport.width < 16) 1026 867 return false; 1027 868 1028 - calculate_recout(pipe_ctx, &recout_skip); 869 + calculate_recout(pipe_ctx, &recout_full); 1029 870 1030 871 /** 1031 872 * Setting line buffer pixel depth to 24bpp yields banding ··· 1069 910 1070 911 if (res) 1071 912 /* May need to re-check lb size after this in some obscure scenario */ 1072 - calculate_inits_and_adj_vp(pipe_ctx, &recout_skip); 913 + calculate_inits_and_adj_vp(pipe_ctx, &recout_full); 1073 914 1074 915 DC_LOG_SCALER( 1075 916 "%s: Viewport:\nheight:%d width:%d x:%d " ··· 2506 2347 { 2507 2348 /* HDR Static Metadata info packet for HDR10 */ 2508 2349 2509 - if (!stream->hdr_static_metadata.valid) 2350 + if (!stream->hdr_static_metadata.valid || 2351 + stream->use_dynamic_meta) 2510 2352 return; 2511 2353 2512 2354 *info_packet = stream->hdr_static_metadata;
+4
drivers/gpu/drm/amd/display/dc/core/dc_sink.c
··· 53 53 sink->dongle_max_pix_clk = init_params->dongle_max_pix_clk; 54 54 sink->converter_disable_audio = init_params->converter_disable_audio; 55 55 sink->dc_container_id = NULL; 56 + sink->sink_id = init_params->link->ctx->dc_sink_id_count; 57 + // increment dc_sink_id_count because we don't want two sinks with same ID 58 + // unless they are actually the same 59 + init_params->link->ctx->dc_sink_id_count++; 56 60 57 61 return true; 58 62 }
+11
drivers/gpu/drm/amd/display/dc/core/dc_surface.c
··· 84 84 return plane_state; 85 85 } 86 86 87 + /** 88 + ***************************************************************************** 89 + * Function: dc_plane_get_status 90 + * 91 + * @brief 92 + * Looks up the pipe context of plane_state and updates the pending status 93 + * of the pipe context. Then returns plane_state->status 94 + * 95 + * @param [in] plane_state: pointer to the plane_state to get the status of 96 + ***************************************************************************** 97 + */ 87 98 const struct dc_plane_status *dc_plane_get_status( 88 99 const struct dc_plane_state *plane_state) 89 100 {
+15 -6
drivers/gpu/drm/amd/display/dc/dc.h
··· 38 38 #include "inc/compressor.h" 39 39 #include "dml/display_mode_lib.h" 40 40 41 - #define DC_VER "3.1.44" 41 + #define DC_VER "3.1.47" 42 42 43 43 #define MAX_SURFACES 3 44 44 #define MAX_STREAMS 6 ··· 68 68 uint32_t max_planes; 69 69 uint32_t max_downscale_ratio; 70 70 uint32_t i2c_speed_in_khz; 71 + uint32_t dmdata_alloc_size; 71 72 unsigned int max_cursor_size; 72 73 unsigned int max_video_width; 73 74 int linear_pitch_alignment; ··· 289 288 bool apply_edp_fast_boot_optimization; 290 289 291 290 /* FBC compressor */ 292 - #if defined(CONFIG_DRM_AMD_DC_FBC) 293 291 struct compressor *fbc_compressor; 294 - #endif 295 292 }; 296 293 297 294 enum frame_buffer_mode { ··· 357 358 TF_TYPE_PREDEFINED, 358 359 TF_TYPE_DISTRIBUTED_POINTS, 359 360 TF_TYPE_BYPASS, 361 + TF_TYPE_HWPWL 360 362 }; 361 363 362 364 struct dc_transfer_func_distributed_points { ··· 377 377 TRANSFER_FUNCTION_PQ, 378 378 TRANSFER_FUNCTION_LINEAR, 379 379 TRANSFER_FUNCTION_UNITY, 380 + TRANSFER_FUNCTION_HLG, 381 + TRANSFER_FUNCTION_HLG12 380 382 }; 381 383 382 384 struct dc_transfer_func { 383 385 struct kref refcount; 384 - struct dc_transfer_func_distributed_points tf_pts; 385 386 enum dc_transfer_func_type type; 386 387 enum dc_transfer_func_predefined tf; 387 388 /* FP16 1.0 reference level in nits, default is 80 nits, only for PQ*/ 388 389 uint32_t sdr_ref_white_level; 389 390 struct dc_context *ctx; 391 + union { 392 + struct pwl_params pwl; 393 + struct dc_transfer_func_distributed_points tf_pts; 394 + }; 390 395 }; 391 396 392 397 /* ··· 666 661 struct dc_link *link; 667 662 struct dc_context *ctx; 668 663 669 - /* private to dc_sink.c */ 670 - struct kref refcount; 664 + uint32_t sink_id; 671 665 666 + /* private to dc_sink.c */ 667 + // refcount must be the last member in dc_sink, since we want the 668 + // sink structure to be logically cloneable up to (but not including) 669 + // refcount 670 + struct kref refcount; 672 671 }; 673 672 674 673 void dc_sink_retain(struct dc_sink *sink);
+60 -1
drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
··· 25 25 #ifndef DC_DDC_TYPES_H_ 26 26 #define DC_DDC_TYPES_H_ 27 27 28 + enum aux_transaction_type { 29 + AUX_TRANSACTION_TYPE_DP, 30 + AUX_TRANSACTION_TYPE_I2C 31 + }; 32 + 33 + 34 + enum i2caux_transaction_action { 35 + I2CAUX_TRANSACTION_ACTION_I2C_WRITE = 0x00, 36 + I2CAUX_TRANSACTION_ACTION_I2C_READ = 0x10, 37 + I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST = 0x20, 38 + 39 + I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT = 0x40, 40 + I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT = 0x50, 41 + I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT = 0x60, 42 + 43 + I2CAUX_TRANSACTION_ACTION_DP_WRITE = 0x80, 44 + I2CAUX_TRANSACTION_ACTION_DP_READ = 0x90 45 + }; 46 + 47 + enum aux_channel_operation_result { 48 + AUX_CHANNEL_OPERATION_SUCCEEDED, 49 + AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN, 50 + AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY, 51 + AUX_CHANNEL_OPERATION_FAILED_TIMEOUT, 52 + AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON 53 + }; 54 + 55 + 56 + struct aux_request_transaction_data { 57 + enum aux_transaction_type type; 58 + enum i2caux_transaction_action action; 59 + /* 20-bit AUX channel transaction address */ 60 + uint32_t address; 61 + /* delay, in 100-microsecond units */ 62 + uint8_t delay; 63 + uint32_t length; 64 + uint8_t *data; 65 + }; 66 + 67 + enum aux_transaction_reply { 68 + AUX_TRANSACTION_REPLY_AUX_ACK = 0x00, 69 + AUX_TRANSACTION_REPLY_AUX_NACK = 0x01, 70 + AUX_TRANSACTION_REPLY_AUX_DEFER = 0x02, 71 + 72 + AUX_TRANSACTION_REPLY_I2C_ACK = 0x00, 73 + AUX_TRANSACTION_REPLY_I2C_NACK = 0x10, 74 + AUX_TRANSACTION_REPLY_I2C_DEFER = 0x20, 75 + 76 + AUX_TRANSACTION_REPLY_HPD_DISCON = 0x40, 77 + 78 + AUX_TRANSACTION_REPLY_INVALID = 0xFF 79 + }; 80 + 81 + struct aux_reply_transaction_data { 82 + enum aux_transaction_reply status; 83 + uint32_t length; 84 + uint8_t *data; 85 + }; 86 + 28 87 struct i2c_payload { 29 88 bool write; 30 89 uint8_t address; ··· 168 109 169 110 uint32_t address; 170 111 uint32_t edid_buf_len; 171 - uint8_t edid_buf[MAX_EDID_BUFFER_SIZE]; 112 + uint8_t edid_buf[DC_MAX_EDID_BUFFER_SIZE]; 172 113 }; 173 114 174 115 #endif /* DC_DDC_TYPES_H_ */
+3 -2
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
··· 430 430 struct { 431 431 uint8_t LINK_TRAINING :1; 432 432 uint8_t LINK_TEST_PATTRN :1; 433 - uint8_t EDID_REAT :1; 433 + uint8_t EDID_READ :1; 434 434 uint8_t PHY_TEST_PATTERN :1; 435 435 uint8_t AUDIO_TEST_PATTERN :1; 436 436 uint8_t RESERVED :1; ··· 443 443 struct { 444 444 uint8_t ACK :1; 445 445 uint8_t NO_ACK :1; 446 - uint8_t RESERVED :6; 446 + uint8_t EDID_CHECKSUM_WRITE:1; 447 + uint8_t RESERVED :5; 447 448 } bits; 448 449 uint8_t raw; 449 450 };
+17 -17
drivers/gpu/drm/amd/display/dc/dc_hw_types.h
··· 567 567 }; 568 568 569 569 enum dc_timing_standard { 570 - TIMING_STANDARD_UNDEFINED, 571 - TIMING_STANDARD_DMT, 572 - TIMING_STANDARD_GTF, 573 - TIMING_STANDARD_CVT, 574 - TIMING_STANDARD_CVT_RB, 575 - TIMING_STANDARD_CEA770, 576 - TIMING_STANDARD_CEA861, 577 - TIMING_STANDARD_HDMI, 578 - TIMING_STANDARD_TV_NTSC, 579 - TIMING_STANDARD_TV_NTSC_J, 580 - TIMING_STANDARD_TV_PAL, 581 - TIMING_STANDARD_TV_PAL_M, 582 - TIMING_STANDARD_TV_PAL_CN, 583 - TIMING_STANDARD_TV_SECAM, 584 - TIMING_STANDARD_EXPLICIT, 570 + DC_TIMING_STANDARD_UNDEFINED, 571 + DC_TIMING_STANDARD_DMT, 572 + DC_TIMING_STANDARD_GTF, 573 + DC_TIMING_STANDARD_CVT, 574 + DC_TIMING_STANDARD_CVT_RB, 575 + DC_TIMING_STANDARD_CEA770, 576 + DC_TIMING_STANDARD_CEA861, 577 + DC_TIMING_STANDARD_HDMI, 578 + DC_TIMING_STANDARD_TV_NTSC, 579 + DC_TIMING_STANDARD_TV_NTSC_J, 580 + DC_TIMING_STANDARD_TV_PAL, 581 + DC_TIMING_STANDARD_TV_PAL_M, 582 + DC_TIMING_STANDARD_TV_PAL_CN, 583 + DC_TIMING_STANDARD_TV_SECAM, 584 + DC_TIMING_STANDARD_EXPLICIT, 585 585 /*!< For explicit timings from EDID, VBIOS, etc.*/ 586 - TIMING_STANDARD_USER_OVERRIDE, 586 + DC_TIMING_STANDARD_USER_OVERRIDE, 587 587 /*!< For mode timing override by user*/ 588 - TIMING_STANDARD_MAX 588 + DC_TIMING_STANDARD_MAX 589 589 }; 590 590 591 591 enum dc_color_depth {
+3 -5
drivers/gpu/drm/amd/display/dc/dc_stream.h
··· 59 59 struct freesync_context freesync_ctx; 60 60 61 61 struct dc_info_packet hdr_static_metadata; 62 + PHYSICAL_ADDRESS_LOC dmdata_address; 63 + bool use_dynamic_meta; 64 + 62 65 struct dc_transfer_func *out_transfer_func; 63 66 struct colorspace_transform gamut_remap_matrix; 64 67 struct dc_csc_transform csc_color_matrix; ··· 301 298 int num_streams, 302 299 unsigned int *v_pos, 303 300 unsigned int *nom_v_pos); 304 - 305 - void dc_stream_set_static_screen_events(struct dc *dc, 306 - struct dc_stream_state **stream, 307 - int num_streams, 308 - const struct dc_static_screen_events *events); 309 301 310 302 #endif /* DC_STREAM_H_ */
+10 -11
drivers/gpu/drm/amd/display/dc/dc_types.h
··· 92 92 bool created_bios; 93 93 struct gpio_service *gpio_service; 94 94 struct i2caux *i2caux; 95 - #if defined(CONFIG_DRM_AMD_DC_FBC) 95 + uint32_t dc_sink_id_count; 96 96 uint64_t fbc_gpu_addr; 97 - #endif 98 97 }; 99 98 100 99 101 - #define MAX_EDID_BUFFER_SIZE 512 100 + #define DC_MAX_EDID_BUFFER_SIZE 512 102 101 #define EDID_BLOCK_SIZE 128 103 102 #define MAX_SURFACE_NUM 4 104 103 #define NUM_PIXEL_FORMATS 10 ··· 136 137 */ 137 138 138 139 enum dc_edid_connector_type { 139 - EDID_CONNECTOR_UNKNOWN = 0, 140 - EDID_CONNECTOR_ANALOG = 1, 141 - EDID_CONNECTOR_DIGITAL = 10, 142 - EDID_CONNECTOR_DVI = 11, 143 - EDID_CONNECTOR_HDMIA = 12, 144 - EDID_CONNECTOR_MDDI = 14, 145 - EDID_CONNECTOR_DISPLAYPORT = 15 140 + DC_EDID_CONNECTOR_UNKNOWN = 0, 141 + DC_EDID_CONNECTOR_ANALOG = 1, 142 + DC_EDID_CONNECTOR_DIGITAL = 10, 143 + DC_EDID_CONNECTOR_DVI = 11, 144 + DC_EDID_CONNECTOR_HDMIA = 12, 145 + DC_EDID_CONNECTOR_MDDI = 14, 146 + DC_EDID_CONNECTOR_DISPLAYPORT = 15 146 147 }; 147 148 148 149 enum dc_edid_status { ··· 168 169 169 170 struct dc_edid { 170 171 uint32_t length; 171 - uint8_t raw_edid[MAX_EDID_BUFFER_SIZE]; 172 + uint8_t raw_edid[DC_MAX_EDID_BUFFER_SIZE]; 172 173 }; 173 174 174 175 /* When speaker location data block is not available, DEFAULT_SPEAKER_LOCATION
-5
drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
··· 289 289 290 290 struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); 291 291 292 - #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 293 - if (REG(DP_DB_CNTL)) 294 - REG_UPDATE(DP_DB_CNTL, DP_DB_DISABLE, 1); 295 - #endif 296 - 297 292 /* set pixel encoding */ 298 293 switch (crtc_timing->pixel_encoding) { 299 294 case PIXEL_ENCODING_YCBCR422:
+1 -3
drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c
··· 143 143 struct dce110_compressor *cp110, 144 144 bool enabled) 145 145 { 146 - uint8_t counter = 0; 146 + uint16_t counter = 0; 147 147 uint32_t addr = mmFBC_STATUS; 148 148 uint32_t value; 149 149 ··· 551 551 compressor->base.lpt_channels_num = 0; 552 552 compressor->base.attached_inst = 0; 553 553 compressor->base.is_enabled = false; 554 - #if defined(CONFIG_DRM_AMD_DC_FBC) 555 554 compressor->base.funcs = &dce110_compressor_funcs; 556 555 557 - #endif 558 556 } 559 557
+175 -142
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
··· 34 34 #include "dce/dce_hwseq.h" 35 35 #include "gpio_service_interface.h" 36 36 37 - #if defined(CONFIG_DRM_AMD_DC_FBC) 38 37 #include "dce110_compressor.h" 39 - #endif 40 38 41 39 #include "bios/bios_parser_helper.h" 42 40 #include "timing_generator.h" ··· 665 667 666 668 void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 667 669 { 670 + bool is_hdmi; 671 + bool is_dp; 672 + 668 673 ASSERT(pipe_ctx->stream); 669 674 670 675 if (pipe_ctx->stream_res.stream_enc == NULL) 671 676 return; /* this is not root pipe */ 672 677 673 - if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 678 + is_hdmi = dc_is_hdmi_signal(pipe_ctx->stream->signal); 679 + is_dp = dc_is_dp_signal(pipe_ctx->stream->signal); 680 + 681 + if (!is_hdmi && !is_dp) 682 + return; 683 + 684 + if (is_hdmi) 674 685 pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 675 686 pipe_ctx->stream_res.stream_enc, 676 687 &pipe_ctx->stream_res.encoder_info_frame); 677 - else if (dc_is_dp_signal(pipe_ctx->stream->signal)) 688 + else 678 689 pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 679 690 pipe_ctx->stream_res.stream_enc, 680 691 &pipe_ctx->stream_res.encoder_info_frame); ··· 979 972 edp_receiver_ready_T9(link); 980 973 } 981 974 982 - void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) 975 + void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) 983 976 { 984 - struct dc_stream_state *stream = pipe_ctx->stream; 985 - struct dc_link *link = stream->sink->link; 977 + struct dc *core_dc = pipe_ctx->stream->ctx->dc; 978 + /* notify audio driver for audio modes of monitor */ 979 + struct pp_smu_funcs_rv *pp_smu = core_dc->res_pool->pp_smu; 980 + unsigned int i, num_audio = 1; 981 + 982 + if (pipe_ctx->stream_res.audio) { 983 + for (i = 0; i < MAX_PIPES; i++) { 984 + /*current_state not updated yet*/ 985 + if (core_dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) 986 + num_audio++; 987 + } 988 + 989 + pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); 990 + 991 + if (num_audio == 1 && pp_smu != NULL && pp_smu->set_pme_wa_enable != NULL) 992 + /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 993 + pp_smu->set_pme_wa_enable(&pp_smu->pp_smu); 994 + /* un-mute audio */ 995 + /* TODO: audio should be per stream rather than per link */ 996 + pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 997 + pipe_ctx->stream_res.stream_enc, false); 998 + } 999 + } 1000 + 1001 + void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option) 1002 + { 986 1003 struct dc *dc = pipe_ctx->stream->ctx->dc; 987 - 988 - if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 989 - pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 990 - pipe_ctx->stream_res.stream_enc); 991 - 992 - if (dc_is_dp_signal(pipe_ctx->stream->signal)) 993 - pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 994 - pipe_ctx->stream_res.stream_enc); 995 1004 996 1005 pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 997 1006 pipe_ctx->stream_res.stream_enc, true); ··· 1038 1015 * stream->stream_engine_id); 1039 1016 */ 1040 1017 } 1018 + } 1041 1019 1020 + void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) 1021 + { 1022 + struct dc_stream_state *stream = pipe_ctx->stream; 1023 + struct dc_link *link = stream->sink->link; 1024 + struct dc *dc = pipe_ctx->stream->ctx->dc; 1025 + 1026 + if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 1027 + pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 1028 + pipe_ctx->stream_res.stream_enc); 1029 + 1030 + if (dc_is_dp_signal(pipe_ctx->stream->signal)) 1031 + pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 1032 + pipe_ctx->stream_res.stream_enc); 1033 + 1034 + dc->hwss.disable_audio_stream(pipe_ctx, option); 1042 1035 1043 1036 link->link_enc->funcs->connect_dig_be_to_fe( 1044 1037 link->link_enc, ··· 1337 1298 struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 1338 1299 pipe_ctx[pipe_ctx->pipe_idx]; 1339 1300 1301 + if (pipe_ctx->stream_res.audio != NULL) { 1302 + struct audio_output audio_output; 1303 + 1304 + build_audio_output(context, pipe_ctx, &audio_output); 1305 + 1306 + if (dc_is_dp_signal(pipe_ctx->stream->signal)) 1307 + pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( 1308 + pipe_ctx->stream_res.stream_enc, 1309 + pipe_ctx->stream_res.audio->inst, 1310 + &pipe_ctx->stream->audio_info); 1311 + else 1312 + pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( 1313 + pipe_ctx->stream_res.stream_enc, 1314 + pipe_ctx->stream_res.audio->inst, 1315 + &pipe_ctx->stream->audio_info, 1316 + &audio_output.crtc_info); 1317 + 1318 + pipe_ctx->stream_res.audio->funcs->az_configure( 1319 + pipe_ctx->stream_res.audio, 1320 + pipe_ctx->stream->signal, 1321 + &audio_output.crtc_info, 1322 + &pipe_ctx->stream->audio_info); 1323 + } 1324 + 1340 1325 /* */ 1341 1326 dc->hwss.enable_stream_timing(pipe_ctx, context, dc); 1342 1327 ··· 1504 1441 1505 1442 power_down_clock_sources(dc); 1506 1443 1507 - #if defined(CONFIG_DRM_AMD_DC_FBC) 1508 1444 if (dc->fbc_compressor) 1509 1445 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 1510 - #endif 1511 1446 } 1512 1447 1513 1448 static void disable_vga_and_power_gate_all_controllers( ··· 1747 1686 if (events->force_trigger) 1748 1687 value |= 0x1; 1749 1688 1750 - #if defined(CONFIG_DRM_AMD_DC_FBC) 1751 1689 value |= 0x84; 1752 - #endif 1753 1690 1754 1691 for (i = 0; i < num_pipes; i++) 1755 1692 pipe_ctx[i]->stream_res.tg->funcs-> ··· 1875 1816 } 1876 1817 } 1877 1818 1878 - #if defined(CONFIG_DRM_AMD_DC_FBC) 1879 - 1880 1819 /* 1881 1820 * Check if FBC can be enabled 1882 1821 */ ··· 1953 1896 compr->funcs->enable_fbc(compr, &params); 1954 1897 } 1955 1898 } 1956 - #endif 1957 1899 1958 1900 static void dce110_reset_hw_ctx_wrap( 1959 1901 struct dc *dc, ··· 2005 1949 } 2006 1950 } 2007 1951 2008 - 2009 - enum dc_status dce110_apply_ctx_to_hw( 1952 + static void dce110_setup_audio_dto( 2010 1953 struct dc *dc, 2011 1954 struct dc_state *context) 2012 1955 { 2013 - struct dc_bios *dcb = dc->ctx->dc_bios; 2014 - enum dc_status status; 2015 1956 int i; 2016 - enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID; 2017 1957 2018 - /* Reset old context */ 2019 - /* look up the targets that have been removed since last commit */ 2020 - dc->hwss.reset_hw_ctx_wrap(dc, context); 2021 - 2022 - /* Skip applying if no targets */ 2023 - if (context->stream_count <= 0) 2024 - return DC_OK; 2025 - 2026 - /* Apply new context */ 2027 - dcb->funcs->set_scratch_critical_state(dcb, true); 2028 - 2029 - /* below is for real asic only */ 2030 - for (i = 0; i < dc->res_pool->pipe_count; i++) { 2031 - struct pipe_ctx *pipe_ctx_old = 2032 - &dc->current_state->res_ctx.pipe_ctx[i]; 2033 - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2034 - 2035 - if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 2036 - continue; 2037 - 2038 - if (pipe_ctx->stream == pipe_ctx_old->stream) { 2039 - if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 2040 - dce_crtc_switch_to_clk_src(dc->hwseq, 2041 - pipe_ctx->clock_source, i); 2042 - continue; 2043 - } 2044 - 2045 - dc->hwss.enable_display_power_gating( 2046 - dc, i, dc->ctx->dc_bios, 2047 - PIPE_GATING_CONTROL_DISABLE); 2048 - } 2049 - 2050 - set_safe_displaymarks(&context->res_ctx, dc->res_pool); 2051 - 2052 - #if defined(CONFIG_DRM_AMD_DC_FBC) 2053 - if (dc->fbc_compressor) 2054 - dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 2055 - #endif 2056 - /*TODO: when pplib works*/ 2057 - apply_min_clocks(dc, context, &clocks_state, true); 2058 - 2059 - #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 2060 - if (dc->ctx->dce_version >= DCN_VERSION_1_0) { 2061 - if (context->bw.dcn.calc_clk.fclk_khz 2062 - > dc->current_state->bw.dcn.cur_clk.fclk_khz) { 2063 - struct dm_pp_clock_for_voltage_req clock; 2064 - 2065 - clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; 2066 - clock.clocks_in_khz = context->bw.dcn.calc_clk.fclk_khz; 2067 - dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 2068 - dc->current_state->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 2069 - context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 2070 - } 2071 - if (context->bw.dcn.calc_clk.dcfclk_khz 2072 - > dc->current_state->bw.dcn.cur_clk.dcfclk_khz) { 2073 - struct dm_pp_clock_for_voltage_req clock; 2074 - 2075 - clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; 2076 - clock.clocks_in_khz = context->bw.dcn.calc_clk.dcfclk_khz; 2077 - dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 2078 - dc->current_state->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 2079 - context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 2080 - } 2081 - if (context->bw.dcn.calc_clk.dispclk_khz 2082 - > dc->current_state->bw.dcn.cur_clk.dispclk_khz) { 2083 - dc->res_pool->display_clock->funcs->set_clock( 2084 - dc->res_pool->display_clock, 2085 - context->bw.dcn.calc_clk.dispclk_khz); 2086 - dc->current_state->bw.dcn.cur_clk.dispclk_khz = 2087 - context->bw.dcn.calc_clk.dispclk_khz; 2088 - context->bw.dcn.cur_clk.dispclk_khz = 2089 - context->bw.dcn.calc_clk.dispclk_khz; 2090 - } 2091 - } else 2092 - #endif 2093 - if (context->bw.dce.dispclk_khz 2094 - > dc->current_state->bw.dce.dispclk_khz) { 2095 - dc->res_pool->display_clock->funcs->set_clock( 2096 - dc->res_pool->display_clock, 2097 - context->bw.dce.dispclk_khz * 115 / 100); 2098 - } 2099 1958 /* program audio wall clock. use HDMI as clock source if HDMI 2100 1959 * audio active. Otherwise, use DP as clock source 2101 1960 * first, loop to find any HDMI audio, if not, loop find DP audio ··· 2084 2113 } 2085 2114 } 2086 2115 } 2116 + } 2117 + 2118 + enum dc_status dce110_apply_ctx_to_hw( 2119 + struct dc *dc, 2120 + struct dc_state *context) 2121 + { 2122 + struct dc_bios *dcb = dc->ctx->dc_bios; 2123 + enum dc_status status; 2124 + int i; 2125 + enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID; 2126 + 2127 + /* Reset old context */ 2128 + /* look up the targets that have been removed since last commit */ 2129 + dc->hwss.reset_hw_ctx_wrap(dc, context); 2130 + 2131 + /* Skip applying if no targets */ 2132 + if (context->stream_count <= 0) 2133 + return DC_OK; 2134 + 2135 + /* Apply new context */ 2136 + dcb->funcs->set_scratch_critical_state(dcb, true); 2137 + 2138 + /* below is for real asic only */ 2139 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 2140 + struct pipe_ctx *pipe_ctx_old = 2141 + &dc->current_state->res_ctx.pipe_ctx[i]; 2142 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2143 + 2144 + if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 2145 + continue; 2146 + 2147 + if (pipe_ctx->stream == pipe_ctx_old->stream) { 2148 + if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 2149 + dce_crtc_switch_to_clk_src(dc->hwseq, 2150 + pipe_ctx->clock_source, i); 2151 + continue; 2152 + } 2153 + 2154 + dc->hwss.enable_display_power_gating( 2155 + dc, i, dc->ctx->dc_bios, 2156 + PIPE_GATING_CONTROL_DISABLE); 2157 + } 2158 + 2159 + set_safe_displaymarks(&context->res_ctx, dc->res_pool); 2160 + 2161 + if (dc->fbc_compressor) 2162 + dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 2163 + 2164 + /*TODO: when pplib works*/ 2165 + apply_min_clocks(dc, context, &clocks_state, true); 2166 + 2167 + #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 2168 + if (dc->ctx->dce_version >= DCN_VERSION_1_0) { 2169 + if (context->bw.dcn.calc_clk.fclk_khz 2170 + > dc->current_state->bw.dcn.cur_clk.fclk_khz) { 2171 + struct dm_pp_clock_for_voltage_req clock; 2172 + 2173 + clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; 2174 + clock.clocks_in_khz = context->bw.dcn.calc_clk.fclk_khz; 2175 + dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 2176 + dc->current_state->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 2177 + context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 2178 + } 2179 + if (context->bw.dcn.calc_clk.dcfclk_khz 2180 + > dc->current_state->bw.dcn.cur_clk.dcfclk_khz) { 2181 + struct dm_pp_clock_for_voltage_req clock; 2182 + 2183 + clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; 2184 + clock.clocks_in_khz = context->bw.dcn.calc_clk.dcfclk_khz; 2185 + dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 2186 + dc->current_state->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 2187 + context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 2188 + } 2189 + if (context->bw.dcn.calc_clk.dispclk_khz 2190 + > dc->current_state->bw.dcn.cur_clk.dispclk_khz) { 2191 + dc->res_pool->display_clock->funcs->set_clock( 2192 + dc->res_pool->display_clock, 2193 + context->bw.dcn.calc_clk.dispclk_khz); 2194 + dc->current_state->bw.dcn.cur_clk.dispclk_khz = 2195 + context->bw.dcn.calc_clk.dispclk_khz; 2196 + context->bw.dcn.cur_clk.dispclk_khz = 2197 + context->bw.dcn.calc_clk.dispclk_khz; 2198 + } 2199 + } else 2200 + #endif 2201 + if (context->bw.dce.dispclk_khz 2202 + > dc->current_state->bw.dce.dispclk_khz) { 2203 + dc->res_pool->display_clock->funcs->set_clock( 2204 + dc->res_pool->display_clock, 2205 + context->bw.dce.dispclk_khz * 115 / 100); 2206 + } 2207 + 2208 + dce110_setup_audio_dto(dc, context); 2087 2209 2088 2210 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2089 2211 struct pipe_ctx *pipe_ctx_old = ··· 2195 2131 if (pipe_ctx->top_pipe) 2196 2132 continue; 2197 2133 2198 - if (context->res_ctx.pipe_ctx[i].stream_res.audio != NULL) { 2199 - 2200 - struct audio_output audio_output; 2201 - 2202 - build_audio_output(context, pipe_ctx, &audio_output); 2203 - 2204 - if (dc_is_dp_signal(pipe_ctx->stream->signal)) 2205 - pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( 2206 - pipe_ctx->stream_res.stream_enc, 2207 - pipe_ctx->stream_res.audio->inst, 2208 - &pipe_ctx->stream->audio_info); 2209 - else 2210 - pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( 2211 - pipe_ctx->stream_res.stream_enc, 2212 - pipe_ctx->stream_res.audio->inst, 2213 - &pipe_ctx->stream->audio_info, 2214 - &audio_output.crtc_info); 2215 - 2216 - pipe_ctx->stream_res.audio->funcs->az_configure( 2217 - pipe_ctx->stream_res.audio, 2218 - pipe_ctx->stream->signal, 2219 - &audio_output.crtc_info, 2220 - &pipe_ctx->stream->audio_info); 2221 - } 2222 - 2223 2134 status = apply_single_controller_ctx_to_hw( 2224 2135 pipe_ctx, 2225 2136 context, ··· 2209 2170 2210 2171 dcb->funcs->set_scratch_critical_state(dcb, false); 2211 2172 2212 - #if defined(CONFIG_DRM_AMD_DC_FBC) 2213 2173 if (dc->fbc_compressor) 2214 2174 enable_fbc(dc, context); 2215 - 2216 - #endif 2217 2175 2218 2176 return DC_OK; 2219 2177 } ··· 2526 2490 abm->funcs->init_backlight(abm); 2527 2491 abm->funcs->abm_init(abm); 2528 2492 } 2529 - #if defined(CONFIG_DRM_AMD_DC_FBC) 2493 + 2530 2494 if (dc->fbc_compressor) 2531 2495 dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 2532 - #endif 2533 2496 2534 2497 } 2535 2498 ··· 2714 2679 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 2715 2680 struct xfm_grph_csc_adjustment adjust; 2716 2681 struct out_csc_color_matrix tbl_entry; 2717 - #if defined(CONFIG_DRM_AMD_DC_FBC) 2718 2682 unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 2719 - #endif 2720 2683 unsigned int i; 2721 2684 DC_LOGGER_INIT(); 2722 2685 memset(&tbl_entry, 0, sizeof(tbl_entry)); ··· 2755 2722 2756 2723 program_scaler(dc, pipe_ctx); 2757 2724 2758 - #if defined(CONFIG_DRM_AMD_DC_FBC) 2759 2725 /* fbc not applicable on Underlay pipe */ 2760 2726 if (dc->fbc_compressor && old_pipe->stream && 2761 2727 pipe_ctx->pipe_idx != underlay_idx) { ··· 2763 2731 else 2764 2732 enable_fbc(dc, dc->current_state); 2765 2733 } 2766 - #endif 2767 2734 2768 2735 mi->funcs->mem_input_program_surface_config( 2769 2736 mi, ··· 2999 2968 .disable_stream = dce110_disable_stream, 3000 2969 .unblank_stream = dce110_unblank_stream, 3001 2970 .blank_stream = dce110_blank_stream, 2971 + .enable_audio_stream = dce110_enable_audio_stream, 2972 + .disable_audio_stream = dce110_disable_audio_stream, 3002 2973 .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 3003 2974 .enable_display_power_gating = dce110_enable_display_power_gating, 3004 2975 .disable_plane = dce110_power_down_fe,
+4
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
··· 49 49 struct dc_link_settings *link_settings); 50 50 51 51 void dce110_blank_stream(struct pipe_ctx *pipe_ctx); 52 + 53 + void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx); 54 + void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option); 55 + 52 56 void dce110_update_info_frame(struct pipe_ctx *pipe_ctx); 53 57 54 58 void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
+1 -6
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
··· 54 54 55 55 #define DC_LOGGER \ 56 56 dc->ctx->logger 57 - #if defined(CONFIG_DRM_AMD_DC_FBC) 57 + 58 58 #include "dce110/dce110_compressor.h" 59 - #endif 60 59 61 60 #include "reg_helper.h" 62 61 ··· 1266 1267 } 1267 1268 } 1268 1269 1269 - #if defined(CONFIG_DRM_AMD_DC_FBC) 1270 1270 dc->fbc_compressor = dce110_compressor_create(ctx); 1271 1271 1272 - 1273 - 1274 - #endif 1275 1272 if (!underlay_create(ctx, &pool->base)) 1276 1273 goto res_create_fail; 1277 1274
+8 -18
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 719 719 if (!pipe_ctx->stream->dpms_off) 720 720 core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); 721 721 else if (pipe_ctx->stream_res.audio) { 722 - /* 723 - * if stream is already disabled outside of commit streams path, 724 - * audio disable was skipped. Need to do it here 725 - */ 726 - pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); 727 - 728 - if (dc->caps.dynamic_audio == true) { 729 - /*we have to dynamic arbitrate the audio endpoints*/ 730 - pipe_ctx->stream_res.audio = NULL; 731 - /*we free the resource, need reset is_audio_acquired*/ 732 - update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); 733 - } 734 - 722 + dc->hwss.disable_audio_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); 735 723 } 736 724 737 725 } ··· 2051 2063 2052 2064 static void dcn10_blank_pixel_data( 2053 2065 struct dc *dc, 2054 - struct stream_resource *stream_res, 2055 - struct dc_stream_state *stream, 2066 + struct pipe_ctx *pipe_ctx, 2056 2067 bool blank) 2057 2068 { 2058 2069 enum dc_color_space color_space; 2059 2070 struct tg_color black_color = {0}; 2071 + struct stream_resource *stream_res = &pipe_ctx->stream_res; 2072 + struct dc_stream_state *stream = pipe_ctx->stream; 2060 2073 2061 2074 /* program otg blank color */ 2062 2075 color_space = stream->output_color_space; ··· 2116 2127 pipe_ctx->stream_res.tg->funcs->program_global_sync( 2117 2128 pipe_ctx->stream_res.tg); 2118 2129 2119 - dc->hwss.blank_pixel_data(dc, &pipe_ctx->stream_res, 2120 - pipe_ctx->stream, blank); 2130 + dc->hwss.blank_pixel_data(dc, pipe_ctx, blank); 2121 2131 } 2122 2132 2123 2133 if (pipe_ctx->plane_state != NULL) { ··· 2235 2247 2236 2248 if (num_planes == 0) { 2237 2249 /* OTG blank before remove all front end */ 2238 - dc->hwss.blank_pixel_data(dc, &top_pipe_to_program->stream_res, top_pipe_to_program->stream, true); 2250 + dc->hwss.blank_pixel_data(dc, top_pipe_to_program, true); 2239 2251 } 2240 2252 2241 2253 /* Disconnect unused mpcc */ ··· 2766 2778 .disable_stream = dce110_disable_stream, 2767 2779 .unblank_stream = dce110_unblank_stream, 2768 2780 .blank_stream = dce110_blank_stream, 2781 + .enable_audio_stream = dce110_enable_audio_stream, 2782 + .disable_audio_stream = dce110_disable_audio_stream, 2769 2783 .enable_display_power_gating = dcn10_dummy_display_power_gating, 2770 2784 .disable_plane = dcn10_disable_plane, 2771 2785 .blank_pixel_data = dcn10_blank_pixel_data,
+32
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
··· 1257 1257 OPTC_UNDERFLOW_OCCURRED_STATUS, &s->underflow_occurred_status); 1258 1258 } 1259 1259 1260 + bool optc1_get_otg_active_size(struct timing_generator *optc, 1261 + uint32_t *otg_active_width, 1262 + uint32_t *otg_active_height) 1263 + { 1264 + uint32_t otg_enabled; 1265 + uint32_t v_blank_start; 1266 + uint32_t v_blank_end; 1267 + uint32_t h_blank_start; 1268 + uint32_t h_blank_end; 1269 + struct optc *optc1 = DCN10TG_FROM_TG(optc); 1270 + 1271 + 1272 + REG_GET(OTG_CONTROL, 1273 + OTG_MASTER_EN, &otg_enabled); 1274 + 1275 + if (otg_enabled == 0) 1276 + return false; 1277 + 1278 + REG_GET_2(OTG_V_BLANK_START_END, 1279 + OTG_V_BLANK_START, &v_blank_start, 1280 + OTG_V_BLANK_END, &v_blank_end); 1281 + 1282 + REG_GET_2(OTG_H_BLANK_START_END, 1283 + OTG_H_BLANK_START, &h_blank_start, 1284 + OTG_H_BLANK_END, &h_blank_end); 1285 + 1286 + *otg_active_width = v_blank_start - v_blank_end; 1287 + *otg_active_height = h_blank_start - h_blank_end; 1288 + return true; 1289 + } 1290 + 1260 1291 void optc1_clear_optc_underflow(struct timing_generator *optc) 1261 1292 { 1262 1293 struct optc *optc1 = DCN10TG_FROM_TG(optc); ··· 1336 1305 .get_position = optc1_get_position, 1337 1306 .get_frame_count = optc1_get_vblank_counter, 1338 1307 .get_scanoutpos = optc1_get_crtc_scanoutpos, 1308 + .get_otg_active_size = optc1_get_otg_active_size, 1339 1309 .set_early_control = optc1_set_early_control, 1340 1310 /* used by enable_timing_synchronization. Not need for FPGA */ 1341 1311 .wait_for_state = optc1_wait_for_state,
+4
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
··· 507 507 508 508 void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable); 509 509 510 + bool optc1_get_otg_active_size(struct timing_generator *optc, 511 + uint32_t *otg_active_width, 512 + uint32_t *otg_active_height); 513 + 510 514 #endif /* __DC_TIMING_GENERATOR_DCN10_H__ */
+3 -1
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
··· 417 417 418 418 static const struct resource_caps res_cap = { 419 419 .num_timing_generator = 4, 420 + .num_opp = 4, 420 421 .num_video_plane = 4, 421 422 .num_audio = 4, 422 423 .num_stream_encoder = 4, ··· 1005 1004 1006 1005 ctx->dc_bios->regs = &bios_regs; 1007 1006 1008 - pool->base.res_cap = &res_cap; 1007 + pool->base.res_cap = &res_cap; 1008 + 1009 1009 pool->base.funcs = &dcn10_res_pool_funcs; 1010 1010 1011 1011 /*
+32 -56
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
··· 257 257 uint8_t colorimetry_bpc; 258 258 uint8_t dynamic_range_rgb = 0; /*full range*/ 259 259 uint8_t dynamic_range_ycbcr = 1; /*bt709*/ 260 + uint8_t dp_pixel_encoding = 0; 261 + uint8_t dp_component_depth = 0; 260 262 261 263 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 262 - 263 - REG_UPDATE(DP_DB_CNTL, DP_DB_DISABLE, 1); 264 264 265 265 /* set pixel encoding */ 266 266 switch (crtc_timing->pixel_encoding) { 267 267 case PIXEL_ENCODING_YCBCR422: 268 - REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 269 - DP_PIXEL_ENCODING_TYPE_YCBCR422); 268 + dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_YCBCR422; 270 269 break; 271 270 case PIXEL_ENCODING_YCBCR444: 272 - REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 273 - DP_PIXEL_ENCODING_TYPE_YCBCR444); 271 + dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_YCBCR444; 274 272 275 273 if (crtc_timing->flags.Y_ONLY) 276 274 if (crtc_timing->display_color_depth != COLOR_DEPTH_666) ··· 276 278 * Color depth of Y-only could be 277 279 * 8, 10, 12, 16 bits 278 280 */ 279 - REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 280 - DP_PIXEL_ENCODING_TYPE_Y_ONLY); 281 + dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_Y_ONLY; 282 + 281 283 /* Note: DP_MSA_MISC1 bit 7 is the indicator 282 284 * of Y-only mode. 283 285 * This bit is set in HW if register ··· 285 287 */ 286 288 break; 287 289 case PIXEL_ENCODING_YCBCR420: 288 - REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 289 - DP_PIXEL_ENCODING_TYPE_YCBCR420); 290 + dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_YCBCR420; 290 291 REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1); 291 292 break; 292 293 default: 293 - REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, 294 - DP_PIXEL_ENCODING_TYPE_RGB444); 294 + dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_RGB444; 295 295 break; 296 296 } 297 297 298 298 misc1 = REG_READ(DP_MSA_MISC); 299 + /* For YCbCr420 and BT2020 Colorimetry Formats, VSC SDP shall be used. 300 + * When MISC1, bit 6, is Set to 1, a Source device uses a VSC SDP to indicate the 301 + * Pixel Encoding/Colorimetry Format and that a Sink device shall ignore MISC1, bit 7, 302 + * and MISC0, bits 7:1 (MISC1, bit 7, and MISC0, bits 7:1, become "don't care"). 303 + */ 304 + if ((crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) || 305 + (output_color_space == COLOR_SPACE_2020_YCBCR) || 306 + (output_color_space == COLOR_SPACE_2020_RGB_FULLRANGE) || 307 + (output_color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)) 308 + misc1 = misc1 | 0x40; 309 + else 310 + misc1 = misc1 & ~0x40; 299 311 300 312 /* set color depth */ 301 - 302 313 switch (crtc_timing->display_color_depth) { 303 314 case COLOR_DEPTH_666: 304 - REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 305 - 0); 315 + dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_6BPC; 306 316 break; 307 317 case COLOR_DEPTH_888: 308 - REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 309 - DP_COMPONENT_PIXEL_DEPTH_8BPC); 318 + dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_8BPC; 310 319 break; 311 320 case COLOR_DEPTH_101010: 312 - REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 313 - DP_COMPONENT_PIXEL_DEPTH_10BPC); 314 - 321 + dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_10BPC; 315 322 break; 316 323 case COLOR_DEPTH_121212: 317 - REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 318 - DP_COMPONENT_PIXEL_DEPTH_12BPC); 324 + dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_12BPC; 319 325 break; 320 326 case COLOR_DEPTH_161616: 321 - REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 322 - DP_COMPONENT_PIXEL_DEPTH_16BPC); 327 + dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_16BPC; 323 328 break; 324 329 default: 325 - REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH, 326 - DP_COMPONENT_PIXEL_DEPTH_6BPC); 330 + dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_6BPC; 327 331 break; 328 332 } 333 + 334 + /* Set DP pixel encoding and component depth */ 335 + REG_UPDATE_2(DP_PIXEL_FORMAT, 336 + DP_PIXEL_ENCODING, dp_pixel_encoding, 337 + DP_COMPONENT_DEPTH, dp_component_depth); 329 338 330 339 /* set dynamic range and YCbCr range */ 331 340 ··· 359 354 360 355 switch (output_color_space) { 361 356 case COLOR_SPACE_SRGB: 362 - misc0 = misc0 | 0x0; 363 357 misc1 = misc1 & ~0x80; /* bit7 = 0*/ 364 358 dynamic_range_rgb = 0; /*full range*/ 365 359 break; ··· 1091 1087 return cea_channels; 1092 1088 } 1093 1089 1094 - static uint32_t calc_max_audio_packets_per_line( 1095 - const struct audio_crtc_info *crtc_info) 1096 - { 1097 - uint32_t max_packets_per_line; 1098 - 1099 - max_packets_per_line = 1100 - crtc_info->h_total - crtc_info->h_active; 1101 - 1102 - if (crtc_info->pixel_repetition) 1103 - max_packets_per_line *= crtc_info->pixel_repetition; 1104 - 1105 - /* for other hdmi features */ 1106 - max_packets_per_line -= 58; 1107 - /* for Control Period */ 1108 - max_packets_per_line -= 16; 1109 - /* Number of Audio Packets per Line */ 1110 - max_packets_per_line /= 32; 1111 - 1112 - return max_packets_per_line; 1113 - } 1114 - 1115 1090 static void get_audio_clock_info( 1116 1091 enum dc_color_depth color_depth, 1117 1092 uint32_t crtc_pixel_clock_in_khz, ··· 1184 1201 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 1185 1202 1186 1203 struct audio_clock_info audio_clock_info = {0}; 1187 - uint32_t max_packets_per_line; 1188 - 1189 - /* For now still do calculation, although this field is ignored when 1190 - * above HDMI_PACKET_GEN_VERSION set to 1 1191 - */ 1192 - max_packets_per_line = calc_max_audio_packets_per_line(crtc_info); 1193 1204 1194 1205 /* HDMI_AUDIO_PACKET_CONTROL */ 1195 - REG_UPDATE_2(HDMI_AUDIO_PACKET_CONTROL, 1196 - HDMI_AUDIO_PACKETS_PER_LINE, max_packets_per_line, 1206 + REG_UPDATE(HDMI_AUDIO_PACKET_CONTROL, 1197 1207 HDMI_AUDIO_DELAY_EN, 1); 1198 1208 1199 1209 /* AFMT_AUDIO_PACKET_CONTROL */
+4 -1
drivers/gpu/drm/amd/display/dc/dm_services.h
··· 339 339 #define dm_log_to_buffer(buffer, size, fmt, args)\ 340 340 vsnprintf(buffer, size, fmt, args) 341 341 342 - unsigned long long dm_get_timestamp(struct dc_context *ctx); 342 + static inline unsigned long long dm_get_timestamp(struct dc_context *ctx) 343 + { 344 + return ktime_get_raw_ns(); 345 + } 343 346 344 347 unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, 345 348 unsigned long long current_time_stamp,
+16
drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
··· 157 157 ctx->operation_succeeded = false; 158 158 } 159 159 break; 160 + case AUX_TRANSACTION_REPLY_HPD_DISCON: 161 + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; 162 + ctx->operation_succeeded = false; 163 + break; 160 164 default: 161 165 ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN; 162 166 ctx->operation_succeeded = false; ··· 218 214 * The HW timeout is set to 550usec, 219 215 * so we should not wait here */ 220 216 } 217 + break; 218 + case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 219 + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; 220 + ctx->operation_succeeded = false; 221 221 break; 222 222 default: 223 223 ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN; ··· 378 370 ctx->operation_succeeded = false; 379 371 } 380 372 break; 373 + case AUX_TRANSACTION_REPLY_HPD_DISCON: 374 + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; 375 + ctx->operation_succeeded = false; 376 + break; 381 377 default: 382 378 ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN; 383 379 ctx->operation_succeeded = false; ··· 433 421 * The HW timeout is set to 550usec, 434 422 * so we should not wait here */ 435 423 } 424 + break; 425 + case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 426 + ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON; 427 + ctx->operation_succeeded = false; 436 428 break; 437 429 default: 438 430 ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
+1 -40
drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h
··· 26 26 #ifndef __DAL_AUX_ENGINE_H__ 27 27 #define __DAL_AUX_ENGINE_H__ 28 28 29 - enum aux_transaction_type { 30 - AUX_TRANSACTION_TYPE_DP, 31 - AUX_TRANSACTION_TYPE_I2C 32 - }; 33 - 34 - struct aux_request_transaction_data { 35 - enum aux_transaction_type type; 36 - enum i2caux_transaction_action action; 37 - /* 20-bit AUX channel transaction address */ 38 - uint32_t address; 39 - /* delay, in 100-microsecond units */ 40 - uint8_t delay; 41 - uint32_t length; 42 - uint8_t *data; 43 - }; 44 - 45 - enum aux_transaction_reply { 46 - AUX_TRANSACTION_REPLY_AUX_ACK = 0x00, 47 - AUX_TRANSACTION_REPLY_AUX_NACK = 0x01, 48 - AUX_TRANSACTION_REPLY_AUX_DEFER = 0x02, 49 - 50 - AUX_TRANSACTION_REPLY_I2C_ACK = 0x00, 51 - AUX_TRANSACTION_REPLY_I2C_NACK = 0x10, 52 - AUX_TRANSACTION_REPLY_I2C_DEFER = 0x20, 53 - 54 - AUX_TRANSACTION_REPLY_INVALID = 0xFF 55 - }; 56 - 57 - struct aux_reply_transaction_data { 58 - enum aux_transaction_reply status; 59 - uint32_t length; 60 - uint8_t *data; 61 - }; 62 - 63 - enum aux_channel_operation_result { 64 - AUX_CHANNEL_OPERATION_SUCCEEDED, 65 - AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN, 66 - AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY, 67 - AUX_CHANNEL_OPERATION_FAILED_TIMEOUT 68 - }; 29 + #include "dc_ddc_types.h" 69 30 70 31 struct aux_engine; 71 32
+34 -22
drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
··· 198 198 ((request->type == AUX_TRANSACTION_TYPE_I2C) && 199 199 ((request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) || 200 200 (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT))); 201 + if (REG(AUXN_IMPCAL)) { 202 + /* clear_aux_error */ 203 + REG_UPDATE_SEQ(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, 204 + 1, 205 + 0); 201 206 202 - /* clear_aux_error */ 203 - REG_UPDATE_SEQ(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, 204 - 1, 205 - 0); 207 + REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, 208 + 1, 209 + 0); 206 210 207 - REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, 208 - 1, 209 - 0); 211 + /* force_default_calibrate */ 212 + REG_UPDATE_1BY1_2(AUXN_IMPCAL, 213 + AUXN_IMPCAL_ENABLE, 1, 214 + AUXN_IMPCAL_OVERRIDE_ENABLE, 0); 210 215 211 - /* force_default_calibrate */ 212 - REG_UPDATE_1BY1_2(AUXN_IMPCAL, 213 - AUXN_IMPCAL_ENABLE, 1, 214 - AUXN_IMPCAL_OVERRIDE_ENABLE, 0); 216 + /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */ 215 217 216 - /* bug? why AUXN update EN and OVERRIDE_EN 1 by 1 while AUX P toggles OVERRIDE? */ 217 - 218 - REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, 219 - 1, 220 - 0); 221 - 218 + REG_UPDATE_SEQ(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, 219 + 1, 220 + 0); 221 + } 222 222 /* set the delay and the number of bytes to write */ 223 223 224 224 /* The length include ··· 291 291 value = REG_GET(AUX_SW_STATUS, 292 292 AUX_SW_REPLY_BYTE_COUNT, &bytes_replied); 293 293 294 + /* in case HPD is LOW, exit AUX transaction */ 295 + if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { 296 + reply->status = AUX_TRANSACTION_REPLY_HPD_DISCON; 297 + return; 298 + } 299 + 294 300 if (bytes_replied) { 295 301 uint32_t reply_result; 296 302 ··· 353 347 * because there was surely an error that was asserted 354 348 * that should have been handled 355 349 * for hot plug case, this could happens*/ 356 - if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) 350 + if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) { 351 + reply->status = AUX_TRANSACTION_REPLY_INVALID; 357 352 ASSERT_CRITICAL(false); 353 + } 358 354 } 359 355 } 360 356 ··· 378 370 /* poll to make sure that SW_DONE is asserted */ 379 371 value = REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1, 380 372 10, aux110->timeout_period/10); 373 + 374 + /* in case HPD is LOW, exit AUX transaction */ 375 + if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) 376 + return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; 381 377 382 378 /* Note that the following bits are set in 'status.bits' 383 379 * during CTS 4.2.1.2 (FW 3.3.1): ··· 414 402 return AUX_CHANNEL_OPERATION_SUCCEEDED; 415 403 } 416 404 } else { 417 - /*time_elapsed >= aux_engine->timeout_period */ 418 - if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) 419 - ASSERT_CRITICAL(false); 420 - 405 + /*time_elapsed >= aux_engine->timeout_period 406 + * AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point 407 + */ 408 + ASSERT_CRITICAL(false); 421 409 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT; 422 410 } 423 411 }
+4 -14
drivers/gpu/drm/amd/display/dc/i2caux/engine.h
··· 26 26 #ifndef __DAL_ENGINE_H__ 27 27 #define __DAL_ENGINE_H__ 28 28 29 + #include "dc_ddc_types.h" 30 + 29 31 enum i2caux_transaction_operation { 30 32 I2CAUX_TRANSACTION_READ, 31 33 I2CAUX_TRANSACTION_WRITE ··· 55 53 I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE, 56 54 I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION, 57 55 I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION, 58 - I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW 56 + I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW, 57 + I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON 59 58 }; 60 59 61 60 struct i2caux_transaction_request { ··· 76 73 enum i2c_default_speed { 77 74 I2CAUX_DEFAULT_I2C_HW_SPEED = 50, 78 75 I2CAUX_DEFAULT_I2C_SW_SPEED = 50 79 - }; 80 - 81 - enum i2caux_transaction_action { 82 - I2CAUX_TRANSACTION_ACTION_I2C_WRITE = 0x00, 83 - I2CAUX_TRANSACTION_ACTION_I2C_READ = 0x10, 84 - I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST = 0x20, 85 - 86 - I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT = 0x40, 87 - I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT = 0x50, 88 - I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT = 0x60, 89 - 90 - I2CAUX_TRANSACTION_ACTION_DP_WRITE = 0x80, 91 - I2CAUX_TRANSACTION_ACTION_DP_READ = 0x90 92 76 }; 93 77 94 78 struct engine;
+1
drivers/gpu/drm/amd/display/dc/inc/core_types.h
··· 148 148 unsigned int underlay_pipe_index; 149 149 unsigned int stream_enc_count; 150 150 unsigned int ref_clock_inKhz; 151 + unsigned int dentist_vco_freq_khz; 151 152 unsigned int timing_generator_count; 152 153 153 154 /*
+3
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
··· 156 156 uint32_t *v_blank_end, 157 157 uint32_t *h_position, 158 158 uint32_t *v_position); 159 + bool (*get_otg_active_size)(struct timing_generator *optc, 160 + uint32_t *otg_active_width, 161 + uint32_t *otg_active_height); 159 162 void (*set_early_control)(struct timing_generator *tg, 160 163 uint32_t early_cntl); 161 164 void (*wait_for_state)(struct timing_generator *tg,
+6 -2
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
··· 154 154 struct dc_link_settings *link_settings); 155 155 156 156 void (*blank_stream)(struct pipe_ctx *pipe_ctx); 157 + 158 + void (*enable_audio_stream)(struct pipe_ctx *pipe_ctx); 159 + 160 + void (*disable_audio_stream)(struct pipe_ctx *pipe_ctx, int option); 161 + 157 162 void (*pipe_control_lock)( 158 163 struct dc *dc, 159 164 struct pipe_ctx *pipe, 160 165 bool lock); 161 166 void (*blank_pixel_data)( 162 167 struct dc *dc, 163 - struct stream_resource *stream_res, 164 - struct dc_stream_state *stream, 168 + struct pipe_ctx *pipe_ctx, 165 169 bool blank); 166 170 167 171 void (*set_bandwidth)(
+1
drivers/gpu/drm/amd/display/dc/inc/resource.h
··· 38 38 39 39 struct resource_caps { 40 40 int num_timing_generator; 41 + int num_opp; 41 42 int num_video_plane; 42 43 int num_audio; 43 44 int num_stream_encoder;
+2 -1
drivers/gpu/drm/amd/display/include/ddc_service_types.h
··· 40 40 DDC_RESULT_FAILED_INCOMPLETE, 41 41 DDC_RESULT_FAILED_OPERATION, 42 42 DDC_RESULT_FAILED_INVALID_OPERATION, 43 - DDC_RESULT_FAILED_BUFFER_OVERFLOW 43 + DDC_RESULT_FAILED_BUFFER_OVERFLOW, 44 + DDC_RESULT_FAILED_HPD_DISCON 44 45 }; 45 46 46 47 enum ddc_service_type {
+7
drivers/gpu/drm/amd/display/include/fixed31_32.h
··· 26 26 #ifndef __DAL_FIXED31_32_H__ 27 27 #define __DAL_FIXED31_32_H__ 28 28 29 + #ifndef LLONG_MAX 30 + #define LLONG_MAX 9223372036854775807ll 31 + #endif 32 + #ifndef LLONG_MIN 33 + #define LLONG_MIN (-LLONG_MAX - 1ll) 34 + #endif 35 + 29 36 #define FIXED31_32_BITS_PER_FRACTIONAL_PART 32 30 37 #ifndef LLONG_MIN 31 38 #define LLONG_MIN (1LL<<63)
+2
drivers/gpu/drm/amd/display/include/logger_interface.h
··· 62 62 const char *msg, 63 63 va_list args); 64 64 65 + void dm_logger_append_heading(struct log_entry *entry); 66 + 65 67 void dm_logger_open( 66 68 struct dal_logger *logger, 67 69 struct log_entry *entry,
+137
drivers/gpu/drm/amd/display/modules/color/color_gamma.c
··· 131 131 dc_fixpt_div(dc_fixpt_one, m1)); 132 132 133 133 } 134 + 135 + /*de gamma, none linear to linear*/ 136 + static void compute_hlg_oetf(struct fixed31_32 in_x, bool is_light0_12, struct fixed31_32 *out_y) 137 + { 138 + struct fixed31_32 a; 139 + struct fixed31_32 b; 140 + struct fixed31_32 c; 141 + struct fixed31_32 threshold; 142 + struct fixed31_32 reference_white_level; 143 + 144 + a = dc_fixpt_from_fraction(17883277, 100000000); 145 + if (is_light0_12) { 146 + /*light 0-12*/ 147 + b = dc_fixpt_from_fraction(28466892, 100000000); 148 + c = dc_fixpt_from_fraction(55991073, 100000000); 149 + threshold = dc_fixpt_one; 150 + reference_white_level = dc_fixpt_half; 151 + } else { 152 + /*light 0-1*/ 153 + b = dc_fixpt_from_fraction(2372241, 100000000); 154 + c = dc_fixpt_add(dc_fixpt_one, dc_fixpt_from_fraction(429347, 100000000)); 155 + threshold = dc_fixpt_from_fraction(1, 12); 156 + reference_white_level = dc_fixpt_pow(dc_fixpt_from_fraction(3, 1), dc_fixpt_half); 157 + } 158 + if (dc_fixpt_lt(threshold, in_x)) 159 + *out_y = dc_fixpt_add(c, dc_fixpt_mul(a, dc_fixpt_log(dc_fixpt_sub(in_x, b)))); 160 + else 161 + *out_y = dc_fixpt_mul(dc_fixpt_pow(in_x, dc_fixpt_half), reference_white_level); 162 + } 163 + 164 + /*re gamma, linear to none linear*/ 165 + static void compute_hlg_eotf(struct fixed31_32 in_x, bool is_light0_12, struct fixed31_32 *out_y) 166 + { 167 + struct fixed31_32 a; 168 + struct fixed31_32 b; 169 + struct fixed31_32 c; 170 + struct fixed31_32 reference_white_level; 171 + 172 + a = dc_fixpt_from_fraction(17883277, 100000000); 173 + if (is_light0_12) { 174 + /*light 0-12*/ 175 + b = dc_fixpt_from_fraction(28466892, 100000000); 176 + c = dc_fixpt_from_fraction(55991073, 100000000); 177 + reference_white_level = dc_fixpt_from_fraction(4, 1); 178 + } else { 179 + /*light 0-1*/ 180 + b = dc_fixpt_from_fraction(2372241, 100000000); 181 + c = dc_fixpt_add(dc_fixpt_one, dc_fixpt_from_fraction(429347, 100000000)); 182 + reference_white_level = dc_fixpt_from_fraction(1, 3); 183 + } 184 + if (dc_fixpt_lt(dc_fixpt_half, in_x)) 185 + *out_y = dc_fixpt_add(dc_fixpt_exp(dc_fixpt_div(dc_fixpt_sub(in_x, c), a)), b); 186 + else 187 + *out_y = dc_fixpt_mul(dc_fixpt_pow(in_x, dc_fixpt_from_fraction(2, 1)), reference_white_level); 188 + } 189 + 190 + 134 191 /* one-time pre-compute PQ values - only for sdr_white_level 80 */ 135 192 void precompute_pq(void) 136 193 { ··· 745 688 curve[i].g = dc_fixpt_one; 746 689 curve[i].b = dc_fixpt_one; 747 690 i++; 691 + } 692 + } 693 + 694 + static void build_hlg_degamma(struct pwl_float_data_ex *degamma, 695 + uint32_t hw_points_num, 696 + const struct hw_x_point *coordinate_x, bool is_light0_12) 697 + { 698 + uint32_t i; 699 + 700 + struct pwl_float_data_ex *rgb = degamma; 701 + const struct hw_x_point *coord_x = coordinate_x; 702 + 703 + i = 0; 704 + 705 + while (i != hw_points_num + 1) { 706 + compute_hlg_oetf(coord_x->x, is_light0_12, &rgb->r); 707 + rgb->g = rgb->r; 708 + rgb->b = rgb->r; 709 + ++coord_x; 710 + ++rgb; 711 + ++i; 712 + } 713 + } 714 + 715 + static void build_hlg_regamma(struct pwl_float_data_ex *regamma, 716 + uint32_t hw_points_num, 717 + const struct hw_x_point *coordinate_x, bool is_light0_12) 718 + { 719 + uint32_t i; 720 + 721 + struct pwl_float_data_ex *rgb = regamma; 722 + const struct hw_x_point *coord_x = coordinate_x; 723 + 724 + i = 0; 725 + 726 + while (i != hw_points_num + 1) { 727 + compute_hlg_eotf(coord_x->x, is_light0_12, &rgb->r); 728 + rgb->g = rgb->r; 729 + rgb->b = rgb->r; 730 + ++coord_x; 731 + ++rgb; 732 + ++i; 748 733 } 749 734 } 750 735 ··· 1721 1622 ret = true; 1722 1623 1723 1624 kvfree(rgb_regamma); 1625 + } else if (trans == TRANSFER_FUNCTION_HLG || 1626 + trans == TRANSFER_FUNCTION_HLG12) { 1627 + rgb_regamma = kvzalloc(sizeof(*rgb_regamma) * 1628 + (MAX_HW_POINTS + _EXTRA_POINTS), 1629 + GFP_KERNEL); 1630 + if (!rgb_regamma) 1631 + goto rgb_regamma_alloc_fail; 1632 + 1633 + build_hlg_regamma(rgb_regamma, 1634 + MAX_HW_POINTS, 1635 + coordinates_x, 1636 + trans == TRANSFER_FUNCTION_HLG12 ? true:false); 1637 + for (i = 0; i <= MAX_HW_POINTS ; i++) { 1638 + points->red[i] = rgb_regamma[i].r; 1639 + points->green[i] = rgb_regamma[i].g; 1640 + points->blue[i] = rgb_regamma[i].b; 1641 + } 1642 + ret = true; 1643 + kvfree(rgb_regamma); 1724 1644 } 1725 1645 rgb_regamma_alloc_fail: 1726 1646 return ret; ··· 1799 1681 } 1800 1682 ret = true; 1801 1683 1684 + kvfree(rgb_degamma); 1685 + } else if (trans == TRANSFER_FUNCTION_HLG || 1686 + trans == TRANSFER_FUNCTION_HLG12) { 1687 + rgb_degamma = kvzalloc(sizeof(*rgb_degamma) * 1688 + (MAX_HW_POINTS + _EXTRA_POINTS), 1689 + GFP_KERNEL); 1690 + if (!rgb_degamma) 1691 + goto rgb_degamma_alloc_fail; 1692 + 1693 + build_hlg_degamma(rgb_degamma, 1694 + MAX_HW_POINTS, 1695 + coordinates_x, 1696 + trans == TRANSFER_FUNCTION_HLG12 ? true:false); 1697 + for (i = 0; i <= MAX_HW_POINTS ; i++) { 1698 + points->red[i] = rgb_degamma[i].r; 1699 + points->green[i] = rgb_degamma[i].g; 1700 + points->blue[i] = rgb_degamma[i].b; 1701 + } 1702 + ret = true; 1802 1703 kvfree(rgb_degamma); 1803 1704 } 1804 1705 points->end_exponent = 0;
+2 -2
drivers/gpu/drm/amd/display/modules/stats/stats.c
··· 29 29 #include "core_types.h" 30 30 31 31 #define DAL_STATS_ENABLE_REGKEY "DalStatsEnable" 32 - #define DAL_STATS_ENABLE_REGKEY_DEFAULT 0x00000001 32 + #define DAL_STATS_ENABLE_REGKEY_DEFAULT 0x00000000 33 33 #define DAL_STATS_ENABLE_REGKEY_ENABLED 0x00000001 34 34 35 35 #define DAL_STATS_ENTRIES_REGKEY "DalStatsEntries" ··· 238 238 for (int i = 0; i < core_stats->entry_id; i++) { 239 239 if (event_index < core_stats->event_index && 240 240 i == events[event_index].entry_id) { 241 - DISPLAY_STATS("%s\n", events[event_index].event_string); 241 + DISPLAY_STATS("==Event==%s\n", events[event_index].event_string); 242 242 event_index++; 243 243 } else if (time_index < core_stats->index && 244 244 i == time[time_index].entry_id) {
+20
drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_offset.h
··· 89 89 #define mmUVD_JPEG_RB_SIZE_BASE_IDX 1 90 90 #define mmUVD_JPEG_ADDR_CONFIG 0x021f 91 91 #define mmUVD_JPEG_ADDR_CONFIG_BASE_IDX 1 92 + #define mmUVD_JPEG_PITCH 0x0222 93 + #define mmUVD_JPEG_PITCH_BASE_IDX 1 92 94 #define mmUVD_JPEG_GPCOM_CMD 0x022c 93 95 #define mmUVD_JPEG_GPCOM_CMD_BASE_IDX 1 94 96 #define mmUVD_JPEG_GPCOM_DATA0 0x022d ··· 205 203 #define mmUVD_RB_WPTR4_BASE_IDX 1 206 204 #define mmUVD_JRBC_RB_RPTR 0x0457 207 205 #define mmUVD_JRBC_RB_RPTR_BASE_IDX 1 206 + #define mmUVD_LMI_JPEG_VMID 0x045d 207 + #define mmUVD_LMI_JPEG_VMID_BASE_IDX 1 208 208 #define mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH 0x045e 209 209 #define mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH_BASE_IDX 1 210 210 #define mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW 0x045f ··· 235 231 #define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_BASE_IDX 1 236 232 #define mmUVD_LMI_JRBC_IB_VMID 0x0507 237 233 #define mmUVD_LMI_JRBC_IB_VMID_BASE_IDX 1 234 + #define mmUVD_LMI_JRBC_RB_VMID 0x0508 235 + #define mmUVD_LMI_JRBC_RB_VMID_BASE_IDX 1 238 236 #define mmUVD_JRBC_RB_WPTR 0x0509 239 237 #define mmUVD_JRBC_RB_WPTR_BASE_IDX 1 240 238 #define mmUVD_JRBC_RB_CNTL 0x050a ··· 245 239 #define mmUVD_JRBC_IB_SIZE_BASE_IDX 1 246 240 #define mmUVD_JRBC_LMI_SWAP_CNTL 0x050d 247 241 #define mmUVD_JRBC_LMI_SWAP_CNTL_BASE_IDX 1 242 + #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW 0x050e 243 + #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_BASE_IDX 1 244 + #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH 0x050f 245 + #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_BASE_IDX 1 246 + #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW 0x0510 247 + #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_BASE_IDX 1 248 + #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH 0x0511 249 + #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_BASE_IDX 1 250 + #define mmUVD_JRBC_RB_REF_DATA 0x0512 251 + #define mmUVD_JRBC_RB_REF_DATA_BASE_IDX 1 252 + #define mmUVD_JRBC_RB_COND_RD_TIMER 0x0513 253 + #define mmUVD_JRBC_RB_COND_RD_TIMER_BASE_IDX 1 254 + #define mmUVD_JRBC_EXTERNAL_REG_BASE 0x0517 255 + #define mmUVD_JRBC_EXTERNAL_REG_BASE_BASE_IDX 1 248 256 #define mmUVD_JRBC_SOFT_RESET 0x0519 249 257 #define mmUVD_JRBC_SOFT_RESET_BASE_IDX 1 250 258 #define mmUVD_JRBC_STATUS 0x051a
+5 -1
drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
··· 81 81 return -EINVAL; 82 82 83 83 hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT; 84 - hwmgr->power_source = PP_PowerSource_AC; 85 84 hwmgr->pp_table_version = PP_TABLE_V1; 86 85 hwmgr->dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; 87 86 hwmgr->request_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO; ··· 235 236 ret = hwmgr->hwmgr_func->backend_init(hwmgr); 236 237 if (ret) 237 238 goto err1; 239 + /* make sure dc limits are valid */ 240 + if ((hwmgr->dyn_state.max_clock_voltage_on_dc.sclk == 0) || 241 + (hwmgr->dyn_state.max_clock_voltage_on_dc.mclk == 0)) 242 + hwmgr->dyn_state.max_clock_voltage_on_dc = 243 + hwmgr->dyn_state.max_clock_voltage_on_ac; 238 244 239 245 ret = psm_init_power_state_table(hwmgr); 240 246 if (ret)
-54
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
··· 39 39 PPSMC_MSG_VCEDPM_Disable); 40 40 } 41 41 42 - static int smu7_enable_disable_samu_dpm(struct pp_hwmgr *hwmgr, bool enable) 43 - { 44 - return smum_send_msg_to_smc(hwmgr, enable ? 45 - PPSMC_MSG_SAMUDPM_Enable : 46 - PPSMC_MSG_SAMUDPM_Disable); 47 - } 48 - 49 42 static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate) 50 43 { 51 44 if (!bgate) ··· 51 58 if (!bgate) 52 59 smum_update_smc_table(hwmgr, SMU_VCE_TABLE); 53 60 return smu7_enable_disable_vce_dpm(hwmgr, !bgate); 54 - } 55 - 56 - static int smu7_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate) 57 - { 58 - if (!bgate) 59 - smum_update_smc_table(hwmgr, SMU_SAMU_TABLE); 60 - return smu7_enable_disable_samu_dpm(hwmgr, !bgate); 61 61 } 62 62 63 63 int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr) ··· 93 107 return 0; 94 108 } 95 109 96 - static int smu7_powerdown_samu(struct pp_hwmgr *hwmgr) 97 - { 98 - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 99 - PHM_PlatformCaps_SamuPowerGating)) 100 - return smum_send_msg_to_smc(hwmgr, 101 - PPSMC_MSG_SAMPowerOFF); 102 - return 0; 103 - } 104 - 105 - static int smu7_powerup_samu(struct pp_hwmgr *hwmgr) 106 - { 107 - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 108 - PHM_PlatformCaps_SamuPowerGating)) 109 - return smum_send_msg_to_smc(hwmgr, 110 - PPSMC_MSG_SAMPowerON); 111 - return 0; 112 - } 113 - 114 110 int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr) 115 111 { 116 112 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 117 113 118 114 data->uvd_power_gated = false; 119 115 data->vce_power_gated = false; 120 - data->samu_power_gated = false; 121 116 122 117 smu7_powerup_uvd(hwmgr); 123 118 smu7_powerup_vce(hwmgr); 124 - smu7_powerup_samu(hwmgr); 125 119 126 120 return 0; 127 121 } ··· 159 193 AMD_PG_STATE_UNGATE); 160 194 smu7_update_vce_dpm(hwmgr, false); 161 195 } 162 - } 163 - 164 - int smu7_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate) 165 - { 166 - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 167 - 168 - if (data->samu_power_gated == bgate) 169 - return 0; 170 - 171 - data->samu_power_gated = bgate; 172 - 173 - if (bgate) { 174 - smu7_update_samu_dpm(hwmgr, true); 175 - smu7_powerdown_samu(hwmgr); 176 - } else { 177 - smu7_powerup_samu(hwmgr); 178 - smu7_update_samu_dpm(hwmgr, false); 179 - } 180 - 181 - return 0; 182 196 } 183 197 184 198 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
-1
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.h
··· 29 29 void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate); 30 30 void smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate); 31 31 int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr); 32 - int smu7_powergate_samu(struct pp_hwmgr *hwmgr, bool bgate); 33 32 int smu7_powergate_acp(struct pp_hwmgr *hwmgr, bool bgate); 34 33 int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr); 35 34 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
+67 -66
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
··· 885 885 data->odn_dpm_table.max_vddc = max_vddc; 886 886 } 887 887 888 + static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr) 889 + { 890 + struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 891 + struct smu7_odn_dpm_table *odn_table = &(data->odn_dpm_table); 892 + struct phm_ppt_v1_information *table_info = 893 + (struct phm_ppt_v1_information *)(hwmgr->pptable); 894 + uint32_t i; 895 + 896 + struct phm_ppt_v1_clock_voltage_dependency_table *dep_table; 897 + struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table; 898 + 899 + if (table_info == NULL) 900 + return; 901 + 902 + for (i = 0; i < data->dpm_table.sclk_table.count; i++) { 903 + if (odn_table->odn_core_clock_dpm_levels.entries[i].clock != 904 + data->dpm_table.sclk_table.dpm_levels[i].value) { 905 + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; 906 + break; 907 + } 908 + } 909 + 910 + for (i = 0; i < data->dpm_table.mclk_table.count; i++) { 911 + if (odn_table->odn_memory_clock_dpm_levels.entries[i].clock != 912 + data->dpm_table.mclk_table.dpm_levels[i].value) { 913 + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; 914 + break; 915 + } 916 + } 917 + 918 + dep_table = table_info->vdd_dep_on_mclk; 919 + odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk); 920 + 921 + for (i = 0; i < dep_table->count; i++) { 922 + if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 923 + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK; 924 + return; 925 + } 926 + } 927 + 928 + dep_table = table_info->vdd_dep_on_sclk; 929 + odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk); 930 + for (i = 0; i < dep_table->count; i++) { 931 + if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 932 + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK; 933 + return; 934 + } 935 + } 936 + if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { 937 + data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; 938 + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK; 939 + } 940 + } 941 + 888 942 static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) 889 943 { 890 944 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); ··· 958 904 959 905 /* initialize ODN table */ 960 906 if (hwmgr->od_enabled) { 961 - smu7_setup_voltage_range_from_vbios(hwmgr); 962 - smu7_odn_initial_default_setting(hwmgr); 907 + if (data->odn_dpm_table.max_vddc) { 908 + smu7_check_dpm_table_updated(hwmgr); 909 + } else { 910 + smu7_setup_voltage_range_from_vbios(hwmgr); 911 + smu7_odn_initial_default_setting(hwmgr); 912 + } 963 913 } 964 - 965 914 return 0; 966 915 } 967 916 ··· 2877 2820 struct pp_power_state *request_ps, 2878 2821 const struct pp_power_state *current_ps) 2879 2822 { 2880 - 2823 + struct amdgpu_device *adev = hwmgr->adev; 2881 2824 struct smu7_power_state *smu7_ps = 2882 2825 cast_phw_smu7_power_state(&request_ps->hardware); 2883 2826 uint32_t sclk; ··· 2900 2843 "VI should always have 2 performance levels", 2901 2844 ); 2902 2845 2903 - max_limits = (PP_PowerSource_AC == hwmgr->power_source) ? 2846 + max_limits = adev->pm.ac_power ? 2904 2847 &(hwmgr->dyn_state.max_clock_voltage_on_ac) : 2905 2848 &(hwmgr->dyn_state.max_clock_voltage_on_dc); 2906 2849 2907 2850 /* Cap clock DPM tables at DC MAX if it is in DC. */ 2908 - if (PP_PowerSource_DC == hwmgr->power_source) { 2851 + if (!adev->pm.ac_power) { 2909 2852 for (i = 0; i < smu7_ps->performance_level_count; i++) { 2910 2853 if (smu7_ps->performance_levels[i].memory_clock > max_limits->mclk) 2911 2854 smu7_ps->performance_levels[i].memory_clock = max_limits->mclk; ··· 3774 3717 uint32_t i; 3775 3718 3776 3719 for (i = 0; i < dpm_table->count; i++) { 3777 - if ((dpm_table->dpm_levels[i].value < low_limit) 3778 - || (dpm_table->dpm_levels[i].value > high_limit)) 3720 + /*skip the trim if od is enabled*/ 3721 + if (!hwmgr->od_enabled && (dpm_table->dpm_levels[i].value < low_limit 3722 + || dpm_table->dpm_levels[i].value > high_limit)) 3779 3723 dpm_table->dpm_levels[i].enabled = false; 3780 3724 else 3781 3725 dpm_table->dpm_levels[i].enabled = true; ··· 3820 3762 const struct smu7_power_state *smu7_ps = 3821 3763 cast_const_phw_smu7_power_state(states->pnew_state); 3822 3764 3823 - /*skip the trim if od is enabled*/ 3824 - if (!hwmgr->od_enabled) 3825 - result = smu7_trim_dpm_states(hwmgr, smu7_ps); 3826 3765 3766 + result = smu7_trim_dpm_states(hwmgr, smu7_ps); 3827 3767 if (result) 3828 3768 return result; 3829 3769 ··· 4300 4244 4301 4245 data->uvd_power_gated = false; 4302 4246 data->vce_power_gated = false; 4303 - data->samu_power_gated = false; 4304 4247 4305 4248 return 0; 4306 4249 } ··· 4792 4737 } 4793 4738 4794 4739 return true; 4795 - } 4796 - 4797 - static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr) 4798 - { 4799 - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 4800 - struct smu7_odn_dpm_table *odn_table = &(data->odn_dpm_table); 4801 - struct phm_ppt_v1_information *table_info = 4802 - (struct phm_ppt_v1_information *)(hwmgr->pptable); 4803 - uint32_t i; 4804 - 4805 - struct phm_ppt_v1_clock_voltage_dependency_table *dep_table; 4806 - struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table; 4807 - 4808 - if (table_info == NULL) 4809 - return; 4810 - 4811 - for (i=0; i<data->dpm_table.sclk_table.count; i++) { 4812 - if (odn_table->odn_core_clock_dpm_levels.entries[i].clock != 4813 - data->dpm_table.sclk_table.dpm_levels[i].value) { 4814 - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; 4815 - break; 4816 - } 4817 - } 4818 - 4819 - for (i=0; i<data->dpm_table.mclk_table.count; i++) { 4820 - if (odn_table->odn_memory_clock_dpm_levels.entries[i].clock != 4821 - data->dpm_table.mclk_table.dpm_levels[i].value) { 4822 - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; 4823 - break; 4824 - } 4825 - } 4826 - 4827 - dep_table = table_info->vdd_dep_on_mclk; 4828 - odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk); 4829 - 4830 - for (i=0; i < dep_table->count; i++) { 4831 - if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 4832 - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK; 4833 - return; 4834 - } 4835 - } 4836 - 4837 - dep_table = table_info->vdd_dep_on_sclk; 4838 - odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk); 4839 - for (i=0; i < dep_table->count; i++) { 4840 - if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 4841 - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK; 4842 - return; 4843 - } 4844 - } 4845 - if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { 4846 - data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; 4847 - data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK; 4848 - } 4849 4740 } 4850 4741 4851 4742 static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
-1
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h
··· 310 310 /* ---- Power Gating States ---- */ 311 311 bool uvd_power_gated; 312 312 bool vce_power_gated; 313 - bool samu_power_gated; 314 313 bool need_long_memory_training; 315 314 316 315 /* Application power optimization parameters */
+46 -38
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
··· 2414 2414 return result; 2415 2415 } 2416 2416 2417 + static void vega10_check_dpm_table_updated(struct pp_hwmgr *hwmgr) 2418 + { 2419 + struct vega10_hwmgr *data = hwmgr->backend; 2420 + struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table); 2421 + struct phm_ppt_v2_information *table_info = hwmgr->pptable; 2422 + struct phm_ppt_v1_clock_voltage_dependency_table *dep_table; 2423 + struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table; 2424 + uint32_t i; 2425 + 2426 + dep_table = table_info->vdd_dep_on_mclk; 2427 + odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_mclk); 2428 + 2429 + for (i = 0; i < dep_table->count; i++) { 2430 + if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 2431 + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK; 2432 + return; 2433 + } 2434 + } 2435 + 2436 + dep_table = table_info->vdd_dep_on_sclk; 2437 + odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_sclk); 2438 + for (i = 0; i < dep_table->count; i++) { 2439 + if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 2440 + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK; 2441 + return; 2442 + } 2443 + } 2444 + 2445 + if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { 2446 + data->need_update_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; 2447 + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK; 2448 + } 2449 + } 2450 + 2417 2451 /** 2418 2452 * Initializes the SMC table and uploads it 2419 2453 * ··· 2464 2430 PPTable_t *pp_table = &(data->smc_state_table.pp_table); 2465 2431 struct pp_atomfwctrl_voltage_table voltage_table; 2466 2432 struct pp_atomfwctrl_bios_boot_up_values boot_up_values; 2433 + struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table); 2467 2434 2468 2435 result = vega10_setup_default_dpm_tables(hwmgr); 2469 2436 PP_ASSERT_WITH_CODE(!result, ··· 2472 2437 return result); 2473 2438 2474 2439 /* initialize ODN table */ 2475 - if (hwmgr->od_enabled) 2476 - vega10_odn_initial_default_setting(hwmgr); 2440 + if (hwmgr->od_enabled) { 2441 + if (odn_table->max_vddc) { 2442 + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK; 2443 + vega10_check_dpm_table_updated(hwmgr); 2444 + } else { 2445 + vega10_odn_initial_default_setting(hwmgr); 2446 + } 2447 + } 2477 2448 2478 2449 pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, 2479 2450 VOLTAGE_OBJ_SVID2, &voltage_table); ··· 3102 3061 struct pp_power_state *request_ps, 3103 3062 const struct pp_power_state *current_ps) 3104 3063 { 3064 + struct amdgpu_device *adev = hwmgr->adev; 3105 3065 struct vega10_power_state *vega10_ps = 3106 3066 cast_phw_vega10_power_state(&request_ps->hardware); 3107 3067 uint32_t sclk; ··· 3128 3086 if (vega10_ps->performance_level_count != 2) 3129 3087 pr_info("VI should always have 2 performance levels"); 3130 3088 3131 - max_limits = (PP_PowerSource_AC == hwmgr->power_source) ? 3089 + max_limits = adev->pm.ac_power ? 3132 3090 &(hwmgr->dyn_state.max_clock_voltage_on_ac) : 3133 3091 &(hwmgr->dyn_state.max_clock_voltage_on_dc); 3134 3092 3135 3093 /* Cap clock DPM tables at DC MAX if it is in DC. */ 3136 - if (PP_PowerSource_DC == hwmgr->power_source) { 3094 + if (!adev->pm.ac_power) { 3137 3095 for (i = 0; i < vega10_ps->performance_level_count; i++) { 3138 3096 if (vega10_ps->performance_levels[i].mem_clock > 3139 3097 max_limits->mclk) ··· 4735 4693 } 4736 4694 4737 4695 return true; 4738 - } 4739 - 4740 - static void vega10_check_dpm_table_updated(struct pp_hwmgr *hwmgr) 4741 - { 4742 - struct vega10_hwmgr *data = hwmgr->backend; 4743 - struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table); 4744 - struct phm_ppt_v2_information *table_info = hwmgr->pptable; 4745 - struct phm_ppt_v1_clock_voltage_dependency_table *dep_table; 4746 - struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table; 4747 - uint32_t i; 4748 - 4749 - dep_table = table_info->vdd_dep_on_mclk; 4750 - odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_mclk); 4751 - 4752 - for (i = 0; i < dep_table->count; i++) { 4753 - if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 4754 - data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK; 4755 - return; 4756 - } 4757 - } 4758 - 4759 - dep_table = table_info->vdd_dep_on_sclk; 4760 - odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_sclk); 4761 - for (i = 0; i < dep_table->count; i++) { 4762 - if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { 4763 - data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK; 4764 - return; 4765 - } 4766 - } 4767 - 4768 - if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { 4769 - data->need_update_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; 4770 - data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK; 4771 - } 4772 4696 } 4773 4697 4774 4698 static void vega10_odn_update_soc_table(struct pp_hwmgr *hwmgr,
-1
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
··· 370 370 /* ---- Power Gating States ---- */ 371 371 bool uvd_power_gated; 372 372 bool vce_power_gated; 373 - bool samu_power_gated; 374 373 bool need_long_memory_training; 375 374 376 375 /* Internal settings to apply the application power optimization parameters */
-2
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
··· 26 26 #include <linux/seq_file.h> 27 27 #include "amd_powerplay.h" 28 28 #include "hardwaremanager.h" 29 - #include "pp_power_source.h" 30 29 #include "hwmgr_ppt.h" 31 30 #include "ppatomctrl.h" 32 31 #include "hwmgr_ppt.h" ··· 740 741 const struct pp_table_func *pptable_func; 741 742 742 743 struct pp_power_state *ps; 743 - enum pp_power_source power_source; 744 744 uint32_t num_ps; 745 745 struct pp_thermal_controller_info thermal_controller; 746 746 bool fan_ctrl_is_in_default_mode;
-36
drivers/gpu/drm/amd/powerplay/inc/pp_power_source.h
··· 1 - /* 2 - * Copyright 2015 Advanced Micro Devices, Inc. 3 - * 4 - * Permission is hereby granted, free of charge, to any person obtaining a 5 - * copy of this software and associated documentation files (the "Software"), 6 - * to deal in the Software without restriction, including without limitation 7 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 - * and/or sell copies of the Software, and to permit persons to whom the 9 - * Software is furnished to do so, subject to the following conditions: 10 - * 11 - * The above copyright notice and this permission notice shall be included in 12 - * all copies or substantial portions of the Software. 13 - * 14 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 - * OTHER DEALINGS IN THE SOFTWARE. 21 - * 22 - */ 23 - 24 - #ifndef PP_POWERSOURCE_H 25 - #define PP_POWERSOURCE_H 26 - 27 - enum pp_power_source { 28 - PP_PowerSource_AC = 0, 29 - PP_PowerSource_DC, 30 - PP_PowerSource_LimitedPower, 31 - PP_PowerSource_LimitedPower_2, 32 - PP_PowerSource_Max 33 - }; 34 - 35 - 36 - #endif
-2
drivers/gpu/drm/amd/powerplay/inc/smumgr.h
··· 29 29 enum SMU_TABLE { 30 30 SMU_UVD_TABLE = 0, 31 31 SMU_VCE_TABLE, 32 - SMU_SAMU_TABLE, 33 32 SMU_BIF_TABLE, 34 33 }; 35 34 ··· 46 47 UcodeLoadStatus, 47 48 UvdBootLevel, 48 49 VceBootLevel, 49 - SamuBootLevel, 50 50 LowSclkInterruptThreshold, 51 51 DRAM_LOG_ADDR_H, 52 52 DRAM_LOG_ADDR_L,
+84 -35
drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
··· 1614 1614 return result; 1615 1615 } 1616 1616 1617 - static int ci_populate_smc_samu_level(struct pp_hwmgr *hwmgr, 1618 - SMU7_Discrete_DpmTable *table) 1619 - { 1620 - int result = -EINVAL; 1621 - uint8_t count; 1622 - struct pp_atomctrl_clock_dividers_vi dividers; 1623 - struct phm_samu_clock_voltage_dependency_table *samu_table = 1624 - hwmgr->dyn_state.samu_clock_voltage_dependency_table; 1625 - 1626 - table->SamuBootLevel = 0; 1627 - table->SamuLevelCount = (uint8_t)(samu_table->count); 1628 - 1629 - for (count = 0; count < table->SamuLevelCount; count++) { 1630 - table->SamuLevel[count].Frequency = samu_table->entries[count].samclk; 1631 - table->SamuLevel[count].MinVoltage = samu_table->entries[count].v * VOLTAGE_SCALE; 1632 - table->SamuLevel[count].MinPhases = 1; 1633 - 1634 - /* retrieve divider value for VBIOS */ 1635 - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, 1636 - table->SamuLevel[count].Frequency, &dividers); 1637 - PP_ASSERT_WITH_CODE((0 == result), 1638 - "can not find divide id for samu clock", return result); 1639 - 1640 - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; 1641 - 1642 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); 1643 - CONVERT_FROM_HOST_TO_SMC_US(table->SamuLevel[count].MinVoltage); 1644 - } 1645 - return result; 1646 - } 1647 - 1648 1617 static int ci_populate_memory_timing_parameters( 1649 1618 struct pp_hwmgr *hwmgr, 1650 1619 uint32_t engine_clock, ··· 1994 2025 result = ci_populate_smc_acp_level(hwmgr, table); 1995 2026 PP_ASSERT_WITH_CODE(0 == result, 1996 2027 "Failed to initialize ACP Level!", return result); 1997 - 1998 - result = ci_populate_smc_samu_level(hwmgr, table); 1999 - PP_ASSERT_WITH_CODE(0 == result, 2000 - "Failed to initialize SAMU Level!", return result); 2001 2028 2002 2029 /* Since only the initial state is completely set up at this point (the other states are just copies of the boot state) we only */ 2003 2030 /* need to populate the ARB settings for the initial state. */ ··· 2846 2881 return 0; 2847 2882 } 2848 2883 2884 + static int ci_update_uvd_smc_table(struct pp_hwmgr *hwmgr) 2885 + { 2886 + struct amdgpu_device *adev = hwmgr->adev; 2887 + struct smu7_hwmgr *data = hwmgr->backend; 2888 + struct ci_smumgr *smu_data = hwmgr->smu_backend; 2889 + struct phm_uvd_clock_voltage_dependency_table *uvd_table = 2890 + hwmgr->dyn_state.uvd_clock_voltage_dependency_table; 2891 + uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | 2892 + AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | 2893 + AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK | 2894 + AMD_DPM_FORCED_LEVEL_PROFILE_PEAK; 2895 + uint32_t max_vddc = adev->pm.ac_power ? hwmgr->dyn_state.max_clock_voltage_on_ac.vddc : 2896 + hwmgr->dyn_state.max_clock_voltage_on_dc.vddc; 2897 + int32_t i; 2898 + 2899 + if (PP_CAP(PHM_PlatformCaps_UVDDPM) || uvd_table->count <= 0) 2900 + smu_data->smc_state_table.UvdBootLevel = 0; 2901 + else 2902 + smu_data->smc_state_table.UvdBootLevel = uvd_table->count - 1; 2903 + 2904 + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, DPM_TABLE_475, 2905 + UvdBootLevel, smu_data->smc_state_table.UvdBootLevel); 2906 + 2907 + data->dpm_level_enable_mask.uvd_dpm_enable_mask = 0; 2908 + 2909 + for (i = uvd_table->count - 1; i >= 0; i--) { 2910 + if (uvd_table->entries[i].v <= max_vddc) 2911 + data->dpm_level_enable_mask.uvd_dpm_enable_mask |= 1 << i; 2912 + if (hwmgr->dpm_level & profile_mode_mask || !PP_CAP(PHM_PlatformCaps_UVDDPM)) 2913 + break; 2914 + } 2915 + ci_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_UVDDPM_SetEnabledMask, 2916 + data->dpm_level_enable_mask.uvd_dpm_enable_mask); 2917 + 2918 + return 0; 2919 + } 2920 + 2921 + static int ci_update_vce_smc_table(struct pp_hwmgr *hwmgr) 2922 + { 2923 + struct amdgpu_device *adev = hwmgr->adev; 2924 + struct smu7_hwmgr *data = hwmgr->backend; 2925 + struct phm_vce_clock_voltage_dependency_table *vce_table = 2926 + hwmgr->dyn_state.vce_clock_voltage_dependency_table; 2927 + uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | 2928 + AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | 2929 + AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK | 2930 + AMD_DPM_FORCED_LEVEL_PROFILE_PEAK; 2931 + uint32_t max_vddc = adev->pm.ac_power ? hwmgr->dyn_state.max_clock_voltage_on_ac.vddc : 2932 + hwmgr->dyn_state.max_clock_voltage_on_dc.vddc; 2933 + int32_t i; 2934 + 2935 + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, DPM_TABLE_475, 2936 + VceBootLevel, 0); /* temp hard code to level 0, vce can set min evclk*/ 2937 + 2938 + data->dpm_level_enable_mask.vce_dpm_enable_mask = 0; 2939 + 2940 + for (i = vce_table->count - 1; i >= 0; i--) { 2941 + if (vce_table->entries[i].v <= max_vddc) 2942 + data->dpm_level_enable_mask.vce_dpm_enable_mask |= 1 << i; 2943 + if (hwmgr->dpm_level & profile_mode_mask || !PP_CAP(PHM_PlatformCaps_VCEDPM)) 2944 + break; 2945 + } 2946 + ci_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_VCEDPM_SetEnabledMask, 2947 + data->dpm_level_enable_mask.vce_dpm_enable_mask); 2948 + 2949 + return 0; 2950 + } 2951 + 2952 + static int ci_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) 2953 + { 2954 + switch (type) { 2955 + case SMU_UVD_TABLE: 2956 + ci_update_uvd_smc_table(hwmgr); 2957 + break; 2958 + case SMU_VCE_TABLE: 2959 + ci_update_vce_smc_table(hwmgr); 2960 + break; 2961 + default: 2962 + break; 2963 + } 2964 + return 0; 2965 + } 2966 + 2849 2967 const struct pp_smumgr_func ci_smu_funcs = { 2850 2968 .smu_init = ci_smu_init, 2851 2969 .smu_fini = ci_smu_fini, ··· 2951 2903 .initialize_mc_reg_table = ci_initialize_mc_reg_table, 2952 2904 .is_dpm_running = ci_is_dpm_running, 2953 2905 .update_dpm_settings = ci_update_dpm_settings, 2906 + .update_smc_table = ci_update_smc_table, 2954 2907 };
-74
drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
··· 1503 1503 return result; 1504 1504 } 1505 1505 1506 - static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr, 1507 - SMU73_Discrete_DpmTable *table) 1508 - { 1509 - int result = -EINVAL; 1510 - uint8_t count; 1511 - struct pp_atomctrl_clock_dividers_vi dividers; 1512 - struct phm_ppt_v1_information *table_info = 1513 - (struct phm_ppt_v1_information *)(hwmgr->pptable); 1514 - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = 1515 - table_info->mm_dep_table; 1516 - 1517 - table->SamuBootLevel = 0; 1518 - table->SamuLevelCount = (uint8_t)(mm_table->count); 1519 - 1520 - for (count = 0; count < table->SamuLevelCount; count++) { 1521 - /* not sure whether we need evclk or not */ 1522 - table->SamuLevel[count].MinVoltage = 0; 1523 - table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; 1524 - table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * 1525 - VOLTAGE_SCALE) << VDDC_SHIFT; 1526 - table->SamuLevel[count].MinVoltage |= ((mm_table->entries[count].vddc - 1527 - VDDC_VDDCI_DELTA) * VOLTAGE_SCALE) << VDDCI_SHIFT; 1528 - table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; 1529 - 1530 - /* retrieve divider value for VBIOS */ 1531 - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, 1532 - table->SamuLevel[count].Frequency, &dividers); 1533 - PP_ASSERT_WITH_CODE((0 == result), 1534 - "can not find divide id for samu clock", return result); 1535 - 1536 - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; 1537 - 1538 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); 1539 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage); 1540 - } 1541 - return result; 1542 - } 1543 - 1544 1506 static int fiji_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr, 1545 1507 int32_t eng_clock, int32_t mem_clock, 1546 1508 struct SMU73_Discrete_MCArbDramTimingTableEntry *arb_regs) ··· 1990 2028 PP_ASSERT_WITH_CODE(0 == result, 1991 2029 "Failed to initialize ACP Level!", return result); 1992 2030 1993 - result = fiji_populate_smc_samu_level(hwmgr, table); 1994 - PP_ASSERT_WITH_CODE(0 == result, 1995 - "Failed to initialize SAMU Level!", return result); 1996 - 1997 2031 /* Since only the initial state is completely set up at this point 1998 2032 * (the other states are just copies of the boot state) we only 1999 2033 * need to populate the ARB settings for the initial state. ··· 2336 2378 return offsetof(SMU73_Discrete_DpmTable, UvdBootLevel); 2337 2379 case VceBootLevel: 2338 2380 return offsetof(SMU73_Discrete_DpmTable, VceBootLevel); 2339 - case SamuBootLevel: 2340 - return offsetof(SMU73_Discrete_DpmTable, SamuBootLevel); 2341 2381 case LowSclkInterruptThreshold: 2342 2382 return offsetof(SMU73_Discrete_DpmTable, LowSclkInterruptThreshold); 2343 2383 } ··· 2434 2478 return 0; 2435 2479 } 2436 2480 2437 - static int fiji_update_samu_smc_table(struct pp_hwmgr *hwmgr) 2438 - { 2439 - struct fiji_smumgr *smu_data = (struct fiji_smumgr *)(hwmgr->smu_backend); 2440 - uint32_t mm_boot_level_offset, mm_boot_level_value; 2441 - 2442 - 2443 - smu_data->smc_state_table.SamuBootLevel = 0; 2444 - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + 2445 - offsetof(SMU73_Discrete_DpmTable, SamuBootLevel); 2446 - 2447 - mm_boot_level_offset /= 4; 2448 - mm_boot_level_offset *= 4; 2449 - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, 2450 - CGS_IND_REG__SMC, mm_boot_level_offset); 2451 - mm_boot_level_value &= 0xFFFFFF00; 2452 - mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; 2453 - cgs_write_ind_register(hwmgr->device, 2454 - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); 2455 - 2456 - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 2457 - PHM_PlatformCaps_StablePState)) 2458 - smum_send_msg_to_smc_with_parameter(hwmgr, 2459 - PPSMC_MSG_SAMUDPM_SetEnabledMask, 2460 - (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); 2461 - return 0; 2462 - } 2463 - 2464 2481 static int fiji_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) 2465 2482 { 2466 2483 switch (type) { ··· 2442 2513 break; 2443 2514 case SMU_VCE_TABLE: 2444 2515 fiji_update_vce_smc_table(hwmgr); 2445 - break; 2446 - case SMU_SAMU_TABLE: 2447 - fiji_update_samu_smc_table(hwmgr); 2448 2516 break; 2449 2517 default: 2450 2518 break;
-10
drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c
··· 1578 1578 return 0; 1579 1579 } 1580 1580 1581 - static int iceland_populate_smc_samu_level(struct pp_hwmgr *hwmgr, 1582 - SMU71_Discrete_DpmTable *table) 1583 - { 1584 - return 0; 1585 - } 1586 - 1587 1581 static int iceland_populate_memory_timing_parameters( 1588 1582 struct pp_hwmgr *hwmgr, 1589 1583 uint32_t engine_clock, ··· 1985 1991 result = iceland_populate_smc_acp_level(hwmgr, table); 1986 1992 PP_ASSERT_WITH_CODE(0 == result, 1987 1993 "Failed to initialize ACP Level!", return result;); 1988 - 1989 - result = iceland_populate_smc_samu_level(hwmgr, table); 1990 - PP_ASSERT_WITH_CODE(0 == result, 1991 - "Failed to initialize SAMU Level!", return result;); 1992 1994 1993 1995 /* Since only the initial state is completely set up at this point (the other states are just copies of the boot state) we only */ 1994 1996 /* need to populate the ARB settings for the initial state. */
-86
drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
··· 1337 1337 return result; 1338 1338 } 1339 1339 1340 - 1341 - static int polaris10_populate_smc_samu_level(struct pp_hwmgr *hwmgr, 1342 - SMU74_Discrete_DpmTable *table) 1343 - { 1344 - int result = -EINVAL; 1345 - uint8_t count; 1346 - struct pp_atomctrl_clock_dividers_vi dividers; 1347 - struct phm_ppt_v1_information *table_info = 1348 - (struct phm_ppt_v1_information *)(hwmgr->pptable); 1349 - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = 1350 - table_info->mm_dep_table; 1351 - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1352 - uint32_t vddci; 1353 - 1354 - table->SamuBootLevel = 0; 1355 - table->SamuLevelCount = (uint8_t)(mm_table->count); 1356 - 1357 - for (count = 0; count < table->SamuLevelCount; count++) { 1358 - /* not sure whether we need evclk or not */ 1359 - table->SamuLevel[count].MinVoltage = 0; 1360 - table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; 1361 - table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * 1362 - VOLTAGE_SCALE) << VDDC_SHIFT; 1363 - 1364 - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) 1365 - vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), 1366 - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); 1367 - else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) 1368 - vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; 1369 - else 1370 - vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; 1371 - 1372 - table->SamuLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; 1373 - table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; 1374 - 1375 - /* retrieve divider value for VBIOS */ 1376 - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, 1377 - table->SamuLevel[count].Frequency, &dividers); 1378 - PP_ASSERT_WITH_CODE((0 == result), 1379 - "can not find divide id for samu clock", return result); 1380 - 1381 - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; 1382 - 1383 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); 1384 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage); 1385 - } 1386 - return result; 1387 - } 1388 - 1389 1340 static int polaris10_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr, 1390 1341 int32_t eng_clock, int32_t mem_clock, 1391 1342 SMU74_Discrete_MCArbDramTimingTableEntry *arb_regs) ··· 1816 1865 PP_ASSERT_WITH_CODE(0 == result, 1817 1866 "Failed to initialize VCE Level!", return result); 1818 1867 1819 - result = polaris10_populate_smc_samu_level(hwmgr, table); 1820 - PP_ASSERT_WITH_CODE(0 == result, 1821 - "Failed to initialize SAMU Level!", return result); 1822 - 1823 1868 /* Since only the initial state is completely set up at this point 1824 1869 * (the other states are just copies of the boot state) we only 1825 1870 * need to populate the ARB settings for the initial state. ··· 2169 2222 return 0; 2170 2223 } 2171 2224 2172 - static int polaris10_update_samu_smc_table(struct pp_hwmgr *hwmgr) 2173 - { 2174 - struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); 2175 - uint32_t mm_boot_level_offset, mm_boot_level_value; 2176 - 2177 - 2178 - smu_data->smc_state_table.SamuBootLevel = 0; 2179 - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + 2180 - offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); 2181 - 2182 - mm_boot_level_offset /= 4; 2183 - mm_boot_level_offset *= 4; 2184 - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, 2185 - CGS_IND_REG__SMC, mm_boot_level_offset); 2186 - mm_boot_level_value &= 0xFFFFFF00; 2187 - mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; 2188 - cgs_write_ind_register(hwmgr->device, 2189 - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); 2190 - 2191 - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 2192 - PHM_PlatformCaps_StablePState)) 2193 - smum_send_msg_to_smc_with_parameter(hwmgr, 2194 - PPSMC_MSG_SAMUDPM_SetEnabledMask, 2195 - (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); 2196 - return 0; 2197 - } 2198 - 2199 - 2200 2225 static int polaris10_update_bif_smc_table(struct pp_hwmgr *hwmgr) 2201 2226 { 2202 2227 struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend); ··· 2194 2275 break; 2195 2276 case SMU_VCE_TABLE: 2196 2277 polaris10_update_vce_smc_table(hwmgr); 2197 - break; 2198 - case SMU_SAMU_TABLE: 2199 - polaris10_update_samu_smc_table(hwmgr); 2200 2278 break; 2201 2279 case SMU_BIF_TABLE: 2202 2280 polaris10_update_bif_smc_table(hwmgr); ··· 2273 2357 return offsetof(SMU74_Discrete_DpmTable, UvdBootLevel); 2274 2358 case VceBootLevel: 2275 2359 return offsetof(SMU74_Discrete_DpmTable, VceBootLevel); 2276 - case SamuBootLevel: 2277 - return offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); 2278 2360 case LowSclkInterruptThreshold: 2279 2361 return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold); 2280 2362 }
-80
drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c
··· 1443 1443 return result; 1444 1444 } 1445 1445 1446 - static int tonga_populate_smc_samu_level(struct pp_hwmgr *hwmgr, 1447 - SMU72_Discrete_DpmTable *table) 1448 - { 1449 - int result = 0; 1450 - uint8_t count; 1451 - pp_atomctrl_clock_dividers_vi dividers; 1452 - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1453 - struct phm_ppt_v1_information *pptable_info = 1454 - (struct phm_ppt_v1_information *)(hwmgr->pptable); 1455 - phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = 1456 - pptable_info->mm_dep_table; 1457 - 1458 - table->SamuBootLevel = 0; 1459 - table->SamuLevelCount = (uint8_t) (mm_table->count); 1460 - 1461 - for (count = 0; count < table->SamuLevelCount; count++) { 1462 - /* not sure whether we need evclk or not */ 1463 - table->SamuLevel[count].Frequency = 1464 - pptable_info->mm_dep_table->entries[count].samclock; 1465 - table->SamuLevel[count].MinVoltage.Vddc = 1466 - phm_get_voltage_index(pptable_info->vddc_lookup_table, 1467 - mm_table->entries[count].vddc); 1468 - table->SamuLevel[count].MinVoltage.VddGfx = 1469 - (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) ? 1470 - phm_get_voltage_index(pptable_info->vddgfx_lookup_table, 1471 - mm_table->entries[count].vddgfx) : 0; 1472 - table->SamuLevel[count].MinVoltage.Vddci = 1473 - phm_get_voltage_id(&data->vddci_voltage_table, 1474 - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); 1475 - table->SamuLevel[count].MinVoltage.Phases = 1; 1476 - 1477 - /* retrieve divider value for VBIOS */ 1478 - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, 1479 - table->SamuLevel[count].Frequency, &dividers); 1480 - PP_ASSERT_WITH_CODE((!result), 1481 - "can not find divide id for samu clock", return result); 1482 - 1483 - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; 1484 - 1485 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); 1486 - } 1487 - 1488 - return result; 1489 - } 1490 - 1491 1446 static int tonga_populate_memory_timing_parameters( 1492 1447 struct pp_hwmgr *hwmgr, 1493 1448 uint32_t engine_clock, ··· 2278 2323 PP_ASSERT_WITH_CODE(!result, 2279 2324 "Failed to initialize ACP Level !", return result); 2280 2325 2281 - result = tonga_populate_smc_samu_level(hwmgr, table); 2282 - PP_ASSERT_WITH_CODE(!result, 2283 - "Failed to initialize SAMU Level !", return result); 2284 - 2285 2326 /* Since only the initial state is completely set up at this 2286 2327 * point (the other states are just copies of the boot state) we only 2287 2328 * need to populate the ARB settings for the initial state. ··· 2624 2673 return offsetof(SMU72_Discrete_DpmTable, UvdBootLevel); 2625 2674 case VceBootLevel: 2626 2675 return offsetof(SMU72_Discrete_DpmTable, VceBootLevel); 2627 - case SamuBootLevel: 2628 - return offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); 2629 2676 case LowSclkInterruptThreshold: 2630 2677 return offsetof(SMU72_Discrete_DpmTable, LowSclkInterruptThreshold); 2631 2678 } ··· 2722 2773 return 0; 2723 2774 } 2724 2775 2725 - static int tonga_update_samu_smc_table(struct pp_hwmgr *hwmgr) 2726 - { 2727 - struct tonga_smumgr *smu_data = (struct tonga_smumgr *)(hwmgr->smu_backend); 2728 - uint32_t mm_boot_level_offset, mm_boot_level_value; 2729 - 2730 - smu_data->smc_state_table.SamuBootLevel = 0; 2731 - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + 2732 - offsetof(SMU72_Discrete_DpmTable, SamuBootLevel); 2733 - 2734 - mm_boot_level_offset /= 4; 2735 - mm_boot_level_offset *= 4; 2736 - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, 2737 - CGS_IND_REG__SMC, mm_boot_level_offset); 2738 - mm_boot_level_value &= 0xFFFFFF00; 2739 - mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; 2740 - cgs_write_ind_register(hwmgr->device, 2741 - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); 2742 - 2743 - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 2744 - PHM_PlatformCaps_StablePState)) 2745 - smum_send_msg_to_smc_with_parameter(hwmgr, 2746 - PPSMC_MSG_SAMUDPM_SetEnabledMask, 2747 - (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); 2748 - return 0; 2749 - } 2750 - 2751 2776 static int tonga_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type) 2752 2777 { 2753 2778 switch (type) { ··· 2730 2807 break; 2731 2808 case SMU_VCE_TABLE: 2732 2809 tonga_update_vce_smc_table(hwmgr); 2733 - break; 2734 - case SMU_SAMU_TABLE: 2735 - tonga_update_samu_smc_table(hwmgr); 2736 2810 break; 2737 2811 default: 2738 2812 break;
-85
drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c
··· 393 393 return 0; 394 394 } 395 395 396 - static int vegam_update_samu_smc_table(struct pp_hwmgr *hwmgr) 397 - { 398 - struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend); 399 - uint32_t mm_boot_level_offset, mm_boot_level_value; 400 - 401 - 402 - smu_data->smc_state_table.SamuBootLevel = 0; 403 - mm_boot_level_offset = smu_data->smu7_data.dpm_table_start + 404 - offsetof(SMU75_Discrete_DpmTable, SamuBootLevel); 405 - 406 - mm_boot_level_offset /= 4; 407 - mm_boot_level_offset *= 4; 408 - mm_boot_level_value = cgs_read_ind_register(hwmgr->device, 409 - CGS_IND_REG__SMC, mm_boot_level_offset); 410 - mm_boot_level_value &= 0xFFFFFF00; 411 - mm_boot_level_value |= smu_data->smc_state_table.SamuBootLevel << 0; 412 - cgs_write_ind_register(hwmgr->device, 413 - CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value); 414 - 415 - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 416 - PHM_PlatformCaps_StablePState)) 417 - smum_send_msg_to_smc_with_parameter(hwmgr, 418 - PPSMC_MSG_SAMUDPM_SetEnabledMask, 419 - (uint32_t)(1 << smu_data->smc_state_table.SamuBootLevel)); 420 - return 0; 421 - } 422 - 423 - 424 396 static int vegam_update_bif_smc_table(struct pp_hwmgr *hwmgr) 425 397 { 426 398 struct vegam_smumgr *smu_data = (struct vegam_smumgr *)(hwmgr->smu_backend); ··· 418 446 break; 419 447 case SMU_VCE_TABLE: 420 448 vegam_update_vce_smc_table(hwmgr); 421 - break; 422 - case SMU_SAMU_TABLE: 423 - vegam_update_samu_smc_table(hwmgr); 424 449 break; 425 450 case SMU_BIF_TABLE: 426 451 vegam_update_bif_smc_table(hwmgr); ··· 1250 1281 return result; 1251 1282 } 1252 1283 1253 - static int vegam_populate_smc_samu_level(struct pp_hwmgr *hwmgr, 1254 - SMU75_Discrete_DpmTable *table) 1255 - { 1256 - int result = -EINVAL; 1257 - uint8_t count; 1258 - struct pp_atomctrl_clock_dividers_vi dividers; 1259 - struct phm_ppt_v1_information *table_info = 1260 - (struct phm_ppt_v1_information *)(hwmgr->pptable); 1261 - struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table = 1262 - table_info->mm_dep_table; 1263 - struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); 1264 - uint32_t vddci; 1265 - 1266 - table->SamuBootLevel = 0; 1267 - table->SamuLevelCount = (uint8_t)(mm_table->count); 1268 - 1269 - for (count = 0; count < table->SamuLevelCount; count++) { 1270 - /* not sure whether we need evclk or not */ 1271 - table->SamuLevel[count].MinVoltage = 0; 1272 - table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; 1273 - table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * 1274 - VOLTAGE_SCALE) << VDDC_SHIFT; 1275 - 1276 - if (SMU7_VOLTAGE_CONTROL_BY_GPIO == data->vddci_control) 1277 - vddci = (uint32_t)phm_find_closest_vddci(&(data->vddci_voltage_table), 1278 - mm_table->entries[count].vddc - VDDC_VDDCI_DELTA); 1279 - else if (SMU7_VOLTAGE_CONTROL_BY_SVID2 == data->vddci_control) 1280 - vddci = mm_table->entries[count].vddc - VDDC_VDDCI_DELTA; 1281 - else 1282 - vddci = (data->vbios_boot_state.vddci_bootup_value * VOLTAGE_SCALE) << VDDCI_SHIFT; 1283 - 1284 - table->SamuLevel[count].MinVoltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; 1285 - table->SamuLevel[count].MinVoltage |= 1 << PHASES_SHIFT; 1286 - 1287 - /* retrieve divider value for VBIOS */ 1288 - result = atomctrl_get_dfs_pll_dividers_vi(hwmgr, 1289 - table->SamuLevel[count].Frequency, &dividers); 1290 - PP_ASSERT_WITH_CODE((0 == result), 1291 - "can not find divide id for samu clock", return result); 1292 - 1293 - table->SamuLevel[count].Divider = (uint8_t)dividers.pll_post_divider; 1294 - 1295 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].Frequency); 1296 - CONVERT_FROM_HOST_TO_SMC_UL(table->SamuLevel[count].MinVoltage); 1297 - } 1298 - return result; 1299 - } 1300 - 1301 1284 static int vegam_populate_memory_timing_parameters(struct pp_hwmgr *hwmgr, 1302 1285 int32_t eng_clock, int32_t mem_clock, 1303 1286 SMU75_Discrete_MCArbDramTimingTableEntry *arb_regs) ··· 1983 2062 PP_ASSERT_WITH_CODE(!result, 1984 2063 "Failed to initialize VCE Level!", return result); 1985 2064 1986 - result = vegam_populate_smc_samu_level(hwmgr, table); 1987 - PP_ASSERT_WITH_CODE(!result, 1988 - "Failed to initialize SAMU Level!", return result); 1989 - 1990 2065 /* Since only the initial state is completely set up at this point 1991 2066 * (the other states are just copies of the boot state) we only 1992 2067 * need to populate the ARB settings for the initial state. ··· 2190 2273 return offsetof(SMU75_Discrete_DpmTable, UvdBootLevel); 2191 2274 case VceBootLevel: 2192 2275 return offsetof(SMU75_Discrete_DpmTable, VceBootLevel); 2193 - case SamuBootLevel: 2194 - return offsetof(SMU75_Discrete_DpmTable, SamuBootLevel); 2195 2276 case LowSclkInterruptThreshold: 2196 2277 return offsetof(SMU75_Discrete_DpmTable, LowSclkInterruptThreshold); 2197 2278 }
+4 -4
drivers/gpu/drm/radeon/radeon_ttm.c
··· 947 947 static struct vm_operations_struct radeon_ttm_vm_ops; 948 948 static const struct vm_operations_struct *ttm_vm_ops = NULL; 949 949 950 - static int radeon_ttm_fault(struct vm_fault *vmf) 950 + static vm_fault_t radeon_ttm_fault(struct vm_fault *vmf) 951 951 { 952 952 struct ttm_buffer_object *bo; 953 953 struct radeon_device *rdev; 954 - int r; 954 + vm_fault_t ret; 955 955 956 956 bo = (struct ttm_buffer_object *)vmf->vma->vm_private_data; 957 957 if (bo == NULL) { ··· 959 959 } 960 960 rdev = radeon_get_rdev(bo->bdev); 961 961 down_read(&rdev->pm.mclk_lock); 962 - r = ttm_vm_ops->fault(vmf); 962 + ret = ttm_vm_ops->fault(vmf); 963 963 up_read(&rdev->pm.mclk_lock); 964 - return r; 964 + return ret; 965 965 } 966 966 967 967 int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
+221 -60
drivers/gpu/drm/scheduler/gpu_scheduler.c
··· 21 21 * 22 22 */ 23 23 24 + /** 25 + * DOC: Overview 26 + * 27 + * The GPU scheduler provides entities which allow userspace to push jobs 28 + * into software queues which are then scheduled on a hardware run queue. 29 + * The software queues have a priority among them. The scheduler selects the entities 30 + * from the run queue using a FIFO. The scheduler provides dependency handling 31 + * features among jobs. The driver is supposed to provide callback functions for 32 + * backend operations to the scheduler like submitting a job to hardware run queue, 33 + * returning the dependencies of a job etc. 34 + * 35 + * The organisation of the scheduler is the following: 36 + * 37 + * 1. Each hw run queue has one scheduler 38 + * 2. Each scheduler has multiple run queues with different priorities 39 + * (e.g., HIGH_HW,HIGH_SW, KERNEL, NORMAL) 40 + * 3. Each scheduler run queue has a queue of entities to schedule 41 + * 4. Entities themselves maintain a queue of jobs that will be scheduled on 42 + * the hardware. 43 + * 44 + * The jobs in a entity are always scheduled in the order that they were pushed. 45 + */ 46 + 24 47 #include <linux/kthread.h> 25 48 #include <linux/wait.h> 26 49 #include <linux/sched.h> ··· 62 39 static void drm_sched_wakeup(struct drm_gpu_scheduler *sched); 63 40 static void drm_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb); 64 41 65 - /* Initialize a given run queue struct */ 42 + /** 43 + * drm_sched_rq_init - initialize a given run queue struct 44 + * 45 + * @rq: scheduler run queue 46 + * 47 + * Initializes a scheduler runqueue. 48 + */ 66 49 static void drm_sched_rq_init(struct drm_sched_rq *rq) 67 50 { 68 51 spin_lock_init(&rq->lock); ··· 76 47 rq->current_entity = NULL; 77 48 } 78 49 50 + /** 51 + * drm_sched_rq_add_entity - add an entity 52 + * 53 + * @rq: scheduler run queue 54 + * @entity: scheduler entity 55 + * 56 + * Adds a scheduler entity to the run queue. 57 + */ 79 58 static void drm_sched_rq_add_entity(struct drm_sched_rq *rq, 80 59 struct drm_sched_entity *entity) 81 60 { ··· 94 57 spin_unlock(&rq->lock); 95 58 } 96 59 60 + /** 61 + * drm_sched_rq_remove_entity - remove an entity 62 + * 63 + * @rq: scheduler run queue 64 + * @entity: scheduler entity 65 + * 66 + * Removes a scheduler entity from the run queue. 67 + */ 97 68 static void drm_sched_rq_remove_entity(struct drm_sched_rq *rq, 98 69 struct drm_sched_entity *entity) 99 70 { ··· 115 70 } 116 71 117 72 /** 118 - * Select an entity which could provide a job to run 73 + * drm_sched_rq_select_entity - Select an entity which could provide a job to run 119 74 * 120 - * @rq The run queue to check. 75 + * @rq: scheduler run queue to check. 121 76 * 122 77 * Try to find a ready entity, returns NULL if none found. 123 78 */ ··· 157 112 } 158 113 159 114 /** 160 - * Init a context entity used by scheduler when submit to HW ring. 115 + * drm_sched_entity_init - Init a context entity used by scheduler when 116 + * submit to HW ring. 161 117 * 162 - * @sched The pointer to the scheduler 163 - * @entity The pointer to a valid drm_sched_entity 164 - * @rq The run queue this entity belongs 165 - * @guilty atomic_t set to 1 when a job on this queue 166 - * is found to be guilty causing a timeout 118 + * @sched: scheduler instance 119 + * @entity: scheduler entity to init 120 + * @rq: the run queue this entity belongs 121 + * @guilty: atomic_t set to 1 when a job on this queue 122 + * is found to be guilty causing a timeout 167 123 * 168 - * return 0 if succeed. negative error code on failure 124 + * Returns 0 on success or a negative error code on failure. 169 125 */ 170 126 int drm_sched_entity_init(struct drm_gpu_scheduler *sched, 171 127 struct drm_sched_entity *entity, ··· 181 135 entity->rq = rq; 182 136 entity->sched = sched; 183 137 entity->guilty = guilty; 184 - entity->fini_status = 0; 185 138 entity->last_scheduled = NULL; 186 139 187 140 spin_lock_init(&entity->rq_lock); ··· 194 149 EXPORT_SYMBOL(drm_sched_entity_init); 195 150 196 151 /** 197 - * Query if entity is initialized 152 + * drm_sched_entity_is_initialized - Query if entity is initialized 198 153 * 199 - * @sched Pointer to scheduler instance 200 - * @entity The pointer to a valid scheduler entity 154 + * @sched: Pointer to scheduler instance 155 + * @entity: The pointer to a valid scheduler entity 201 156 * 202 157 * return true if entity is initialized, false otherwise 203 158 */ ··· 209 164 } 210 165 211 166 /** 212 - * Check if entity is idle 167 + * drm_sched_entity_is_idle - Check if entity is idle 213 168 * 214 - * @entity The pointer to a valid scheduler entity 169 + * @entity: scheduler entity 215 170 * 216 - * Return true if entity don't has any unscheduled jobs. 171 + * Returns true if the entity does not have any unscheduled jobs. 217 172 */ 218 173 static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity) 219 174 { 220 175 rmb(); 221 - if (spsc_queue_peek(&entity->job_queue) == NULL) 176 + 177 + if (!entity->rq || spsc_queue_peek(&entity->job_queue) == NULL) 222 178 return true; 223 179 224 180 return false; 225 181 } 226 182 227 183 /** 228 - * Check if entity is ready 184 + * drm_sched_entity_is_ready - Check if entity is ready 229 185 * 230 - * @entity The pointer to a valid scheduler entity 186 + * @entity: scheduler entity 231 187 * 232 188 * Return true if entity could provide a job. 233 189 */ ··· 256 210 257 211 258 212 /** 259 - * Destroy a context entity 213 + * drm_sched_entity_do_release - Destroy a context entity 260 214 * 261 - * @sched Pointer to scheduler instance 262 - * @entity The pointer to a valid scheduler entity 215 + * @sched: scheduler instance 216 + * @entity: scheduler entity 217 + * @timeout: time to wait in for Q to become empty in jiffies. 263 218 * 264 - * Splitting drm_sched_entity_fini() into two functions, The first one is does the waiting, 219 + * Splitting drm_sched_entity_fini() into two functions, The first one does the waiting, 265 220 * removes the entity from the runqueue and returns an error when the process was killed. 221 + * 222 + * Returns the remaining time in jiffies left from the input timeout 266 223 */ 267 - void drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, 268 - struct drm_sched_entity *entity) 224 + long drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, 225 + struct drm_sched_entity *entity, long timeout) 269 226 { 227 + long ret = timeout; 228 + 270 229 if (!drm_sched_entity_is_initialized(sched, entity)) 271 - return; 230 + return ret; 272 231 /** 273 232 * The client will not queue more IBs during this fini, consume existing 274 233 * queued IBs or discard them on SIGKILL 275 234 */ 276 - if ((current->flags & PF_SIGNALED) && current->exit_code == SIGKILL) 277 - entity->fini_status = -ERESTARTSYS; 278 - else 279 - entity->fini_status = wait_event_killable(sched->job_scheduled, 280 - drm_sched_entity_is_idle(entity)); 281 - drm_sched_entity_set_rq(entity, NULL); 235 + if (current->flags & PF_EXITING) { 236 + if (timeout) 237 + ret = wait_event_timeout( 238 + sched->job_scheduled, 239 + drm_sched_entity_is_idle(entity), 240 + timeout); 241 + } else 242 + wait_event_killable(sched->job_scheduled, drm_sched_entity_is_idle(entity)); 243 + 244 + 245 + /* For killed process disable any more IBs enqueue right now */ 246 + if ((current->flags & PF_EXITING) && (current->exit_code == SIGKILL)) 247 + drm_sched_entity_set_rq(entity, NULL); 248 + 249 + return ret; 282 250 } 283 251 EXPORT_SYMBOL(drm_sched_entity_do_release); 284 252 285 253 /** 286 - * Destroy a context entity 254 + * drm_sched_entity_cleanup - Destroy a context entity 287 255 * 288 - * @sched Pointer to scheduler instance 289 - * @entity The pointer to a valid scheduler entity 256 + * @sched: scheduler instance 257 + * @entity: scheduler entity 290 258 * 291 - * The second one then goes over the entity and signals all jobs with an error code. 259 + * This should be called after @drm_sched_entity_do_release. It goes over the 260 + * entity and signals all jobs with an error code if the process was killed. 261 + * 292 262 */ 293 263 void drm_sched_entity_cleanup(struct drm_gpu_scheduler *sched, 294 264 struct drm_sched_entity *entity) 295 265 { 296 - if (entity->fini_status) { 266 + 267 + drm_sched_entity_set_rq(entity, NULL); 268 + 269 + /* Consumption of existing IBs wasn't completed. Forcefully 270 + * remove them here. 271 + */ 272 + if (spsc_queue_peek(&entity->job_queue)) { 297 273 struct drm_sched_job *job; 298 274 int r; 299 275 ··· 335 267 struct drm_sched_fence *s_fence = job->s_fence; 336 268 drm_sched_fence_scheduled(s_fence); 337 269 dma_fence_set_error(&s_fence->finished, -ESRCH); 338 - r = dma_fence_add_callback(entity->last_scheduled, &job->finish_cb, 339 - drm_sched_entity_kill_jobs_cb); 340 - if (r == -ENOENT) 270 + 271 + /* 272 + * When pipe is hanged by older entity, new entity might 273 + * not even have chance to submit it's first job to HW 274 + * and so entity->last_scheduled will remain NULL 275 + */ 276 + if (!entity->last_scheduled) { 341 277 drm_sched_entity_kill_jobs_cb(NULL, &job->finish_cb); 342 - else if (r) 343 - DRM_ERROR("fence add callback failed (%d)\n", r); 278 + } else { 279 + r = dma_fence_add_callback(entity->last_scheduled, &job->finish_cb, 280 + drm_sched_entity_kill_jobs_cb); 281 + if (r == -ENOENT) 282 + drm_sched_entity_kill_jobs_cb(NULL, &job->finish_cb); 283 + else if (r) 284 + DRM_ERROR("fence add callback failed (%d)\n", r); 285 + } 344 286 } 345 287 } 346 288 ··· 359 281 } 360 282 EXPORT_SYMBOL(drm_sched_entity_cleanup); 361 283 284 + /** 285 + * drm_sched_entity_fini - Destroy a context entity 286 + * 287 + * @sched: scheduler instance 288 + * @entity: scheduler entity 289 + * 290 + * Calls drm_sched_entity_do_release() and drm_sched_entity_cleanup() 291 + */ 362 292 void drm_sched_entity_fini(struct drm_gpu_scheduler *sched, 363 293 struct drm_sched_entity *entity) 364 294 { 365 - drm_sched_entity_do_release(sched, entity); 295 + drm_sched_entity_do_release(sched, entity, MAX_WAIT_SCHED_ENTITY_Q_EMPTY); 366 296 drm_sched_entity_cleanup(sched, entity); 367 297 } 368 298 EXPORT_SYMBOL(drm_sched_entity_fini); ··· 392 306 dma_fence_put(f); 393 307 } 394 308 309 + /** 310 + * drm_sched_entity_set_rq - Sets the run queue for an entity 311 + * 312 + * @entity: scheduler entity 313 + * @rq: scheduler run queue 314 + * 315 + * Sets the run queue for an entity and removes the entity from the previous 316 + * run queue in which was present. 317 + */ 395 318 void drm_sched_entity_set_rq(struct drm_sched_entity *entity, 396 319 struct drm_sched_rq *rq) 397 320 { ··· 420 325 } 421 326 EXPORT_SYMBOL(drm_sched_entity_set_rq); 422 327 328 + /** 329 + * drm_sched_dependency_optimized 330 + * 331 + * @fence: the dependency fence 332 + * @entity: the entity which depends on the above fence 333 + * 334 + * Returns true if the dependency can be optimized and false otherwise 335 + */ 423 336 bool drm_sched_dependency_optimized(struct dma_fence* fence, 424 337 struct drm_sched_entity *entity) 425 338 { ··· 516 413 } 517 414 518 415 /** 519 - * Submit a job to the job queue 416 + * drm_sched_entity_push_job - Submit a job to the entity's job queue 520 417 * 521 - * @sched_job The pointer to job required to submit 418 + * @sched_job: job to submit 419 + * @entity: scheduler entity 522 420 * 523 421 * Note: To guarantee that the order of insertion to queue matches 524 422 * the job's fence sequence number this function should be ··· 610 506 job->sched->ops->timedout_job(job); 611 507 } 612 508 509 + /** 510 + * drm_sched_hw_job_reset - stop the scheduler if it contains the bad job 511 + * 512 + * @sched: scheduler instance 513 + * @bad: bad scheduler job 514 + * 515 + */ 613 516 void drm_sched_hw_job_reset(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad) 614 517 { 615 518 struct drm_sched_job *s_job; ··· 661 550 } 662 551 EXPORT_SYMBOL(drm_sched_hw_job_reset); 663 552 553 + /** 554 + * drm_sched_job_recovery - recover jobs after a reset 555 + * 556 + * @sched: scheduler instance 557 + * 558 + */ 664 559 void drm_sched_job_recovery(struct drm_gpu_scheduler *sched) 665 560 { 666 561 struct drm_sched_job *s_job, *tmp; ··· 716 599 EXPORT_SYMBOL(drm_sched_job_recovery); 717 600 718 601 /** 719 - * Init a sched_job with basic field 602 + * drm_sched_job_init - init a scheduler job 720 603 * 721 - * Note: Refer to drm_sched_entity_push_job documentation 604 + * @job: scheduler job to init 605 + * @sched: scheduler instance 606 + * @entity: scheduler entity to use 607 + * @owner: job owner for debugging 608 + * 609 + * Refer to drm_sched_entity_push_job() documentation 722 610 * for locking considerations. 611 + * 612 + * Returns 0 for success, negative error code otherwise. 723 613 */ 724 614 int drm_sched_job_init(struct drm_sched_job *job, 725 615 struct drm_gpu_scheduler *sched, ··· 750 626 EXPORT_SYMBOL(drm_sched_job_init); 751 627 752 628 /** 753 - * Return ture if we can push more jobs to the hw. 629 + * drm_sched_ready - is the scheduler ready 630 + * 631 + * @sched: scheduler instance 632 + * 633 + * Return true if we can push more jobs to the hw, otherwise false. 754 634 */ 755 635 static bool drm_sched_ready(struct drm_gpu_scheduler *sched) 756 636 { ··· 763 635 } 764 636 765 637 /** 766 - * Wake up the scheduler when it is ready 638 + * drm_sched_wakeup - Wake up the scheduler when it is ready 639 + * 640 + * @sched: scheduler instance 641 + * 767 642 */ 768 643 static void drm_sched_wakeup(struct drm_gpu_scheduler *sched) 769 644 { ··· 775 644 } 776 645 777 646 /** 778 - * Select next entity to process 779 - */ 647 + * drm_sched_select_entity - Select next entity to process 648 + * 649 + * @sched: scheduler instance 650 + * 651 + * Returns the entity to process or NULL if none are found. 652 + */ 780 653 static struct drm_sched_entity * 781 654 drm_sched_select_entity(struct drm_gpu_scheduler *sched) 782 655 { ··· 800 665 return entity; 801 666 } 802 667 668 + /** 669 + * drm_sched_process_job - process a job 670 + * 671 + * @f: fence 672 + * @cb: fence callbacks 673 + * 674 + * Called after job has finished execution. 675 + */ 803 676 static void drm_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb) 804 677 { 805 678 struct drm_sched_fence *s_fence = ··· 823 680 wake_up_interruptible(&sched->wake_up_worker); 824 681 } 825 682 683 + /** 684 + * drm_sched_blocked - check if the scheduler is blocked 685 + * 686 + * @sched: scheduler instance 687 + * 688 + * Returns true if blocked, otherwise false. 689 + */ 826 690 static bool drm_sched_blocked(struct drm_gpu_scheduler *sched) 827 691 { 828 692 if (kthread_should_park()) { ··· 840 690 return false; 841 691 } 842 692 693 + /** 694 + * drm_sched_main - main scheduler thread 695 + * 696 + * @param: scheduler instance 697 + * 698 + * Returns 0. 699 + */ 843 700 static int drm_sched_main(void *param) 844 701 { 845 702 struct sched_param sparam = {.sched_priority = 1}; ··· 901 744 } 902 745 903 746 /** 904 - * Init a gpu scheduler instance 747 + * drm_sched_init - Init a gpu scheduler instance 905 748 * 906 - * @sched The pointer to the scheduler 907 - * @ops The backend operations for this scheduler. 908 - * @hw_submissions Number of hw submissions to do. 909 - * @name Name used for debugging 749 + * @sched: scheduler instance 750 + * @ops: backend operations for this scheduler 751 + * @hw_submission: number of hw submissions that can be in flight 752 + * @hang_limit: number of times to allow a job to hang before dropping it 753 + * @timeout: timeout value in jiffies for the scheduler 754 + * @name: name used for debugging 910 755 * 911 756 * Return 0 on success, otherwise error code. 912 - */ 757 + */ 913 758 int drm_sched_init(struct drm_gpu_scheduler *sched, 914 759 const struct drm_sched_backend_ops *ops, 915 760 unsigned hw_submission, ··· 947 788 EXPORT_SYMBOL(drm_sched_init); 948 789 949 790 /** 950 - * Destroy a gpu scheduler 791 + * drm_sched_fini - Destroy a gpu scheduler 951 792 * 952 - * @sched The pointer to the scheduler 793 + * @sched: scheduler instance 794 + * 795 + * Tears down and cleans up the scheduler. 953 796 */ 954 797 void drm_sched_fini(struct drm_gpu_scheduler *sched) 955 798 {
+22 -23
drivers/gpu/drm/ttm/ttm_bo_vm.c
··· 44 44 45 45 #define TTM_BO_VM_NUM_PREFAULT 16 46 46 47 - static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, 47 + static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo, 48 48 struct vm_fault *vmf) 49 49 { 50 - int ret = 0; 50 + vm_fault_t ret = 0; 51 + int err = 0; 51 52 52 53 if (likely(!bo->moving)) 53 54 goto out_unlock; ··· 79 78 /* 80 79 * Ordinary wait. 81 80 */ 82 - ret = dma_fence_wait(bo->moving, true); 83 - if (unlikely(ret != 0)) { 84 - ret = (ret != -ERESTARTSYS) ? VM_FAULT_SIGBUS : 81 + err = dma_fence_wait(bo->moving, true); 82 + if (unlikely(err != 0)) { 83 + ret = (err != -ERESTARTSYS) ? VM_FAULT_SIGBUS : 85 84 VM_FAULT_NOPAGE; 86 85 goto out_unlock; 87 86 } ··· 106 105 + page_offset; 107 106 } 108 107 109 - static int ttm_bo_vm_fault(struct vm_fault *vmf) 108 + static vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) 110 109 { 111 110 struct vm_area_struct *vma = vmf->vma; 112 111 struct ttm_buffer_object *bo = (struct ttm_buffer_object *) ··· 117 116 unsigned long pfn; 118 117 struct ttm_tt *ttm = NULL; 119 118 struct page *page; 120 - int ret; 119 + int err; 121 120 int i; 121 + vm_fault_t ret = VM_FAULT_NOPAGE; 122 122 unsigned long address = vmf->address; 123 123 struct ttm_mem_type_manager *man = 124 124 &bdev->man[bo->mem.mem_type]; ··· 131 129 * for reserve, and if it fails, retry the fault after waiting 132 130 * for the buffer to become unreserved. 133 131 */ 134 - ret = ttm_bo_reserve(bo, true, true, NULL); 135 - if (unlikely(ret != 0)) { 136 - if (ret != -EBUSY) 132 + err = ttm_bo_reserve(bo, true, true, NULL); 133 + if (unlikely(err != 0)) { 134 + if (err != -EBUSY) 137 135 return VM_FAULT_NOPAGE; 138 136 139 137 if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) { ··· 165 163 } 166 164 167 165 if (bdev->driver->fault_reserve_notify) { 168 - ret = bdev->driver->fault_reserve_notify(bo); 169 - switch (ret) { 166 + err = bdev->driver->fault_reserve_notify(bo); 167 + switch (err) { 170 168 case 0: 171 169 break; 172 170 case -EBUSY: ··· 194 192 goto out_unlock; 195 193 } 196 194 197 - ret = ttm_mem_io_lock(man, true); 198 - if (unlikely(ret != 0)) { 195 + err = ttm_mem_io_lock(man, true); 196 + if (unlikely(err != 0)) { 199 197 ret = VM_FAULT_NOPAGE; 200 198 goto out_unlock; 201 199 } 202 - ret = ttm_mem_io_reserve_vm(bo); 203 - if (unlikely(ret != 0)) { 200 + err = ttm_mem_io_reserve_vm(bo); 201 + if (unlikely(err != 0)) { 204 202 ret = VM_FAULT_SIGBUS; 205 203 goto out_io_unlock; 206 204 } ··· 268 266 } 269 267 270 268 if (vma->vm_flags & VM_MIXEDMAP) 271 - ret = vm_insert_mixed(&cvma, address, 269 + ret = vmf_insert_mixed(&cvma, address, 272 270 __pfn_to_pfn_t(pfn, PFN_DEV)); 273 271 else 274 - ret = vm_insert_pfn(&cvma, address, pfn); 272 + ret = vmf_insert_pfn(&cvma, address, pfn); 275 273 276 274 /* 277 275 * Somebody beat us to this PTE or prefaulting to 278 276 * an already populated PTE, or prefaulting error. 279 277 */ 280 278 281 - if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0))) 279 + if (unlikely((ret == VM_FAULT_NOPAGE && i > 0))) 282 280 break; 283 - else if (unlikely(ret != 0)) { 284 - ret = 285 - (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; 281 + else if (unlikely(ret & VM_FAULT_ERROR)) 286 282 goto out_io_unlock; 287 - } 288 283 289 284 address += PAGE_SIZE; 290 285 if (unlikely(++page_offset >= page_last))
+127 -31
include/drm/gpu_scheduler.h
··· 27 27 #include <drm/spsc_queue.h> 28 28 #include <linux/dma-fence.h> 29 29 30 + #define MAX_WAIT_SCHED_ENTITY_Q_EMPTY msecs_to_jiffies(1000) 31 + 30 32 struct drm_gpu_scheduler; 31 33 struct drm_sched_rq; 32 34 ··· 45 43 }; 46 44 47 45 /** 48 - * drm_sched_entity - A wrapper around a job queue (typically attached 49 - * to the DRM file_priv). 46 + * struct drm_sched_entity - A wrapper around a job queue (typically 47 + * attached to the DRM file_priv). 48 + * 49 + * @list: used to append this struct to the list of entities in the 50 + * runqueue. 51 + * @rq: runqueue to which this entity belongs. 52 + * @rq_lock: lock to modify the runqueue to which this entity belongs. 53 + * @sched: the scheduler instance to which this entity is enqueued. 54 + * @job_queue: the list of jobs of this entity. 55 + * @fence_seq: a linearly increasing seqno incremented with each 56 + * new &drm_sched_fence which is part of the entity. 57 + * @fence_context: a unique context for all the fences which belong 58 + * to this entity. 59 + * The &drm_sched_fence.scheduled uses the 60 + * fence_context but &drm_sched_fence.finished uses 61 + * fence_context + 1. 62 + * @dependency: the dependency fence of the job which is on the top 63 + * of the job queue. 64 + * @cb: callback for the dependency fence above. 65 + * @guilty: points to ctx's guilty. 66 + * @fini_status: contains the exit status in case the process was signalled. 67 + * @last_scheduled: points to the finished fence of the last scheduled job. 50 68 * 51 69 * Entities will emit jobs in order to their corresponding hardware 52 70 * ring, and the scheduler will alternate between entities based on 53 71 * scheduling policy. 54 - */ 72 + */ 55 73 struct drm_sched_entity { 56 74 struct list_head list; 57 75 struct drm_sched_rq *rq; ··· 85 63 86 64 struct dma_fence *dependency; 87 65 struct dma_fence_cb cb; 88 - atomic_t *guilty; /* points to ctx's guilty */ 89 - int fini_status; 90 - struct dma_fence *last_scheduled; 66 + atomic_t *guilty; 67 + struct dma_fence *last_scheduled; 91 68 }; 92 69 93 70 /** 71 + * struct drm_sched_rq - queue of entities to be scheduled. 72 + * 73 + * @lock: to modify the entities list. 74 + * @entities: list of the entities to be scheduled. 75 + * @current_entity: the entity which is to be scheduled. 76 + * 94 77 * Run queue is a set of entities scheduling command submissions for 95 78 * one specific ring. It implements the scheduling policy that selects 96 79 * the next entity to emit commands from. 97 - */ 80 + */ 98 81 struct drm_sched_rq { 99 82 spinlock_t lock; 100 83 struct list_head entities; 101 84 struct drm_sched_entity *current_entity; 102 85 }; 103 86 87 + /** 88 + * struct drm_sched_fence - fences corresponding to the scheduling of a job. 89 + */ 104 90 struct drm_sched_fence { 91 + /** 92 + * @scheduled: this fence is what will be signaled by the scheduler 93 + * when the job is scheduled. 94 + */ 105 95 struct dma_fence scheduled; 106 96 107 - /* This fence is what will be signaled by the scheduler when 108 - * the job is completed. 109 - * 110 - * When setting up an out fence for the job, you should use 111 - * this, since it's available immediately upon 112 - * drm_sched_job_init(), and the fence returned by the driver 113 - * from run_job() won't be created until the dependencies have 114 - * resolved. 115 - */ 97 + /** 98 + * @finished: this fence is what will be signaled by the scheduler 99 + * when the job is completed. 100 + * 101 + * When setting up an out fence for the job, you should use 102 + * this, since it's available immediately upon 103 + * drm_sched_job_init(), and the fence returned by the driver 104 + * from run_job() won't be created until the dependencies have 105 + * resolved. 106 + */ 116 107 struct dma_fence finished; 117 108 109 + /** 110 + * @cb: the callback for the parent fence below. 111 + */ 118 112 struct dma_fence_cb cb; 113 + /** 114 + * @parent: the fence returned by &drm_sched_backend_ops.run_job 115 + * when scheduling the job on hardware. We signal the 116 + * &drm_sched_fence.finished fence once parent is signalled. 117 + */ 119 118 struct dma_fence *parent; 119 + /** 120 + * @sched: the scheduler instance to which the job having this struct 121 + * belongs to. 122 + */ 120 123 struct drm_gpu_scheduler *sched; 124 + /** 125 + * @lock: the lock used by the scheduled and the finished fences. 126 + */ 121 127 spinlock_t lock; 128 + /** 129 + * @owner: job owner for debugging 130 + */ 122 131 void *owner; 123 132 }; 124 133 125 134 struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); 126 135 127 136 /** 128 - * drm_sched_job - A job to be run by an entity. 137 + * struct drm_sched_job - A job to be run by an entity. 138 + * 139 + * @queue_node: used to append this struct to the queue of jobs in an entity. 140 + * @sched: the scheduler instance on which this job is scheduled. 141 + * @s_fence: contains the fences for the scheduling of job. 142 + * @finish_cb: the callback for the finished fence. 143 + * @finish_work: schedules the function @drm_sched_job_finish once the job has 144 + * finished to remove the job from the 145 + * @drm_gpu_scheduler.ring_mirror_list. 146 + * @node: used to append this struct to the @drm_gpu_scheduler.ring_mirror_list. 147 + * @work_tdr: schedules a delayed call to @drm_sched_job_timedout after the timeout 148 + * interval is over. 149 + * @id: a unique id assigned to each job scheduled on the scheduler. 150 + * @karma: increment on every hang caused by this job. If this exceeds the hang 151 + * limit of the scheduler then the job is marked guilty and will not 152 + * be scheduled further. 153 + * @s_priority: the priority of the job. 154 + * @entity: the entity to which this job belongs. 129 155 * 130 156 * A job is created by the driver using drm_sched_job_init(), and 131 157 * should call drm_sched_entity_push_job() once it wants the scheduler ··· 200 130 } 201 131 202 132 /** 133 + * struct drm_sched_backend_ops 134 + * 203 135 * Define the backend operations called by the scheduler, 204 - * these functions should be implemented in driver side 205 - */ 136 + * these functions should be implemented in driver side. 137 + */ 206 138 struct drm_sched_backend_ops { 207 - /* Called when the scheduler is considering scheduling this 208 - * job next, to get another struct dma_fence for this job to 139 + /** 140 + * @dependency: Called when the scheduler is considering scheduling 141 + * this job next, to get another struct dma_fence for this job to 209 142 * block on. Once it returns NULL, run_job() may be called. 210 143 */ 211 144 struct dma_fence *(*dependency)(struct drm_sched_job *sched_job, 212 145 struct drm_sched_entity *s_entity); 213 146 214 - /* Called to execute the job once all of the dependencies have 215 - * been resolved. This may be called multiple times, if 147 + /** 148 + * @run_job: Called to execute the job once all of the dependencies 149 + * have been resolved. This may be called multiple times, if 216 150 * timedout_job() has happened and drm_sched_job_recovery() 217 151 * decides to try it again. 218 152 */ 219 153 struct dma_fence *(*run_job)(struct drm_sched_job *sched_job); 220 154 221 - /* Called when a job has taken too long to execute, to trigger 222 - * GPU recovery. 155 + /** 156 + * @timedout_job: Called when a job has taken too long to execute, 157 + * to trigger GPU recovery. 223 158 */ 224 159 void (*timedout_job)(struct drm_sched_job *sched_job); 225 160 226 - /* Called once the job's finished fence has been signaled and 227 - * it's time to clean it up. 161 + /** 162 + * @free_job: Called once the job's finished fence has been signaled 163 + * and it's time to clean it up. 228 164 */ 229 165 void (*free_job)(struct drm_sched_job *sched_job); 230 166 }; 231 167 232 168 /** 233 - * One scheduler is implemented for each hardware ring 234 - */ 169 + * struct drm_gpu_scheduler 170 + * 171 + * @ops: backend operations provided by the driver. 172 + * @hw_submission_limit: the max size of the hardware queue. 173 + * @timeout: the time after which a job is removed from the scheduler. 174 + * @name: name of the ring for which this scheduler is being used. 175 + * @sched_rq: priority wise array of run queues. 176 + * @wake_up_worker: the wait queue on which the scheduler sleeps until a job 177 + * is ready to be scheduled. 178 + * @job_scheduled: once @drm_sched_entity_do_release is called the scheduler 179 + * waits on this wait queue until all the scheduled jobs are 180 + * finished. 181 + * @hw_rq_count: the number of jobs currently in the hardware queue. 182 + * @job_id_count: used to assign unique id to the each job. 183 + * @thread: the kthread on which the scheduler which run. 184 + * @ring_mirror_list: the list of jobs which are currently in the job queue. 185 + * @job_list_lock: lock to protect the ring_mirror_list. 186 + * @hang_limit: once the hangs by a job crosses this limit then it is marked 187 + * guilty and it will be considered for scheduling further. 188 + * 189 + * One scheduler is implemented for each hardware ring. 190 + */ 235 191 struct drm_gpu_scheduler { 236 192 const struct drm_sched_backend_ops *ops; 237 193 uint32_t hw_submission_limit; ··· 284 188 struct drm_sched_entity *entity, 285 189 struct drm_sched_rq *rq, 286 190 atomic_t *guilty); 287 - void drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, 288 - struct drm_sched_entity *entity); 191 + long drm_sched_entity_do_release(struct drm_gpu_scheduler *sched, 192 + struct drm_sched_entity *entity, long timeout); 289 193 void drm_sched_entity_cleanup(struct drm_gpu_scheduler *sched, 290 194 struct drm_sched_entity *entity); 291 195 void drm_sched_entity_fini(struct drm_gpu_scheduler *sched,
+25 -1
include/uapi/drm/amdgpu_drm.h
··· 72 72 #define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle) 73 73 #define DRM_IOCTL_AMDGPU_SCHED DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched) 74 74 75 + /** 76 + * DOC: memory domains 77 + * 78 + * %AMDGPU_GEM_DOMAIN_CPU System memory that is not GPU accessible. 79 + * Memory in this pool could be swapped out to disk if there is pressure. 80 + * 81 + * %AMDGPU_GEM_DOMAIN_GTT GPU accessible system memory, mapped into the 82 + * GPU's virtual address space via gart. Gart memory linearizes non-contiguous 83 + * pages of system memory, allows GPU access system memory in a linezrized 84 + * fashion. 85 + * 86 + * %AMDGPU_GEM_DOMAIN_VRAM Local video memory. For APUs, it is memory 87 + * carved out by the BIOS. 88 + * 89 + * %AMDGPU_GEM_DOMAIN_GDS Global on-chip data storage used to share data 90 + * across shader threads. 91 + * 92 + * %AMDGPU_GEM_DOMAIN_GWS Global wave sync, used to synchronize the 93 + * execution of all the waves on a device. 94 + * 95 + * %AMDGPU_GEM_DOMAIN_OA Ordered append, used by 3D or Compute engines 96 + * for appending data. 97 + */ 75 98 #define AMDGPU_GEM_DOMAIN_CPU 0x1 76 99 #define AMDGPU_GEM_DOMAIN_GTT 0x2 77 100 #define AMDGPU_GEM_DOMAIN_VRAM 0x4 ··· 506 483 #define AMDGPU_HW_IP_UVD_ENC 5 507 484 #define AMDGPU_HW_IP_VCN_DEC 6 508 485 #define AMDGPU_HW_IP_VCN_ENC 7 509 - #define AMDGPU_HW_IP_NUM 8 486 + #define AMDGPU_HW_IP_VCN_JPEG 8 487 + #define AMDGPU_HW_IP_NUM 9 510 488 511 489 #define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1 512 490