diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-02 10:54:12 +0300 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-02 10:54:12 +0300 |
commit | 5599617ec0719dba3b1f85a4abca2a6c93368ae3 (patch) | |
tree | 7d2f9bb6a538ee8ed5cfa391f2cfa72a3e2daa9f /drivers/gpu | |
parent | 8d19d7d9dbc25d1a1ffa602ed9eff25a88c98163 (diff) | |
parent | 66fd7a66e8b9e11e49f46ea77910f935c4dee5c3 (diff) | |
download | linux-5599617ec0719dba3b1f85a4abca2a6c93368ae3.tar.xz |
Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next-queued
Git got absolutely destroyed with all our cherry-picking from
drm-intel-next-queued to various branches. It ended up inserting
intel_crtc_page_flip 2x even in intel_display.c.
Backmerge to get back to sanity.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/gpu')
360 files changed, 3308 insertions, 1615 deletions
diff --git a/drivers/gpu/drm/amd/acp/Kconfig b/drivers/gpu/drm/amd/acp/Kconfig index ca77ec10147c..e503e3d6d920 100644 --- a/drivers/gpu/drm/amd/acp/Kconfig +++ b/drivers/gpu/drm/amd/acp/Kconfig @@ -2,6 +2,7 @@ menu "ACP (Audio CoProcessor) Configuration" config DRM_AMD_ACP bool "Enable AMD Audio CoProcessor IP support" + depends on DRM_AMDGPU select MFD_CORE select PM_GENERIC_DOMAINS if PM help diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 2a009c398dcb..992f00b65be4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -602,6 +602,8 @@ int amdgpu_sync_wait(struct amdgpu_sync *sync); void amdgpu_sync_free(struct amdgpu_sync *sync); int amdgpu_sync_init(void); void amdgpu_sync_fini(void); +int amdgpu_fence_slab_init(void); +void amdgpu_fence_slab_fini(void); /* * GART structures, functions & helpers diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 35d0856738ae..823bf5e0b0c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -106,7 +106,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, struct amdgpu_bo *bo; struct mm_struct *usermm; - gobj = drm_gem_object_lookup(adev->ddev, filp, info[i].bo_handle); + gobj = drm_gem_object_lookup(filp, info[i].bo_handle); if (!gobj) { r = -ENOENT; goto error_free; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index 60a0c9ac11b2..cb07da41152b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -194,12 +194,12 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) bpc = 8; DRM_DEBUG("%s: HDMI deep color 10 bpc exceeds max tmds clock. Using %d bpc.\n", connector->name, bpc); - } else if (bpc > 8) { - /* max_tmds_clock missing, but hdmi spec mandates it for deep color. */ - DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n", - connector->name); - bpc = 8; } + } else if (bpc > 8) { + /* max_tmds_clock missing, but hdmi spec mandates it for deep color. */ + DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n", + connector->name); + bpc = 8; } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 2bbeeb07c187..9bc8f1d99733 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -92,8 +92,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, { struct drm_gem_object *gobj; - gobj = drm_gem_object_lookup(p->adev->ddev, p->filp, - data->handle); + gobj = drm_gem_object_lookup(p->filp, data->handle); if (gobj == NULL) return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 726803069fef..b0832da2ef7e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -563,7 +563,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev, struct amdgpu_framebuffer *amdgpu_fb; int ret; - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); if (obj == NULL) { dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " "can't create framebuffer\n", mode_cmd->handles[0]); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 1dab5f2b725b..f888c015f76c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -50,9 +50,11 @@ * KMS wrapper. * - 3.0.0 - initial driver * - 3.1.0 - allow reading more status registers (GRBM, SRBM, SDMA, CP) + * - 3.2.0 - GFX8: Uses EOP_TC_WB_ACTION_EN, so UMDs don't have to do the same + * at the end of IBs. */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 1 +#define KMS_DRIVER_MINOR 2 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; @@ -279,14 +281,26 @@ static const struct pci_device_id pciidlist[] = { {0x1002, 0x98E4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_STONEY|AMD_IS_APU}, /* Polaris11 */ {0x1002, 0x67E0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, - {0x1002, 0x67E1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, + {0x1002, 0x67E3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, {0x1002, 0x67E8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, - {0x1002, 0x67E9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, {0x1002, 0x67EB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, + {0x1002, 0x67EF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, {0x1002, 0x67FF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, + {0x1002, 0x67E1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, + {0x1002, 0x67E7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, + {0x1002, 0x67E9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS11}, /* Polaris10 */ {0x1002, 0x67C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67C2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, {0x1002, 0x67DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67C8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67C9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, + {0x1002, 0x67CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS10}, {0, 0, 0} }; @@ -563,9 +577,12 @@ static struct pci_driver amdgpu_kms_pci_driver = { .driver.pm = &amdgpu_pm_ops, }; + + static int __init amdgpu_init(void) { amdgpu_sync_init(); + amdgpu_fence_slab_init(); if (vgacon_text_force()) { DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); return -EINVAL; @@ -576,7 +593,6 @@ static int __init amdgpu_init(void) driver->driver_features |= DRIVER_MODESET; driver->num_ioctls = amdgpu_max_kms_ioctl; amdgpu_register_atpx_handler(); - /* let modprobe override vga console setting */ return drm_pci_init(driver, pdriver); } @@ -587,6 +603,7 @@ static void __exit amdgpu_exit(void) drm_pci_exit(driver, pdriver); amdgpu_unregister_atpx_handler(); amdgpu_sync_fini(); + amdgpu_fence_slab_fini(); } module_init(amdgpu_init); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index ba9c04283d01..d1558768cfb7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -55,8 +55,21 @@ struct amdgpu_fence { }; static struct kmem_cache *amdgpu_fence_slab; -static atomic_t amdgpu_fence_slab_ref = ATOMIC_INIT(0); +int amdgpu_fence_slab_init(void) +{ + amdgpu_fence_slab = kmem_cache_create( + "amdgpu_fence", sizeof(struct amdgpu_fence), 0, + SLAB_HWCACHE_ALIGN, NULL); + if (!amdgpu_fence_slab) + return -ENOMEM; + return 0; +} + +void amdgpu_fence_slab_fini(void) +{ + kmem_cache_destroy(amdgpu_fence_slab); +} /* * Cast helper */ @@ -396,13 +409,6 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, */ int amdgpu_fence_driver_init(struct amdgpu_device *adev) { - if (atomic_inc_return(&amdgpu_fence_slab_ref) == 1) { - amdgpu_fence_slab = kmem_cache_create( - "amdgpu_fence", sizeof(struct amdgpu_fence), 0, - SLAB_HWCACHE_ALIGN, NULL); - if (!amdgpu_fence_slab) - return -ENOMEM; - } if (amdgpu_debugfs_fence_init(adev)) dev_err(adev->dev, "fence debugfs file creation failed\n"); @@ -437,13 +443,10 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) amd_sched_fini(&ring->sched); del_timer_sync(&ring->fence_drv.fallback_timer); for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) - fence_put(ring->fence_drv.fences[i]); + fence_put(ring->fence_drv.fences[j]); kfree(ring->fence_drv.fences); ring->fence_drv.initialized = false; } - - if (atomic_dec_and_test(&amdgpu_fence_slab_ref)) - kmem_cache_destroy(amdgpu_fence_slab); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index c68f4cacaa85..8fab6486064f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -338,7 +338,7 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp, struct drm_gem_object *gobj; struct amdgpu_bo *robj; - gobj = drm_gem_object_lookup(dev, filp, handle); + gobj = drm_gem_object_lookup(filp, handle); if (gobj == NULL) { return -ENOENT; } @@ -402,7 +402,7 @@ int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data, int r = 0; long ret; - gobj = drm_gem_object_lookup(dev, filp, handle); + gobj = drm_gem_object_lookup(filp, handle); if (gobj == NULL) { return -ENOENT; } @@ -436,7 +436,7 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data, int r = -1; DRM_DEBUG("%d \n", args->handle); - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) return -ENOENT; robj = gem_to_amdgpu_bo(gobj); @@ -584,7 +584,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) return -ENOENT; rbo = gem_to_amdgpu_bo(gobj); @@ -646,7 +646,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, struct amdgpu_bo *robj; int r; - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { return -ENOENT; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 9266c7b69808..835a3fa8d8df 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -219,7 +219,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev) if (r) { return r; } - adev->ddev->vblank_disable_allowed = true; /* enable msi */ adev->irq.msi_enabled = false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index 9f4a45cd2aab..32fa7b7913f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c @@ -232,7 +232,10 @@ static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) int r; mutex_lock(&adev->mn_lock); - down_write(&mm->mmap_sem); + if (down_write_killable(&mm->mmap_sem)) { + mutex_unlock(&adev->mn_lock); + return ERR_PTR(-EINTR); + } hash_for_each_possible(adev->mn_hash, rmn, node, (unsigned long)mm) if (rmn->mm == mm) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ea708cb94862..9f36ed30ba11 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -53,6 +53,18 @@ /* Special value that no flush is necessary */ #define AMDGPU_VM_NO_FLUSH (~0ll) +/* Local structure. Encapsulate some VM table update parameters to reduce + * the number of function parameters + */ +struct amdgpu_vm_update_params { + /* address where to copy page table entries from */ + uint64_t src; + /* DMA addresses to use for mapping */ + dma_addr_t *pages_addr; + /* indirect buffer to fill with commands */ + struct amdgpu_ib *ib; +}; + /** * amdgpu_vm_num_pde - return the number of page directory entries * @@ -389,9 +401,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, * amdgpu_vm_update_pages - helper to call the right asic function * * @adev: amdgpu_device pointer - * @src: address where to copy page table entries from - * @pages_addr: DMA addresses to use for mapping - * @ib: indirect buffer to fill with commands + * @vm_update_params: see amdgpu_vm_update_params definition * @pe: addr of the page entry * @addr: dst addr to write into pe * @count: number of page entries to update @@ -402,29 +412,29 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, * to setup the page table using the DMA. */ static void amdgpu_vm_update_pages(struct amdgpu_device *adev, - uint64_t src, - dma_addr_t *pages_addr, - struct amdgpu_ib *ib, + struct amdgpu_vm_update_params + *vm_update_params, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags) { trace_amdgpu_vm_set_page(pe, addr, count, incr, flags); - if (src) { - src += (addr >> 12) * 8; - amdgpu_vm_copy_pte(adev, ib, pe, src, count); + if (vm_update_params->src) { + amdgpu_vm_copy_pte(adev, vm_update_params->ib, + pe, (vm_update_params->src + (addr >> 12) * 8), count); - } else if (pages_addr) { - amdgpu_vm_write_pte(adev, ib, pages_addr, pe, addr, - count, incr, flags); + } else if (vm_update_params->pages_addr) { + amdgpu_vm_write_pte(adev, vm_update_params->ib, + vm_update_params->pages_addr, + pe, addr, count, incr, flags); } else if (count < 3) { - amdgpu_vm_write_pte(adev, ib, NULL, pe, addr, + amdgpu_vm_write_pte(adev, vm_update_params->ib, NULL, pe, addr, count, incr, flags); } else { - amdgpu_vm_set_pte_pde(adev, ib, pe, addr, + amdgpu_vm_set_pte_pde(adev, vm_update_params->ib, pe, addr, count, incr, flags); } } @@ -444,10 +454,12 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, struct amdgpu_ring *ring; struct fence *fence = NULL; struct amdgpu_job *job; + struct amdgpu_vm_update_params vm_update_params; unsigned entries; uint64_t addr; int r; + memset(&vm_update_params, 0, sizeof(vm_update_params)); ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); r = reservation_object_reserve_shared(bo->tbo.resv); @@ -465,7 +477,8 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, if (r) goto error; - amdgpu_vm_update_pages(adev, 0, NULL, &job->ibs[0], addr, 0, entries, + vm_update_params.ib = &job->ibs[0]; + amdgpu_vm_update_pages(adev, &vm_update_params, addr, 0, entries, 0, 0); amdgpu_ring_pad_ib(ring, &job->ibs[0]); @@ -538,11 +551,12 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, uint64_t last_pde = ~0, last_pt = ~0; unsigned count = 0, pt_idx, ndw; struct amdgpu_job *job; - struct amdgpu_ib *ib; + struct amdgpu_vm_update_params vm_update_params; struct fence *fence = NULL; int r; + memset(&vm_update_params, 0, sizeof(vm_update_params)); ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); /* padding, etc. */ @@ -555,7 +569,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, if (r) return r; - ib = &job->ibs[0]; + vm_update_params.ib = &job->ibs[0]; /* walk over the address space and update the page directory */ for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { @@ -575,7 +589,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ((last_pt + incr * count) != pt)) { if (count) { - amdgpu_vm_update_pages(adev, 0, NULL, ib, + amdgpu_vm_update_pages(adev, &vm_update_params, last_pde, last_pt, count, incr, AMDGPU_PTE_VALID); @@ -590,14 +604,15 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, } if (count) - amdgpu_vm_update_pages(adev, 0, NULL, ib, last_pde, last_pt, - count, incr, AMDGPU_PTE_VALID); + amdgpu_vm_update_pages(adev, &vm_update_params, + last_pde, last_pt, + count, incr, AMDGPU_PTE_VALID); - if (ib->length_dw != 0) { - amdgpu_ring_pad_ib(ring, ib); + if (vm_update_params.ib->length_dw != 0) { + amdgpu_ring_pad_ib(ring, vm_update_params.ib); amdgpu_sync_resv(adev, &job->sync, pd->tbo.resv, AMDGPU_FENCE_OWNER_VM); - WARN_ON(ib->length_dw > ndw); + WARN_ON(vm_update_params.ib->length_dw > ndw); r = amdgpu_job_submit(job, ring, &vm->entity, AMDGPU_FENCE_OWNER_VM, &fence); if (r) @@ -623,18 +638,15 @@ error_free: * amdgpu_vm_frag_ptes - add fragment information to PTEs * * @adev: amdgpu_device pointer - * @src: address where to copy page table entries from - * @pages_addr: DMA addresses to use for mapping - * @ib: IB for the update + * @vm_update_params: see amdgpu_vm_update_params definition * @pe_start: first PTE to handle * @pe_end: last PTE to handle * @addr: addr those PTEs should point to * @flags: hw mapping flags */ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, - uint64_t src, - dma_addr_t *pages_addr, - struct amdgpu_ib *ib, + struct amdgpu_vm_update_params + *vm_update_params, uint64_t pe_start, uint64_t pe_end, uint64_t addr, uint32_t flags) { @@ -671,11 +683,11 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, return; /* system pages are non continuously */ - if (src || pages_addr || !(flags & AMDGPU_PTE_VALID) || - (frag_start >= frag_end)) { + if (vm_update_params->src || vm_update_params->pages_addr || + !(flags & AMDGPU_PTE_VALID) || (frag_start >= frag_end)) { count = (pe_end - pe_start) / 8; - amdgpu_vm_update_pages(adev, src, pages_addr, ib, pe_start, + amdgpu_vm_update_pages(adev, vm_update_params, pe_start, addr, count, AMDGPU_GPU_PAGE_SIZE, flags); return; @@ -684,21 +696,21 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, /* handle the 4K area at the beginning */ if (pe_start != frag_start) { count = (frag_start - pe_start) / 8; - amdgpu_vm_update_pages(adev, 0, NULL, ib, pe_start, addr, + amdgpu_vm_update_pages(adev, vm_update_params, pe_start, addr, count, AMDGPU_GPU_PAGE_SIZE, flags); addr += AMDGPU_GPU_PAGE_SIZE * count; } /* handle the area in the middle */ count = (frag_end - frag_start) / 8; - amdgpu_vm_update_pages(adev, 0, NULL, ib, frag_start, addr, count, + amdgpu_vm_update_pages(adev, vm_update_params, frag_start, addr, count, AMDGPU_GPU_PAGE_SIZE, flags | frag_flags); /* handle the 4K area at the end */ if (frag_end != pe_end) { addr += AMDGPU_GPU_PAGE_SIZE * count; count = (pe_end - frag_end) / 8; - amdgpu_vm_update_pages(adev, 0, NULL, ib, frag_end, addr, + amdgpu_vm_update_pages(adev, vm_update_params, frag_end, addr, count, AMDGPU_GPU_PAGE_SIZE, flags); } } @@ -707,8 +719,7 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, * amdgpu_vm_update_ptes - make sure that page tables are valid * * @adev: amdgpu_device pointer - * @src: address where to copy page table entries from - * @pages_addr: DMA addresses to use for mapping + * @vm_update_params: see amdgpu_vm_update_params definition * @vm: requested vm * @start: start of GPU address range * @end: end of GPU address range @@ -718,10 +729,9 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, * Update the page tables in the range @start - @end. */ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, - uint64_t src, - dma_addr_t *pages_addr, + struct amdgpu_vm_update_params + *vm_update_params, struct amdgpu_vm *vm, - struct amdgpu_ib *ib, uint64_t start, uint64_t end, uint64_t dst, uint32_t flags) { @@ -747,7 +757,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, if (last_pe_end != pe_start) { - amdgpu_vm_frag_ptes(adev, src, pages_addr, ib, + amdgpu_vm_frag_ptes(adev, vm_update_params, last_pe_start, last_pe_end, last_dst, flags); @@ -762,7 +772,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, dst += nptes * AMDGPU_GPU_PAGE_SIZE; } - amdgpu_vm_frag_ptes(adev, src, pages_addr, ib, last_pe_start, + amdgpu_vm_frag_ptes(adev, vm_update_params, last_pe_start, last_pe_end, last_dst, flags); } @@ -794,11 +804,14 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, void *owner = AMDGPU_FENCE_OWNER_VM; unsigned nptes, ncmds, ndw; struct amdgpu_job *job; - struct amdgpu_ib *ib; + struct amdgpu_vm_update_params vm_update_params; struct fence *f = NULL; int r; ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); + memset(&vm_update_params, 0, sizeof(vm_update_params)); + vm_update_params.src = src; + vm_update_params.pages_addr = pages_addr; /* sync to everything on unmapping */ if (!(flags & AMDGPU_PTE_VALID)) @@ -815,11 +828,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, /* padding, etc. */ ndw = 64; - if (src) { + if (vm_update_params.src) { /* only copy commands needed */ ndw += ncmds * 7; - } else if (pages_addr) { + } else if (vm_update_params.pages_addr) { /* header for write data commands */ ndw += ncmds * 4; @@ -838,7 +851,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, if (r) return r; - ib = &job->ibs[0]; + vm_update_params.ib = &job->ibs[0]; r = amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv, owner); @@ -849,11 +862,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, if (r) goto error_free; - amdgpu_vm_update_ptes(adev, src, pages_addr, vm, ib, start, + amdgpu_vm_update_ptes(adev, &vm_update_params, vm, start, last + 1, addr, flags); - amdgpu_ring_pad_ib(ring, ib); - WARN_ON(ib->length_dw > ndw); + amdgpu_ring_pad_ib(ring, vm_update_params.ib); + WARN_ON(vm_update_params.ib->length_dw > ndw); r = amdgpu_job_submit(job, ring, &vm->entity, AMDGPU_FENCE_OWNER_VM, &f); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c index bf731e9f643e..7f85c2c1d681 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c @@ -276,8 +276,8 @@ static int amdgpu_atombios_dp_get_dp_link_config(struct drm_connector *connector } } } else { - for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { - for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; if (max_pix_clock >= pix_clock) { *dp_lanes = lane_num; diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index 845c21b1b2ee..be3d6f79a864 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -103,7 +103,6 @@ static void cik_ih_disable_interrupts(struct amdgpu_device *adev) */ static int cik_ih_irq_init(struct amdgpu_device *adev) { - int ret = 0; int rb_bufsz; u32 interrupt_cntl, ih_cntl, ih_rb_cntl; u64 wptr_off; @@ -156,7 +155,7 @@ static int cik_ih_irq_init(struct amdgpu_device *adev) /* enable irqs */ cik_ih_enable_interrupts(adev); - return ret; + return 0; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index fa4449e126e6..933e425a8154 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c @@ -1579,7 +1579,6 @@ static int cz_dpm_update_sclk_limit(struct amdgpu_device *adev) static int cz_dpm_set_deep_sleep_sclk_threshold(struct amdgpu_device *adev) { - int ret = 0; struct cz_power_info *pi = cz_get_pi(adev); if (pi->caps_sclk_ds) { @@ -1588,20 +1587,19 @@ static int cz_dpm_set_deep_sleep_sclk_threshold(struct amdgpu_device *adev) CZ_MIN_DEEP_SLEEP_SCLK); } - return ret; + return 0; } /* ?? without dal support, is this still needed in setpowerstate list*/ static int cz_dpm_set_watermark_threshold(struct amdgpu_device *adev) { - int ret = 0; struct cz_power_info *pi = cz_get_pi(adev); cz_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetWatermarkFrequency, pi->sclk_dpm.soft_max_clk); - return ret; + return 0; } static int cz_dpm_enable_nbdpm(struct amdgpu_device *adev) @@ -1636,7 +1634,6 @@ static void cz_dpm_nbdpm_lm_pstate_enable(struct amdgpu_device *adev, static int cz_dpm_update_low_memory_pstate(struct amdgpu_device *adev) { - int ret = 0; struct cz_power_info *pi = cz_get_pi(adev); struct cz_ps *ps = &pi->requested_ps; @@ -1647,21 +1644,19 @@ static int cz_dpm_update_low_memory_pstate(struct amdgpu_device *adev) cz_dpm_nbdpm_lm_pstate_enable(adev, true); } - return ret; + return 0; } /* with dpm enabled */ static int cz_dpm_set_power_state(struct amdgpu_device *adev) { - int ret = 0; - cz_dpm_update_sclk_limit(adev); cz_dpm_set_deep_sleep_sclk_threshold(adev); cz_dpm_set_watermark_threshold(adev); cz_dpm_enable_nbdpm(adev); cz_dpm_update_low_memory_pstate(adev); - return ret; + return 0; } static void cz_dpm_post_set_power_state(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c index 863cb16f6126..3d23a70b6432 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c @@ -103,7 +103,6 @@ static void cz_ih_disable_interrupts(struct amdgpu_device *adev) */ static int cz_ih_irq_init(struct amdgpu_device *adev) { - int ret = 0; int rb_bufsz; u32 interrupt_cntl, ih_cntl, ih_rb_cntl; u64 wptr_off; @@ -157,7 +156,7 @@ static int cz_ih_irq_init(struct amdgpu_device *adev) /* enable interrupts */ cz_ih_enable_interrupts(adev); - return ret; + return 0; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index be1cf388c2ec..8227344d2ff6 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -2594,7 +2594,7 @@ static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc, return -EINVAL; } - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, amdgpu_crtc->crtc_id); return -ENOENT; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 1e0988572a2f..af26ec0bc59d 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -137,7 +137,7 @@ static const u32 polaris11_golden_settings_a11[] = mmDCI_CLK_CNTL, 0x00000080, 0x00000000, mmFBC_DEBUG_COMP, 0x000000f0, 0x00000070, mmFBC_DEBUG1, 0xffffffff, 0x00000008, - mmFBC_MISC, 0x9f313fff, 0x14300008, + mmFBC_MISC, 0x9f313fff, 0x14302008, mmHDMI_CONTROL, 0x313f031f, 0x00000011, }; @@ -145,7 +145,7 @@ static const u32 polaris10_golden_settings_a11[] = { mmDCI_CLK_CNTL, 0x00000080, 0x00000000, mmFBC_DEBUG_COMP, 0x000000f0, 0x00000070, - mmFBC_MISC, 0x9f313fff, 0x14300008, + mmFBC_MISC, 0x9f313fff, 0x14302008, mmHDMI_CONTROL, 0x313f031f, 0x00000011, }; @@ -2605,7 +2605,7 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc, return -EINVAL; } - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, amdgpu_crtc->crtc_id); return -ENOENT; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index c087f930d67e..3fb65e41a6ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -2501,7 +2501,7 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc, return -EINVAL; } - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, amdgpu_crtc->crtc_id); return -ENOENT; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 92647fbf5b8b..f19bab68fd83 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -267,10 +267,13 @@ static const u32 tonga_mgcg_cgcg_init[] = static const u32 golden_settings_polaris11_a11[] = { + mmCB_HW_CONTROL, 0xfffdf3cf, 0x00006208, mmCB_HW_CONTROL_3, 0x000001ff, 0x00000040, mmDB_DEBUG2, 0xf00fffff, 0x00000400, mmPA_SC_ENHANCE, 0xffffffff, 0x20000001, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000, + mmPA_SC_RASTER_CONFIG, 0x3f3fffff, 0x16000012, + mmPA_SC_RASTER_CONFIG_1, 0x0000003f, 0x00000000, mmRLC_CGCG_CGLS_CTRL, 0x00000003, 0x0001003c, mmRLC_CGCG_CGLS_CTRL_3D, 0xffffffff, 0x0001003c, mmSQ_CONFIG, 0x07f80000, 0x07180000, @@ -284,8 +287,6 @@ static const u32 golden_settings_polaris11_a11[] = static const u32 polaris11_golden_common_all[] = { mmGRBM_GFX_INDEX, 0xffffffff, 0xe0000000, - mmPA_SC_RASTER_CONFIG, 0xffffffff, 0x16000012, - mmPA_SC_RASTER_CONFIG_1, 0xffffffff, 0x00000000, mmGB_ADDR_CONFIG, 0xffffffff, 0x22011002, mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800, mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800, @@ -296,6 +297,7 @@ static const u32 polaris11_golden_common_all[] = static const u32 golden_settings_polaris10_a11[] = { mmATC_MISC_CG, 0x000c0fc0, 0x000c0200, + mmCB_HW_CONTROL, 0xfffdf3cf, 0x00006208, mmCB_HW_CONTROL_3, 0x000001ff, 0x00000040, mmDB_DEBUG2, 0xf00fffff, 0x00000400, mmPA_SC_ENHANCE, 0xffffffff, 0x20000001, @@ -5725,6 +5727,7 @@ static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, amdgpu_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN | EOP_TC_ACTION_EN | + EOP_TC_WB_ACTION_EN | EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5))); amdgpu_ring_write(ring, addr & 0xfffffffc); diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c index 39bfc52d0b42..3b8906ce3511 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c @@ -103,7 +103,6 @@ static void iceland_ih_disable_interrupts(struct amdgpu_device *adev) */ static int iceland_ih_irq_init(struct amdgpu_device *adev) { - int ret = 0; int rb_bufsz; u32 interrupt_cntl, ih_cntl, ih_rb_cntl; u64 wptr_off; @@ -157,7 +156,7 @@ static int iceland_ih_irq_init(struct amdgpu_device *adev) /* enable interrupts */ iceland_ih_enable_interrupts(adev); - return ret; + return 0; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index b45f54714574..a789a863d677 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -2252,7 +2252,7 @@ static void kv_apply_state_adjust_rules(struct amdgpu_device *adev, if (pi->caps_stable_p_state) { stable_p_state_sclk = (max_limits->sclk * 75) / 100; - for (i = table->count - 1; i >= 0; i++) { + for (i = table->count - 1; i >= 0; i--) { if (stable_p_state_sclk >= table->entries[i].clk) { stable_p_state_sclk = table->entries[i].clk; break; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 063f08a9957a..31d99b0010f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -109,10 +109,12 @@ static const u32 fiji_mgcg_cgcg_init[] = static const u32 golden_settings_polaris11_a11[] = { mmSDMA0_CHICKEN_BITS, 0xfc910007, 0x00810007, + mmSDMA0_CLK_CTRL, 0xff000fff, 0x00000000, mmSDMA0_GFX_IB_CNTL, 0x800f0111, 0x00000100, mmSDMA0_RLC0_IB_CNTL, 0x800f0111, 0x00000100, mmSDMA0_RLC1_IB_CNTL, 0x800f0111, 0x00000100, mmSDMA1_CHICKEN_BITS, 0xfc910007, 0x00810007, + mmSDMA1_CLK_CTRL, 0xff000fff, 0x00000000, mmSDMA1_GFX_IB_CNTL, 0x800f0111, 0x00000100, mmSDMA1_RLC0_IB_CNTL, 0x800f0111, 0x00000100, mmSDMA1_RLC1_IB_CNTL, 0x800f0111, 0x00000100, diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index f036af937fbc..c92055805a45 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -99,7 +99,6 @@ static void tonga_ih_disable_interrupts(struct amdgpu_device *adev) */ static int tonga_ih_irq_init(struct amdgpu_device *adev) { - int ret = 0; int rb_bufsz; u32 interrupt_cntl, ih_rb_cntl, ih_doorbell_rtpr; u64 wptr_off; @@ -165,7 +164,7 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev) /* enable interrupts */ tonga_ih_enable_interrupts(adev); - return ret; + return 0; } /** diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index c94f9faa220a..24a16e49b571 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c @@ -3573,46 +3573,11 @@ static int fiji_force_dpm_highest(struct pp_hwmgr *hwmgr) return 0; } -static void fiji_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr) -{ - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)hwmgr->pptable; - struct phm_clock_voltage_dependency_table *table = - table_info->vddc_dep_on_dal_pwrl; - struct phm_ppt_v1_clock_voltage_dependency_table *vddc_table; - enum PP_DAL_POWERLEVEL dal_power_level = hwmgr->dal_power_level; - uint32_t req_vddc = 0, req_volt, i; - - if (!table && !(dal_power_level >= PP_DAL_POWERLEVEL_ULTRALOW && - dal_power_level <= PP_DAL_POWERLEVEL_PERFORMANCE)) - return; - - for (i= 0; i < table->count; i++) { - if (dal_power_level == table->entries[i].clk) { - req_vddc = table->entries[i].v; - break; - } - } - - vddc_table = table_info->vdd_dep_on_sclk; - for (i= 0; i < vddc_table->count; i++) { - if (req_vddc <= vddc_table->entries[i].vddc) { - req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE) - << VDDC_SHIFT; - smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, - PPSMC_MSG_VddC_Request, req_volt); - return; - } - } - printk(KERN_ERR "DAL requested level can not" - " found a available voltage in VDDC DPM Table \n"); -} - static int fiji_upload_dpmlevel_enable_mask(struct pp_hwmgr *hwmgr) { struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); - fiji_apply_dal_min_voltage_request(hwmgr); + phm_apply_dal_min_voltage_request(hwmgr); if (!data->sclk_dpm_key_disabled) { if (data->dpm_level_enable_mask.sclk_dpm_enable_mask) @@ -4349,7 +4314,7 @@ static int fiji_populate_and_upload_sclk_mclk_dpm_levels( if (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK)) { - result = fiji_populate_all_memory_levels(hwmgr); + result = fiji_populate_all_graphic_levels(hwmgr); PP_ASSERT_WITH_CODE((0 == result), "Failed to populate SCLK during PopulateNewDPMClocksStates Function!", return result); @@ -5109,11 +5074,11 @@ static int fiji_get_pp_table(struct pp_hwmgr *hwmgr, char **table) struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); if (!data->soft_pp_table) { - data->soft_pp_table = kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); + data->soft_pp_table = kmemdup(hwmgr->soft_pp_table, + hwmgr->soft_pp_table_size, + GFP_KERNEL); if (!data->soft_pp_table) return -ENOMEM; - memcpy(data->soft_pp_table, hwmgr->soft_pp_table, - hwmgr->soft_pp_table_size); } *table = (char *)&data->soft_pp_table; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 7d69ed635bc2..1c48917da3cf 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -30,6 +30,9 @@ #include "pppcielanes.h" #include "pp_debug.h" #include "ppatomctrl.h" +#include "ppsmc.h" + +#define VOLTAGE_SCALE 4 extern int cz_hwmgr_init(struct pp_hwmgr *hwmgr); extern int tonga_hwmgr_init(struct pp_hwmgr *hwmgr); @@ -566,3 +569,38 @@ uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask) return level; } + +void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr) +{ + struct phm_ppt_v1_information *table_info = + (struct phm_ppt_v1_information *)hwmgr->pptable; + struct phm_clock_voltage_dependency_table *table = + table_info->vddc_dep_on_dal_pwrl; + struct phm_ppt_v1_clock_voltage_dependency_table *vddc_table; + enum PP_DAL_POWERLEVEL dal_power_level = hwmgr->dal_power_level; + uint32_t req_vddc = 0, req_volt, i; + + if (!table || table->count <= 0 + || dal_power_level < PP_DAL_POWERLEVEL_ULTRALOW + || dal_power_level > PP_DAL_POWERLEVEL_PERFORMANCE) + return; + + for (i = 0; i < table->count; i++) { + if (dal_power_level == table->entries[i].clk) { + req_vddc = table->entries[i].v; + break; + } + } + + vddc_table = table_info->vdd_dep_on_sclk; + for (i = 0; i < vddc_table->count; i++) { + if (req_vddc <= vddc_table->entries[i].vddc) { + req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE); + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_VddC_Request, req_volt); + return; + } + } + printk(KERN_ERR "DAL requested level can not" + " found a available voltage in VDDC DPM Table \n"); +} diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c index 93768fa1dcdc..aa6be033f21b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c @@ -189,41 +189,6 @@ int phm_get_current_pcie_lane_number(struct pp_hwmgr *hwmgr) return decode_pcie_lane_width(link_width); } -void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr) -{ - struct phm_ppt_v1_information *table_info = - (struct phm_ppt_v1_information *)hwmgr->pptable; - struct phm_clock_voltage_dependency_table *table = - table_info->vddc_dep_on_dal_pwrl; - struct phm_ppt_v1_clock_voltage_dependency_table *vddc_table; - enum PP_DAL_POWERLEVEL dal_power_level = hwmgr->dal_power_level; - uint32_t req_vddc = 0, req_volt, i; - - if (!table && !(dal_power_level >= PP_DAL_POWERLEVEL_ULTRALOW && - dal_power_level <= PP_DAL_POWERLEVEL_PERFORMANCE)) - return; - - for (i = 0; i < table->count; i++) { - if (dal_power_level == table->entries[i].clk) { - req_vddc = table->entries[i].v; - break; - } - } - - vddc_table = table_info->vdd_dep_on_sclk; - for (i = 0; i < vddc_table->count; i++) { - if (req_vddc <= vddc_table->entries[i].vddc) { - req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE) - << VDDC_SHIFT; - smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, - PPSMC_MSG_VddC_Request, req_volt); - return; - } - } - printk(KERN_ERR "DAL requested level can not" - " found a available voltage in VDDC DPM Table \n"); -} - /** * Enable voltage control * @@ -2091,7 +2056,7 @@ static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr) "Failed to populate Clock Stretcher Data Table!", return result); } - + table->CurrSclkPllRange = 0xff; table->GraphicsVoltageChangeEnable = 1; table->GraphicsThermThrottleEnable = 1; table->GraphicsInterval = 1; @@ -2184,6 +2149,7 @@ static int polaris10_init_smc_table(struct pp_hwmgr *hwmgr) CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask1); CONVERT_FROM_HOST_TO_SMC_UL(table->SmioMask2); CONVERT_FROM_HOST_TO_SMC_UL(table->SclkStepSize); + CONVERT_FROM_HOST_TO_SMC_UL(table->CurrSclkPllRange); CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitHigh); CONVERT_FROM_HOST_TO_SMC_US(table->TemperatureLimitLow); CONVERT_FROM_HOST_TO_SMC_US(table->VoltageResponseTime); @@ -4760,11 +4726,11 @@ static int polaris10_get_pp_table(struct pp_hwmgr *hwmgr, char **table) struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); if (!data->soft_pp_table) { - data->soft_pp_table = kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); + data->soft_pp_table = kmemdup(hwmgr->soft_pp_table, + hwmgr->soft_pp_table_size, + GFP_KERNEL); if (!data->soft_pp_table) return -ENOMEM; - memcpy(data->soft_pp_table, hwmgr->soft_pp_table, - hwmgr->soft_pp_table_size); } *table = (char *)&data->soft_pp_table; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 1faad92b50d3..16fed487973b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c @@ -5331,7 +5331,7 @@ static int tonga_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) { PP_ASSERT_WITH_CODE( - true == tonga_is_dpm_running(hwmgr), + 0 == tonga_is_dpm_running(hwmgr), "Trying to freeze SCLK DPM when DPM is disabled", ); PP_ASSERT_WITH_CODE( @@ -5344,7 +5344,7 @@ static int tonga_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) if ((0 == data->mclk_dpm_key_disabled) && (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) { - PP_ASSERT_WITH_CODE(true == tonga_is_dpm_running(hwmgr), + PP_ASSERT_WITH_CODE(0 == tonga_is_dpm_running(hwmgr), "Trying to freeze MCLK DPM when DPM is disabled", ); PP_ASSERT_WITH_CODE( @@ -5445,7 +5445,7 @@ static int tonga_populate_and_upload_sclk_mclk_dpm_levels(struct pp_hwmgr *hwmgr } if (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK)) { - result = tonga_populate_all_memory_levels(hwmgr); + result = tonga_populate_all_graphic_levels(hwmgr); PP_ASSERT_WITH_CODE((0 == result), "Failed to populate SCLK during PopulateNewDPMClocksStates Function!", return result); @@ -5647,7 +5647,7 @@ static int tonga_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) (data->need_update_smu7_dpm_table & (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) { - PP_ASSERT_WITH_CODE(true == tonga_is_dpm_running(hwmgr), + PP_ASSERT_WITH_CODE(0 == tonga_is_dpm_running(hwmgr), "Trying to Unfreeze SCLK DPM when DPM is disabled", ); PP_ASSERT_WITH_CODE( @@ -5661,7 +5661,7 @@ static int tonga_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) { PP_ASSERT_WITH_CODE( - true == tonga_is_dpm_running(hwmgr), + 0 == tonga_is_dpm_running(hwmgr), "Trying to Unfreeze MCLK DPM when DPM is disabled", ); PP_ASSERT_WITH_CODE( @@ -6056,11 +6056,11 @@ static int tonga_get_pp_table(struct pp_hwmgr *hwmgr, char **table) struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); if (!data->soft_pp_table) { - data->soft_pp_table = kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL); + data->soft_pp_table = kmemdup(hwmgr->soft_pp_table, + hwmgr->soft_pp_table_size, + GFP_KERNEL); if (!data->soft_pp_table) return -ENOMEM; - memcpy(data->soft_pp_table, hwmgr->soft_pp_table, - hwmgr->soft_pp_table_size); } *table = (char *)&data->soft_pp_table; diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index fd4ce7aaeee9..28f571449495 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -673,7 +673,7 @@ extern int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr, phm_ppt_v1_volta extern int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr); extern int phm_hwmgr_backend_fini(struct pp_hwmgr *hwmgr); extern uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask); - +extern void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr); #define PHM_ENTIRE_REGISTER_MASK 0xFFFFFFFFU diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c index da18f44fd1c8..87c023e518ab 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/cz_smumgr.c @@ -639,7 +639,7 @@ static int cz_smu_populate_firmware_entries(struct pp_smumgr *smumgr) cz_smu->driver_buffer_length = 0; - for (i = 0; i < sizeof(firmware_list)/sizeof(*firmware_list); i++) { + for (i = 0; i < ARRAY_SIZE(firmware_list); i++) { firmware_type = cz_translate_firmware_enum_to_arg(smumgr, firmware_list[i]); diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 734899c4e4bb..4f909378d581 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -316,7 +316,7 @@ static struct drm_driver hdlcd_driver = { .get_vblank_counter = drm_vblank_no_hw_counter, .enable_vblank = hdlcd_enable_vblank, .disable_vblank = hdlcd_disable_vblank, - .gem_free_object = drm_gem_cma_free_object, + .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = drm_gem_cma_dumb_create, .dumb_map_offset = drm_gem_cma_dumb_map_offset, @@ -379,7 +379,6 @@ static int hdlcd_drm_bind(struct device *dev) DRM_ERROR("failed to initialise vblank\n"); goto err_vblank; } - drm->vblank_disable_allowed = true; drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 0293eb74d777..3130aa8bcdd0 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -897,7 +897,6 @@ static void cursor_update(void *data) static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file, uint32_t handle, uint32_t w, uint32_t h) { - struct drm_device *dev = crtc->dev; struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct armada_gem_object *obj = NULL; int ret; @@ -911,7 +910,7 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc, if (w > 64 || h > 64 || (w > 32 && h > 32)) return -ENOMEM; - obj = armada_gem_object_lookup(dev, file, handle); + obj = armada_gem_object_lookup(file, handle); if (!obj) return -ENOENT; diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 82043c204b76..439824a61aa5 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -113,7 +113,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) goto err_comp; dev->irq_enabled = true; - dev->vblank_disable_allowed = 1; ret = armada_fbdev_init(dev); if (ret) diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c index 5fa4bf20b232..f03c212b754d 100644 --- a/drivers/gpu/drm/armada/armada_fb.c +++ b/drivers/gpu/drm/armada/armada_fb.c @@ -120,7 +120,7 @@ static struct drm_framebuffer *armada_fb_create(struct drm_device *dev, goto err; } - obj = armada_gem_object_lookup(dev, dfile, mode->handles[0]); + obj = armada_gem_object_lookup(dfile, mode->handles[0]); if (!obj) { ret = -ENOENT; goto err; diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index aca7f9cc6109..88e7fc797721 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -278,7 +278,7 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, struct armada_gem_object *obj; int ret = 0; - obj = armada_gem_object_lookup(dev, file, handle); + obj = armada_gem_object_lookup(file, handle); if (!obj) { DRM_ERROR("failed to lookup gem object\n"); return -EINVAL; @@ -348,7 +348,7 @@ int armada_gem_mmap_ioctl(struct drm_device *dev, void *data, struct armada_gem_object *dobj; unsigned long addr; - dobj = armada_gem_object_lookup(dev, file, args->handle); + dobj = armada_gem_object_lookup(file, args->handle); if (dobj == NULL) return -ENOENT; @@ -391,7 +391,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - dobj = armada_gem_object_lookup(dev, file, args->handle); + dobj = armada_gem_object_lookup(file, args->handle); if (dobj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/armada/armada_gem.h b/drivers/gpu/drm/armada/armada_gem.h index b000ea3a829a..b88d2b9853c7 100644 --- a/drivers/gpu/drm/armada/armada_gem.h +++ b/drivers/gpu/drm/armada/armada_gem.h @@ -45,9 +45,9 @@ struct drm_gem_object *armada_gem_prime_import(struct drm_device *, int armada_gem_map_import(struct armada_gem_object *); static inline struct armada_gem_object *armada_gem_object_lookup( - struct drm_device *dev, struct drm_file *dfile, unsigned handle) + struct drm_file *dfile, unsigned handle) { - struct drm_gem_object *obj = drm_gem_object_lookup(dev, dfile, handle); + struct drm_gem_object *obj = drm_gem_object_lookup(dfile, handle); return obj ? drm_to_armada_gem(obj) : NULL; } diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index b1480acbb3c3..7bc3aa6dda8c 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -333,7 +333,7 @@ ast_user_framebuffer_create(struct drm_device *dev, struct ast_framebuffer *ast_fb; int ret; - obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); if (obj == NULL) return ERR_PTR(-ENOENT); @@ -574,7 +574,7 @@ ast_dumb_mmap_offset(struct drm_file *file, struct drm_gem_object *obj; struct ast_bo *bo; - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index a965e7e8ad6e..c337922606e3 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1141,7 +1141,7 @@ static int ast_cursor_set(struct drm_crtc *crtc, if (width > AST_MAX_HWC_WIDTH || height > AST_MAX_HWC_HEIGHT) return -EINVAL; - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("Cannot find cursor object %x for crtc\n", handle); return -ENOENT; diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index 8df0aaf98725..cf23a755f777 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -430,7 +430,7 @@ static void atmel_hlcdc_crtc_destroy_state(struct drm_crtc *crtc, struct atmel_hlcdc_crtc_state *state; state = drm_crtc_state_to_atmel_hlcdc_crtc_state(s); - __drm_atomic_helper_crtc_destroy_state(crtc, s); + __drm_atomic_helper_crtc_destroy_state(s); kfree(state); } diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index 24a30f64ed2d..6cf912c45e48 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c @@ -458,7 +458,7 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, struct drm_gem_object *obj; struct bochs_bo *bo; - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) return -ENOENT; @@ -520,7 +520,7 @@ bochs_user_framebuffer_create(struct drm_device *dev, if (mode_cmd->pixel_format != DRM_FORMAT_XRGB8888) return ERR_PTR(-ENOENT); - obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); if (obj == NULL) return ERR_PTR(-ENOENT); diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c index 0907715e90fd..32d32c5b7b17 100644 --- a/drivers/gpu/drm/cirrus/cirrus_main.c +++ b/drivers/gpu/drm/cirrus/cirrus_main.c @@ -61,7 +61,7 @@ cirrus_user_framebuffer_create(struct drm_device *dev, bpp, mode_cmd->pitches[0])) return ERR_PTR(-EINVAL); - obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); if (obj == NULL) return ERR_PTR(-ENOENT); @@ -295,7 +295,7 @@ cirrus_dumb_mmap_offset(struct drm_file *file, struct drm_gem_object *obj; struct cirrus_bo *bo; - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index d3d8d7bfcc57..0b1a411cb89e 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c @@ -331,9 +331,6 @@ static void cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); int i; - if (size != CIRRUS_LUT_SIZE) - return; - for (i = 0; i < CIRRUS_LUT_SIZE; i++) { cirrus_crtc->lut_r[i] = red[i]; cirrus_crtc->lut_g[i] = green[i]; diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 86e89db02ed7..3ff1ed7b33db 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1160,14 +1160,18 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, { struct drm_crtc_state *crtc_state; - if (crtc) - drm_connector_reference(conn_state->connector); - if (conn_state->crtc && conn_state->crtc != crtc) { + if (conn_state->crtc == crtc) + return 0; + + if (conn_state->crtc) { crtc_state = drm_atomic_get_existing_crtc_state(conn_state->state, conn_state->crtc); crtc_state->connector_mask &= ~(1 << drm_connector_index(conn_state->connector)); + + drm_connector_unreference(conn_state->connector); + conn_state->crtc = NULL; } if (crtc) { @@ -1177,18 +1181,16 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, crtc_state->connector_mask |= 1 << drm_connector_index(conn_state->connector); - } - if (conn_state->crtc) - drm_connector_unreference(conn_state->connector); - conn_state->crtc = crtc; + drm_connector_reference(conn_state->connector); + conn_state->crtc = crtc; - if (crtc) DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d:%s]\n", conn_state, crtc->base.id, crtc->name); - else + } else { DRM_DEBUG_ATOMIC("Link connector state %p to [NOCRTC]\n", conn_state); + } return 0; } diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 43a0b3dfa846..939df900dcaa 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -414,6 +414,9 @@ mode_fixup(struct drm_atomic_state *state) for_each_crtc_in_state(state, crtc, crtc_state, i) { const struct drm_crtc_helper_funcs *funcs; + if (!crtc_state->enable) + continue; + if (!crtc_state->mode_changed && !crtc_state->connectors_changed) continue; @@ -2530,7 +2533,7 @@ EXPORT_SYMBOL(drm_atomic_helper_best_encoder); void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) { if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc, crtc->state); + __drm_atomic_helper_crtc_destroy_state(crtc->state); kfree(crtc->state); crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); @@ -2595,15 +2598,13 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); /** * __drm_atomic_helper_crtc_destroy_state - release CRTC state - * @crtc: CRTC object * @state: CRTC state object to release * * Releases all resources stored in the CRTC state without actually freeing * the memory of the CRTC state. This is useful for drivers that subclass the * CRTC state. */ -void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, - struct drm_crtc_state *state) +void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) { drm_property_unreference_blob(state->mode_blob); drm_property_unreference_blob(state->degamma_lut); @@ -2623,7 +2624,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state) { - __drm_atomic_helper_crtc_destroy_state(crtc, state); + __drm_atomic_helper_crtc_destroy_state(state); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); @@ -2638,7 +2639,7 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); void drm_atomic_helper_plane_reset(struct drm_plane *plane) { if (plane->state) - __drm_atomic_helper_plane_destroy_state(plane, plane->state); + __drm_atomic_helper_plane_destroy_state(plane->state); kfree(plane->state); plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); @@ -2693,15 +2694,13 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); /** * __drm_atomic_helper_plane_destroy_state - release plane state - * @plane: plane object * @state: plane state object to release * * Releases all resources stored in the plane state without actually freeing * the memory of the plane state. This is useful for drivers that subclass the * plane state. */ -void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, - struct drm_plane_state *state) +void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) { if (state->fb) drm_framebuffer_unreference(state->fb); @@ -2719,7 +2718,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - __drm_atomic_helper_plane_destroy_state(plane, state); + __drm_atomic_helper_plane_destroy_state(state); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); @@ -2760,8 +2759,7 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector) kzalloc(sizeof(*conn_state), GFP_KERNEL); if (connector->state) - __drm_atomic_helper_connector_destroy_state(connector, - connector->state); + __drm_atomic_helper_connector_destroy_state(connector->state); kfree(connector->state); __drm_atomic_helper_connector_reset(connector, conn_state); @@ -2894,7 +2892,6 @@ EXPORT_SYMBOL(drm_atomic_helper_duplicate_state); /** * __drm_atomic_helper_connector_destroy_state - release connector state - * @connector: connector object * @state: connector state object to release * * Releases all resources stored in the connector state without actually @@ -2902,8 +2899,7 @@ EXPORT_SYMBOL(drm_atomic_helper_duplicate_state); * subclass the connector state. */ void -__drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, - struct drm_connector_state *state) +__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state) { /* * This is currently a placeholder so that drivers that subclass the @@ -2926,7 +2922,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state) { - __drm_atomic_helper_connector_destroy_state(connector, state); + __drm_atomic_helper_connector_destroy_state(state); kfree(state); } EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index 6743ff7dccfa..059f7c39c582 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -72,7 +72,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) { #if defined(CONFIG_X86) - if (cpu_has_clflush) { + if (static_cpu_has(X86_FEATURE_CLFLUSH)) { drm_cache_flush_clflush(pages, num_pages); return; } @@ -105,7 +105,7 @@ void drm_clflush_sg(struct sg_table *st) { #if defined(CONFIG_X86) - if (cpu_has_clflush) { + if (static_cpu_has(X86_FEATURE_CLFLUSH)) { struct sg_page_iter sg_iter; mb(); @@ -129,7 +129,7 @@ void drm_clflush_virt_range(void *addr, unsigned long length) { #if defined(CONFIG_X86) - if (cpu_has_clflush) { + if (static_cpu_has(X86_FEATURE_CLFLUSH)) { const int size = boot_cpu_data.x86_clflush_size; void *end = addr + length; addr = (void *)(((unsigned long)addr) & -size); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 70f9c682d144..37427b2bb9fc 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1030,8 +1030,6 @@ int drm_connector_register(struct drm_connector *connector) { int ret; - drm_mode_object_register(connector->dev, &connector->base); - ret = drm_sysfs_connector_add(connector); if (ret) return ret; @@ -1042,6 +1040,8 @@ int drm_connector_register(struct drm_connector *connector) return ret; } + drm_mode_object_register(connector->dev, &connector->base); + return 0; } EXPORT_SYMBOL(drm_connector_register); @@ -5139,6 +5139,9 @@ EXPORT_SYMBOL(drm_mode_connector_attach_encoder); int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size) { + uint16_t *r_base, *g_base, *b_base; + int i; + crtc->gamma_size = gamma_size; crtc->gamma_store = kcalloc(gamma_size, sizeof(uint16_t) * 3, @@ -5148,6 +5151,16 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, return -ENOMEM; } + r_base = crtc->gamma_store; + g_base = r_base + gamma_size; + b_base = g_base + gamma_size; + for (i = 0; i < gamma_size; i++) { + r_base[i] = i << 8; + g_base[i] = i << 8; + b_base[i] = i << 8; + } + + return 0; } EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 96b181a881e2..7df26d4b7ad8 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3901,6 +3901,133 @@ static void drm_add_display_info(struct edid *edid, info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; } +static int validate_displayid(u8 *displayid, int length, int idx) +{ + int i; + u8 csum = 0; + struct displayid_hdr *base; + + base = (struct displayid_hdr *)&displayid[idx]; + + DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", + base->rev, base->bytes, base->prod_id, base->ext_count); + + if (base->bytes + 5 > length - idx) + return -EINVAL; + for (i = idx; i <= base->bytes + 5; i++) { + csum += displayid[i]; + } + if (csum) { + DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum); + return -EINVAL; + } + return 0; +} + +static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev, + struct displayid_detailed_timings_1 *timings) +{ + struct drm_display_mode *mode; + unsigned pixel_clock = (timings->pixel_clock[0] | + (timings->pixel_clock[1] << 8) | + (timings->pixel_clock[2] << 16)); + unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1; + unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1; + unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1; + unsigned hsync_width = (timings->hsw[0] | timings->hsw[1] << 8) + 1; + unsigned vactive = (timings->vactive[0] | timings->vactive[1] << 8) + 1; + unsigned vblank = (timings->vblank[0] | timings->vblank[1] << 8) + 1; + unsigned vsync = (timings->vsync[0] | (timings->vsync[1] & 0x7f) << 8) + 1; + unsigned vsync_width = (timings->vsw[0] | timings->vsw[1] << 8) + 1; + bool hsync_positive = (timings->hsync[1] >> 7) & 0x1; + bool vsync_positive = (timings->vsync[1] >> 7) & 0x1; + mode = drm_mode_create(dev); + if (!mode) + return NULL; + + mode->clock = pixel_clock * 10; + mode->hdisplay = hactive; + mode->hsync_start = mode->hdisplay + hsync; + mode->hsync_end = mode->hsync_start + hsync_width; + mode->htotal = mode->hdisplay + hblank; + + mode->vdisplay = vactive; + mode->vsync_start = mode->vdisplay + vsync; + mode->vsync_end = mode->vsync_start + vsync_width; + mode->vtotal = mode->vdisplay + vblank; + + mode->flags = 0; + mode->flags |= hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; + mode->flags |= vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; + mode->type = DRM_MODE_TYPE_DRIVER; + + if (timings->flags & 0x80) + mode->type |= DRM_MODE_TYPE_PREFERRED; + mode->vrefresh = drm_mode_vrefresh(mode); + drm_mode_set_name(mode); + + return mode; +} + +static int add_displayid_detailed_1_modes(struct drm_connector *connector, + struct displayid_block *block) +{ + struct displayid_detailed_timing_block *det = (struct displayid_detailed_timing_block *)block; + int i; + int num_timings; + struct drm_display_mode *newmode; + int num_modes = 0; + /* blocks must be multiple of 20 bytes length */ + if (block->num_bytes % 20) + return 0; + + num_timings = block->num_bytes / 20; + for (i = 0; i < num_timings; i++) { + struct displayid_detailed_timings_1 *timings = &det->timings[i]; + + newmode = drm_mode_displayid_detailed(connector->dev, timings); + if (!newmode) + continue; + + drm_mode_probed_add(connector, newmode); + num_modes++; + } + return num_modes; +} + +static int add_displayid_detailed_modes(struct drm_connector *connector, + struct edid *edid) +{ + u8 *displayid; + int ret; + int idx = 1; + int length = EDID_LENGTH; + struct displayid_block *block; + int num_modes = 0; + + displayid = drm_find_displayid_extension(edid); + if (!displayid) + return 0; + + ret = validate_displayid(displayid, length, idx); + if (ret) + return 0; + + idx += sizeof(struct displayid_hdr); + while (block = (struct displayid_block *)&displayid[idx], + idx + sizeof(struct displayid_block) <= length && + idx + sizeof(struct displayid_block) + block->num_bytes <= length && + block->num_bytes > 0) { + idx += block->num_bytes + sizeof(struct displayid_block); + switch (block->tag) { + case DATA_BLOCK_TYPE_1_DETAILED_TIMING: + num_modes += add_displayid_detailed_1_modes(connector, block); + break; + } + } + return num_modes; +} + /** * drm_add_edid_modes - add modes from EDID data, if available * @connector: connector we're probing @@ -3946,6 +4073,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) num_modes += add_established_modes(connector, edid); num_modes += add_cea_modes(connector, edid); num_modes += add_alternate_cea_modes(connector, edid); + num_modes += add_displayid_detailed_modes(connector, edid); if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) num_modes += add_inferred_modes(connector, edid); @@ -4152,96 +4280,98 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, } EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode); +static int drm_parse_tiled_block(struct drm_connector *connector, + struct displayid_block *block) +{ + struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block; + u16 w, h; + u8 tile_v_loc, tile_h_loc; + u8 num_v_tile, num_h_tile; + struct drm_tile_group *tg; + + w = tile->tile_size[0] | tile->tile_size[1] << 8; + h = tile->tile_size[2] | tile->tile_size[3] << 8; + + num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30); + num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30); + tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4); + tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4); + + connector->has_tile = true; + if (tile->tile_cap & 0x80) + connector->tile_is_single_monitor = true; + + connector->num_h_tile = num_h_tile + 1; + connector->num_v_tile = num_v_tile + 1; + connector->tile_h_loc = tile_h_loc; + connector->tile_v_loc = tile_v_loc; + connector->tile_h_size = w + 1; + connector->tile_v_size = h + 1; + + DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap); + DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1); + DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n", + num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc); + DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]); + + tg = drm_mode_get_tile_group(connector->dev, tile->topology_id); + if (!tg) { + tg = drm_mode_create_tile_group(connector->dev, tile->topology_id); + } + if (!tg) + return -ENOMEM; + + if (connector->tile_group != tg) { + /* if we haven't got a pointer, + take the reference, drop ref to old tile group */ + if (connector->tile_group) { + drm_mode_put_tile_group(connector->dev, connector->tile_group); + } + connector->tile_group = tg; + } else + /* if same tile group, then release the ref we just took. */ + drm_mode_put_tile_group(connector->dev, tg); + return 0; +} + static int drm_parse_display_id(struct drm_connector *connector, u8 *displayid, int length, bool is_edid_extension) { /* if this is an EDID extension the first byte will be 0x70 */ int idx = 0; - struct displayid_hdr *base; struct displayid_block *block; - u8 csum = 0; - int i; + int ret; if (is_edid_extension) idx = 1; - base = (struct displayid_hdr *)&displayid[idx]; - - DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", - base->rev, base->bytes, base->prod_id, base->ext_count); - - if (base->bytes + 5 > length - idx) - return -EINVAL; - - for (i = idx; i <= base->bytes + 5; i++) { - csum += displayid[i]; - } - if (csum) { - DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum); - return -EINVAL; - } + ret = validate_displayid(displayid, length, idx); + if (ret) + return ret; - block = (struct displayid_block *)&displayid[idx + 4]; - DRM_DEBUG_KMS("block id %d, rev %d, len %d\n", - block->tag, block->rev, block->num_bytes); - - switch (block->tag) { - case DATA_BLOCK_TILED_DISPLAY: { - struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block; - - u16 w, h; - u8 tile_v_loc, tile_h_loc; - u8 num_v_tile, num_h_tile; - struct drm_tile_group *tg; - - w = tile->tile_size[0] | tile->tile_size[1] << 8; - h = tile->tile_size[2] | tile->tile_size[3] << 8; - - num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30); - num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30); - tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4); - tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4); - - connector->has_tile = true; - if (tile->tile_cap & 0x80) - connector->tile_is_single_monitor = true; - - connector->num_h_tile = num_h_tile + 1; - connector->num_v_tile = num_v_tile + 1; - connector->tile_h_loc = tile_h_loc; - connector->tile_v_loc = tile_v_loc; - connector->tile_h_size = w + 1; - connector->tile_v_size = h + 1; - - DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap); - DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1); - DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n", - num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc); - DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]); - - tg = drm_mode_get_tile_group(connector->dev, tile->topology_id); - if (!tg) { - tg = drm_mode_create_tile_group(connector->dev, tile->topology_id); + idx += sizeof(struct displayid_hdr); + while (block = (struct displayid_block *)&displayid[idx], + idx + sizeof(struct displayid_block) <= length && + idx + sizeof(struct displayid_block) + block->num_bytes <= length && + block->num_bytes > 0) { + idx += block->num_bytes + sizeof(struct displayid_block); + DRM_DEBUG_KMS("block id 0x%x, rev %d, len %d\n", + block->tag, block->rev, block->num_bytes); + + switch (block->tag) { + case DATA_BLOCK_TILED_DISPLAY: + ret = drm_parse_tiled_block(connector, block); + if (ret) + return ret; + break; + case DATA_BLOCK_TYPE_1_DETAILED_TIMING: + /* handled in mode gathering code. */ + break; + default: + DRM_DEBUG_KMS("found DisplayID tag 0x%x, unhandled\n", block->tag); + break; } - if (!tg) - return -ENOMEM; - - if (connector->tile_group != tg) { - /* if we haven't got a pointer, - take the reference, drop ref to old tile group */ - if (connector->tile_group) { - drm_mode_put_tile_group(connector->dev, connector->tile_group); - } - connector->tile_group = tg; - } else - /* if same tile group, then release the ref we just took. */ - drm_mode_put_tile_group(connector->dev, tg); - } - break; - default: - printk("unknown displayid tag %d\n", block->tag); - break; } return 0; } diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 9a401aed98e0..622f788bff46 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c @@ -271,7 +271,7 @@ int drm_load_edid_firmware(struct drm_connector *connector) * by commas, search through the list looking for one that * matches the connector. * - * If there's one or more that don't't specify a connector, keep + * If there's one or more that doesn't specify a connector, keep * the last one found one as a fallback. */ fwstr = kstrdup(edid_firmware, GFP_KERNEL); diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 3165ac0e93e5..172cafe11c71 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -133,7 +133,7 @@ static struct drm_framebuffer_funcs drm_fb_cma_funcs = { static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_cma_object **obj, - unsigned int num_planes, struct drm_framebuffer_funcs *funcs) + unsigned int num_planes, const struct drm_framebuffer_funcs *funcs) { struct drm_fb_cma *fb_cma; int ret; @@ -159,13 +159,17 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, } /** - * drm_fb_cma_create() - (struct drm_mode_config_funcs *)->fb_create callback function + * drm_fb_cma_create_with_funcs() - helper function for the + * &drm_mode_config_funcs ->fb_create + * callback function * - * If your hardware has special alignment or pitch requirements these should be - * checked before calling this function. + * This can be used to set &drm_framebuffer_funcs for drivers that need the + * dirty() callback. Use drm_fb_cma_create() if you don't need to change + * &drm_framebuffer_funcs. */ -struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, - struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) +struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev, + struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd, + const struct drm_framebuffer_funcs *funcs) { struct drm_fb_cma *fb_cma; struct drm_gem_cma_object *objs[4]; @@ -183,7 +187,7 @@ struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, unsigned int height = mode_cmd->height / (i ? vsub : 1); unsigned int min_size; - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[i]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); if (!obj) { dev_err(dev->dev, "Failed to lookup GEM object\n"); ret = -ENXIO; @@ -202,7 +206,7 @@ struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, objs[i] = to_drm_gem_cma_obj(obj); } - fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i, &drm_fb_cma_funcs); + fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i, funcs); if (IS_ERR(fb_cma)) { ret = PTR_ERR(fb_cma); goto err_gem_object_unreference; @@ -215,6 +219,21 @@ err_gem_object_unreference: drm_gem_object_unreference_unlocked(&objs[i]->base); return ERR_PTR(ret); } +EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs); + +/** + * drm_fb_cma_create() - &drm_mode_config_funcs ->fb_create callback function + * + * If your hardware has special alignment or pitch requirements these should be + * checked before calling this function. Use drm_fb_cma_create_with_funcs() if + * you need to set &drm_framebuffer_funcs ->dirty. + */ +struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, + struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) +{ + return drm_fb_cma_create_with_funcs(dev, file_priv, mode_cmd, + &drm_fb_cma_funcs); +} EXPORT_SYMBOL_GPL(drm_fb_cma_create); /** @@ -350,7 +369,7 @@ static void drm_fbdev_cma_defio_fini(struct fb_info *fbi) */ int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes, - struct drm_framebuffer_funcs *funcs) + const struct drm_framebuffer_funcs *funcs) { struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper); struct drm_mode_fb_cmd2 mode_cmd = { 0 }; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index e03f8ad90b3a..7590df5e2e72 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1042,7 +1042,6 @@ static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, { struct drm_fb_helper *fb_helper = info->par; struct drm_framebuffer *fb = fb_helper->fb; - int pindex; if (info->fix.visual == FB_VISUAL_TRUECOLOR) { u32 *palette; @@ -1074,38 +1073,10 @@ static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, !fb_helper->funcs->gamma_get)) return -EINVAL; - pindex = regno; + WARN_ON(fb->bits_per_pixel != 8); - if (fb->bits_per_pixel == 16) { - pindex = regno << 3; + fb_helper->funcs->gamma_set(crtc, red, green, blue, regno); - if (fb->depth == 16 && regno > 63) - return -EINVAL; - if (fb->depth == 15 && regno > 31) - return -EINVAL; - - if (fb->depth == 16) { - u16 r, g, b; - int i; - if (regno < 32) { - for (i = 0; i < 8; i++) - fb_helper->funcs->gamma_set(crtc, red, - green, blue, pindex + i); - } - - fb_helper->funcs->gamma_get(crtc, &r, - &g, &b, - pindex >> 1); - - for (i = 0; i < 4; i++) - fb_helper->funcs->gamma_set(crtc, r, - green, b, - (pindex >> 1) + i); - } - } - - if (fb->depth != 16) - fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex); return 0; } @@ -1968,7 +1939,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, int n, int width, int height) { int c, o; - struct drm_device *dev = fb_helper->dev; struct drm_connector *connector; const struct drm_connector_helper_funcs *connector_funcs; struct drm_encoder *encoder; @@ -1987,7 +1957,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, if (modes[n] == NULL) return best_score; - crtcs = kzalloc(dev->mode_config.num_connector * + crtcs = kzalloc(fb_helper->connector_count * sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); if (!crtcs) return best_score; @@ -2033,7 +2003,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, if (score > best_score) { best_score = score; memcpy(best_crtcs, crtcs, - dev->mode_config.num_connector * + fb_helper->connector_count * sizeof(struct drm_fb_helper_crtc *)); } } diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index f716308fb48c..32156060b9c9 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -588,7 +588,6 @@ EXPORT_SYMBOL(drm_gem_put_pages); /** * drm_gem_object_lookup - look up a GEM object from it's handle - * @dev: DRM device * @filp: DRM file private date * @handle: userspace handle * @@ -598,8 +597,7 @@ EXPORT_SYMBOL(drm_gem_put_pages); * otherwise. */ struct drm_gem_object * -drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, - u32 handle) +drm_gem_object_lookup(struct drm_file *filp, u32 handle) { struct drm_gem_object *obj; @@ -607,12 +605,8 @@ drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, /* Check if we currently have a reference on the object */ obj = idr_find(&filp->object_idr, handle); - if (obj == NULL) { - spin_unlock(&filp->table_lock); - return NULL; - } - - drm_gem_object_reference(obj); + if (obj) + drm_gem_object_reference(obj); spin_unlock(&filp->table_lock); @@ -665,7 +659,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_GEM)) return -ENODEV; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = drm_gem_object_lookup(file_priv, args->handle); if (obj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index 1f500a1b9969..e1ab008b3f08 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -291,7 +291,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, { struct drm_gem_object *gem_obj; - gem_obj = drm_gem_object_lookup(drm, file_priv, handle); + gem_obj = drm_gem_object_lookup(file_priv, handle); if (!gem_obj) { dev_err(drm->dev, "failed to lookup GEM object\n"); return -EINVAL; diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index d3124b67f4a5..5a773e437e2f 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -42,10 +42,6 @@ #include <linux/vgaarb.h> #include <linux/export.h> -/* Access macro for slots in vblank timestamp ringbuffer. */ -#define vblanktimestamp(dev, pipe, count) \ - ((dev)->vblank[pipe].time[(count) % DRM_VBLANKTIME_RBSIZE]) - /* Retry timestamp calculation up to 3 times to satisfy * drm_timestamp_precision before giving up. */ @@ -82,29 +78,15 @@ static void store_vblank(struct drm_device *dev, unsigned int pipe, struct timeval *t_vblank, u32 last) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; - u32 tslot; assert_spin_locked(&dev->vblank_time_lock); vblank->last = last; - /* All writers hold the spinlock, but readers are serialized by - * the latching of vblank->count below. - */ - tslot = vblank->count + vblank_count_inc; - vblanktimestamp(dev, pipe, tslot) = *t_vblank; - - /* - * vblank timestamp updates are protected on the write side with - * vblank_time_lock, but on the read side done locklessly using a - * sequence-lock on the vblank counter. Ensure correct ordering using - * memory barrriers. We need the barrier both before and also after the - * counter update to synchronize with the next timestamp write. - * The read-side barriers for this are in drm_vblank_count_and_time. - */ - smp_wmb(); + write_seqlock(&vblank->seqlock); + vblank->time = *t_vblank; vblank->count += vblank_count_inc; - smp_wmb(); + write_sequnlock(&vblank->seqlock); } /** @@ -205,7 +187,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, const struct timeval *t_old; u64 diff_ns; - t_old = &vblanktimestamp(dev, pipe, vblank->count); + t_old = &vblank->time; diff_ns = timeval_to_ns(&t_vblank) - timeval_to_ns(t_old); /* @@ -239,49 +221,6 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, diff = 1; } - /* - * FIMXE: Need to replace this hack with proper seqlocks. - * - * Restrict the bump of the software vblank counter to a safe maximum - * value of +1 whenever there is the possibility that concurrent readers - * of vblank timestamps could be active at the moment, as the current - * implementation of the timestamp caching and updating is not safe - * against concurrent readers for calls to store_vblank() with a bump - * of anything but +1. A bump != 1 would very likely return corrupted - * timestamps to userspace, because the same slot in the cache could - * be concurrently written by store_vblank() and read by one of those - * readers without the read-retry logic detecting the collision. - * - * Concurrent readers can exist when we are called from the - * drm_vblank_off() or drm_vblank_on() functions and other non-vblank- - * irq callers. However, all those calls to us are happening with the - * vbl_lock locked to prevent drm_vblank_get(), so the vblank refcount - * can't increase while we are executing. Therefore a zero refcount at - * this point is safe for arbitrary counter bumps if we are called - * outside vblank irq, a non-zero count is not 100% safe. Unfortunately - * we must also accept a refcount of 1, as whenever we are called from - * drm_vblank_get() -> drm_vblank_enable() the refcount will be 1 and - * we must let that one pass through in order to not lose vblank counts - * during vblank irq off - which would completely defeat the whole - * point of this routine. - * - * Whenever we are called from vblank irq, we have to assume concurrent - * readers exist or can show up any time during our execution, even if - * the refcount is currently zero, as vblank irqs are usually only - * enabled due to the presence of readers, and because when we are called - * from vblank irq we can't hold the vbl_lock to protect us from sudden - * bumps in vblank refcount. Therefore also restrict bumps to +1 when - * called from vblank irq. - */ - if ((diff > 1) && (atomic_read(&vblank->refcount) > 1 || - (flags & DRM_CALLED_FROM_VBLIRQ))) { - DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u " - "refcount %u, vblirq %u\n", pipe, diff, - atomic_read(&vblank->refcount), - (flags & DRM_CALLED_FROM_VBLIRQ) != 0); - diff = 1; - } - DRM_DEBUG_VBL("updating vblank count on crtc %u:" " current=%u, diff=%u, hw=%u hw_last=%u\n", pipe, vblank->count, diff, cur_vblank, vblank->last); @@ -379,9 +318,6 @@ static void vblank_disable_fn(unsigned long arg) unsigned int pipe = vblank->pipe; unsigned long irqflags; - if (!dev->vblank_disable_allowed) - return; - spin_lock_irqsave(&dev->vbl_lock, irqflags); if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) { DRM_DEBUG("disabling vblank on crtc %u\n", pipe); @@ -451,6 +387,7 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs) init_waitqueue_head(&vblank->queue); setup_timer(&vblank->disable_timer, vblank_disable_fn, (unsigned long)vblank); + seqlock_init(&vblank->seqlock); } DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); @@ -468,8 +405,6 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs) "get_vblank_timestamp == NULL\n"); } - dev->vblank_disable_allowed = false; - return 0; err: @@ -1022,25 +957,19 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, struct timeval *vblanktime) { struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; - int count = DRM_TIMESTAMP_MAXRETRIES; - u32 cur_vblank; + u32 vblank_count; + unsigned int seq; if (WARN_ON(pipe >= dev->num_crtcs)) return 0; - /* - * Vblank timestamps are read lockless. To ensure consistency the vblank - * counter is rechecked and ordering is ensured using memory barriers. - * This works like a seqlock. The write-side barriers are in store_vblank. - */ do { - cur_vblank = vblank->count; - smp_rmb(); - *vblanktime = vblanktimestamp(dev, pipe, cur_vblank); - smp_rmb(); - } while (cur_vblank != vblank->count && --count > 0); + seq = read_seqbegin(&vblank->seqlock); + vblank_count = vblank->count; + *vblanktime = vblank->time; + } while (read_seqretry(&vblank->seqlock, seq)); - return cur_vblank; + return vblank_count; } EXPORT_SYMBOL(drm_vblank_count_and_time); @@ -1616,7 +1545,6 @@ void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe) if (vblank->inmodeset) { spin_lock_irqsave(&dev->vbl_lock, irqflags); - dev->vblank_disable_allowed = true; drm_reset_vblank_timestamp(dev, pipe); spin_unlock_irqrestore(&dev->vbl_lock, irqflags); diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 04de6fd88f8c..cb39f45d6a16 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -179,12 +179,14 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) { struct drm_mm_node *hole; - u64 end = node->start + node->size; + u64 end; u64 hole_start; u64 hole_end; BUG_ON(node == NULL); + end = node->start + node->size; + /* Find the relevant hole to add our node to */ drm_mm_for_each_hole(hole, mm, hole_start, hole_end) { if (hole_start > node->start || hole_end < end) diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index e3a4adf03e7b..f33ebe638a28 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -30,12 +30,12 @@ * * As KMS moves toward more fine grained locking, and atomic ioctl where * userspace can indirectly control locking order, it becomes necessary - * to use ww_mutex and acquire-contexts to avoid deadlocks. But because + * to use &ww_mutex and acquire-contexts to avoid deadlocks. But because * the locking is more distributed around the driver code, we want a bit * of extra utility/tracking out of our acquire-ctx. This is provided * by drm_modeset_lock / drm_modeset_acquire_ctx. * - * For basic principles of ww_mutex, see: Documentation/locking/ww-mutex-design.txt + * For basic principles of &ww_mutex, see: Documentation/locking/ww-mutex-design.txt * * The basic usage pattern is to: * @@ -51,6 +51,13 @@ * ... do stuff ... * drm_modeset_drop_locks(&ctx); * drm_modeset_acquire_fini(&ctx); + * + * On top of of these per-object locks using &ww_mutex there's also an overall + * dev->mode_config.lock, for protecting everything else. Mostly this means + * probe state of connectors, and preventing hotplug add/removal of connectors. + * + * Finally there's a bunch of dedicated locks to protect drm core internal + * lists and lookup data structures. */ /** diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index df6cdc76a16e..aab0f3f1f42d 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -407,7 +407,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, struct dma_buf *dmabuf; mutex_lock(&file_priv->prime.lock); - obj = drm_gem_object_lookup(dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { ret = -ENOENT; goto out_unlock; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index c2f92e362812..3d4f56df8359 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -314,7 +314,7 @@ static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data, if (args->op & ~(ETNA_PREP_READ | ETNA_PREP_WRITE | ETNA_PREP_NOSYNC)) return -EINVAL; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; @@ -335,7 +335,7 @@ static int etnaviv_ioctl_gem_cpu_fini(struct drm_device *dev, void *data, if (args->flags) return -EINVAL; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; @@ -356,7 +356,7 @@ static int etnaviv_ioctl_gem_info(struct drm_device *dev, void *data, if (args->pad) return -EINVAL; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; @@ -441,7 +441,7 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data, if (!gpu) return -ENXIO; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index 236ada93df53..afdd55ddf821 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -28,11 +28,6 @@ #define BO_LOCKED 0x4000 #define BO_PINNED 0x2000 -static inline void __user *to_user_ptr(u64 address) -{ - return (void __user *)(uintptr_t)address; -} - static struct etnaviv_gem_submit *submit_create(struct drm_device *dev, struct etnaviv_gpu *gpu, size_t nr) { @@ -347,21 +342,21 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, cmdbuf->exec_state = args->exec_state; cmdbuf->ctx = file->driver_priv; - ret = copy_from_user(bos, to_user_ptr(args->bos), + ret = copy_from_user(bos, u64_to_user_ptr(args->bos), args->nr_bos * sizeof(*bos)); if (ret) { ret = -EFAULT; goto err_submit_cmds; } - ret = copy_from_user(relocs, to_user_ptr(args->relocs), + ret = copy_from_user(relocs, u64_to_user_ptr(args->relocs), args->nr_relocs * sizeof(*relocs)); if (ret) { ret = -EFAULT; goto err_submit_cmds; } - ret = copy_from_user(stream, to_user_ptr(args->stream), + ret = copy_from_user(stream, u64_to_user_ptr(args->stream), args->stream_size); if (ret) { ret = -EFAULT; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 049d00d8ded5..ff6aa5dfb2d7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -796,9 +796,9 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m) debug.state[0] == debug.state[1]) { seq_puts(m, "seems to be stuck\n"); } else if (debug.address[0] == debug.address[1]) { - seq_puts(m, "adress is constant\n"); + seq_puts(m, "address is constant\n"); } else { - seq_puts(m, "is runing\n"); + seq_puts(m, "is running\n"); } seq_printf(m, "\t address 0: 0x%08x\n", debug.address[0]); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 21c719e8e02b..2dd820e23b0c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -212,13 +212,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) */ dev->irq_enabled = true; - /* - * with vblank_disable_allowed = true, vblank interrupt will be disabled - * by drm timer once a current process gives up ownership of - * vblank event.(after drm_vblank_put function is called) - */ - dev->vblank_disable_allowed = true; - /* init kms poll for handling hpd */ drm_kms_helper_poll_init(dev); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index f851a40ac6cb..e0166403b4bd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -152,8 +152,7 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, int ret; for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) { - obj = drm_gem_object_lookup(dev, file_priv, - mode_cmd->handles[i]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); if (!obj) { DRM_ERROR("failed to lookup gem object\n"); ret = -ENOENT; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 72d9414bd944..cdf9f1af4347 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -177,7 +177,7 @@ unsigned long exynos_drm_gem_get_size(struct drm_device *dev, struct exynos_drm_gem *exynos_gem; struct drm_gem_object *obj; - obj = drm_gem_object_lookup(dev, file_priv, gem_handle); + obj = drm_gem_object_lookup(file_priv, gem_handle); if (!obj) { DRM_ERROR("failed to lookup gem object.\n"); return 0; @@ -296,7 +296,7 @@ dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev, struct exynos_drm_gem *exynos_gem; struct drm_gem_object *obj; - obj = drm_gem_object_lookup(dev, filp, gem_handle); + obj = drm_gem_object_lookup(filp, gem_handle); if (!obj) { DRM_ERROR("failed to lookup gem object.\n"); return ERR_PTR(-EINVAL); @@ -313,7 +313,7 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev, { struct drm_gem_object *obj; - obj = drm_gem_object_lookup(dev, filp, gem_handle); + obj = drm_gem_object_lookup(filp, gem_handle); if (!obj) { DRM_ERROR("failed to lookup gem object.\n"); return; @@ -362,7 +362,7 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, struct drm_exynos_gem_info *args = data; struct drm_gem_object *obj; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = drm_gem_object_lookup(file_priv, args->handle); if (!obj) { DRM_ERROR("failed to lookup gem object.\n"); return -EINVAL; @@ -434,7 +434,7 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, * with DRM_IOCTL_MODE_MAP_DUMB command. */ - obj = drm_gem_object_lookup(dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("failed to lookup gem object.\n"); return -EINVAL; diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 50185ac347b2..55f1d37c666a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -166,7 +166,7 @@ static void exynos_drm_plane_destroy_state(struct drm_plane *plane, { struct exynos_drm_plane_state *old_exynos_state = to_exynos_plane_state(old_state); - __drm_atomic_helper_plane_destroy_state(plane, old_state); + __drm_atomic_helper_plane_destroy_state(old_state); kfree(old_exynos_state); } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 6cd09944405f..58de5a430508 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1626,7 +1626,7 @@ static int hdmi_clk_init(struct hdmi_context *hdata) clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL); if (!clks) - return -ENOMEM; + return -ENOMEM; hdata->clk_gates = clks; hdata->clk_muxes = clks + drv_data->clk_gates.count; diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 44f6f262d75a..0ec1ad961e0d 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -80,7 +80,6 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) dev_err(dev->dev, "failed to initialize vblank\n"); goto done; } - dev->vblank_disable_allowed = true; ret = fsl_dcu_drm_irq_init(dev); if (ret < 0) diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index ec2bc769742a..7440bf90ac9c 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -490,7 +490,7 @@ static struct drm_framebuffer *psb_user_framebuffer_create * Find the GEM object and thus the gtt range object that is * to back this space */ - obj = drm_gem_object_lookup(dev, filp, cmd->handles[0]); + obj = drm_gem_object_lookup(filp, cmd->handles[0]); if (obj == NULL) return ERR_PTR(-ENOENT); diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 506224b3a0ad..6d1cb6b370b1 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -63,7 +63,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, struct drm_gem_object *obj; /* GEM does all our handle to object mapping */ - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index 5bf765de2517..c95406e6f44d 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -372,7 +372,7 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc, return -EINVAL; } - obj = drm_gem_object_lookup(dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { ret = -ENOENT; goto unlock; diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 4e1c6850520e..82b8ce418b27 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -374,7 +374,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) drm_irq_install(dev, dev->pdev->irq); - dev->vblank_disable_allowed = true; dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ dev->driver->get_vblank_counter = psb_get_vblank_counter; diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 398015be87e4..7b6c84925098 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -491,7 +491,6 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, struct drm_psb_private *dev_priv = dev->dev_private; struct gma_crtc *gma_crtc; int i; - uint16_t *r_base, *g_base, *b_base; /* We allocate a extra array of drm_connector pointers * for fbdev after the crtc */ @@ -519,16 +518,10 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, gma_crtc->pipe = pipe; gma_crtc->plane = pipe; - r_base = gma_crtc->base.gamma_store; - g_base = r_base + 256; - b_base = g_base + 256; for (i = 0; i < 256; i++) { gma_crtc->lut_r[i] = i; gma_crtc->lut_g[i] = i; gma_crtc->lut_b[i] = i; - r_base[i] = i << 8; - g_base[i] = i << 8; - b_base[i] = i << 8; gma_crtc->lut_adj[i] = 0; } diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 3f94785fbcca..193657259ee9 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -173,7 +173,7 @@ static struct drm_driver kirin_drm_driver = { .fops = &kirin_drm_fops, .set_busid = drm_platform_set_busid, - .gem_free_object = drm_gem_cma_free_object, + .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = kirin_gem_cma_dumb_create, .dumb_map_offset = drm_gem_cma_dumb_map_offset, diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index aee5e59cb477..07edaed9d5a2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -515,9 +515,6 @@ static int i915_load_modeset_init(struct drm_device *dev) intel_modeset_gem_init(dev); - /* Always safe in the mode setting case. */ - /* FIXME: do pre/post-mode set stuff in core KMS code */ - dev->vblank_disable_allowed = true; if (INTEL_INFO(dev)->num_pipes == 0) return 0; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 943d7b222fd4..872c60608dbd 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -35,11 +35,9 @@ #include "i915_trace.h" #include "intel_drv.h" -#include <linux/apple-gmux.h> #include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> -#include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include <drm/drm_crtc_helper.h> @@ -1030,13 +1028,7 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (PCI_FUNC(pdev->devfn)) return -ENODEV; - /* - * apple-gmux is needed on dual GPU MacBook Pro - * to probe the panel if we're the inactive GPU. - */ - if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) && - apple_gmux_present() && pdev != vga_default_device() && - !vga_switcheroo_handler_flags()) + if (vga_switcheroo_client_probe_defer(pdev)) return -EPROBE_DEFER; return drm_get_pci_dev(pdev, ent, &driver); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c1e61ff9bade..96d5034830f0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3833,11 +3833,6 @@ static inline i915_reg_t i915_vgacntrl_reg(struct drm_device *dev) return VGACNTRL; } -static inline void __user *to_user_ptr(u64 address) -{ - return (void __user *)(uintptr_t)address; -} - static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m) { unsigned long j = msecs_to_jiffies(m); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3472280d8142..343d88114f3b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -319,7 +319,7 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, { struct drm_device *dev = obj->base.dev; void *vaddr = obj->phys_handle->vaddr + args->offset; - char __user *user_data = to_user_ptr(args->data_ptr); + char __user *user_data = u64_to_user_ptr(args->data_ptr); int ret = 0; /* We manually control the domain here and pretend that it @@ -600,7 +600,7 @@ i915_gem_shmem_pread(struct drm_device *dev, int needs_clflush = 0; struct sg_page_iter sg_iter; - user_data = to_user_ptr(args->data_ptr); + user_data = u64_to_user_ptr(args->data_ptr); remain = args->size; obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); @@ -687,7 +687,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, return 0; if (!access_ok(VERIFY_WRITE, - to_user_ptr(args->data_ptr), + u64_to_user_ptr(args->data_ptr), args->size)) return -EFAULT; @@ -695,7 +695,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; @@ -779,7 +779,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, if (ret) goto out_unpin; - user_data = to_user_ptr(args->data_ptr); + user_data = u64_to_user_ptr(args->data_ptr); remain = args->size; offset = i915_gem_obj_ggtt_offset(obj) + args->offset; @@ -903,7 +903,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev, int needs_clflush_before = 0; struct sg_page_iter sg_iter; - user_data = to_user_ptr(args->data_ptr); + user_data = u64_to_user_ptr(args->data_ptr); remain = args->size; obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); @@ -1032,12 +1032,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, return 0; if (!access_ok(VERIFY_READ, - to_user_ptr(args->data_ptr), + u64_to_user_ptr(args->data_ptr), args->size)) return -EFAULT; if (likely(!i915.prefault_disable)) { - ret = fault_in_multipages_readable(to_user_ptr(args->data_ptr), + ret = fault_in_multipages_readable(u64_to_user_ptr(args->data_ptr), args->size); if (ret) return -EFAULT; @@ -1049,7 +1049,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, if (ret) goto put_rpm; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; @@ -1617,7 +1617,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; @@ -1665,7 +1665,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; @@ -1709,10 +1709,10 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (args->flags & ~(I915_MMAP_WC)) return -EINVAL; - if (args->flags & I915_MMAP_WC && !cpu_has_pat) + if (args->flags & I915_MMAP_WC && !boot_cpu_has(X86_FEATURE_PAT)) return -ENODEV; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (obj == NULL) return -ENOENT; @@ -1731,7 +1731,10 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - down_write(&mm->mmap_sem); + if (down_write_killable(&mm->mmap_sem)) { + drm_gem_object_unreference_unlocked(obj); + return -EINTR; + } vma = find_vma(mm, addr); if (vma) vma->vm_page_prot = @@ -2075,7 +2078,7 @@ i915_gem_mmap_gtt(struct drm_file *file, if (ret) return ret; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; @@ -3132,7 +3135,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) if (ret) return ret; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->bo_handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->bo_handle)); if (&obj->base == NULL) { mutex_unlock(&dev->struct_mutex); return -ENOENT; @@ -3939,7 +3942,7 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_caching *args = data; struct drm_i915_gem_object *obj; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) return -ENOENT; @@ -4000,7 +4003,7 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, if (ret) goto rpm_put; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; @@ -4370,7 +4373,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; @@ -4435,7 +4438,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file_priv, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 84d990331abd..8097698b9622 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -489,7 +489,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, ret = relocate_entry_cpu(obj, reloc, target_offset); else if (obj->map_and_fenceable) ret = relocate_entry_gtt(obj, reloc, target_offset); - else if (cpu_has_clflush) + else if (static_cpu_has(X86_FEATURE_CLFLUSH)) ret = relocate_entry_clflush(obj, reloc, target_offset); else { WARN_ONCE(1, "Impossible case in relocation handling\n"); @@ -515,7 +515,7 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma, struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; int remain, ret; - user_relocs = to_user_ptr(entry->relocs_ptr); + user_relocs = u64_to_user_ptr(entry->relocs_ptr); remain = entry->relocation_count; while (remain) { @@ -536,9 +536,7 @@ i915_gem_execbuffer_relocate_vma(struct i915_vma *vma, return ret; if (r->presumed_offset != offset && - __copy_to_user_inatomic(&user_relocs->presumed_offset, - &r->presumed_offset, - sizeof(r->presumed_offset))) { + __put_user(r->presumed_offset, &user_relocs->presumed_offset)) { return -EFAULT; } @@ -869,7 +867,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, u64 invalid_offset = (u64)-1; int j; - user_relocs = to_user_ptr(exec[i].relocs_ptr); + user_relocs = u64_to_user_ptr(exec[i].relocs_ptr); if (copy_from_user(reloc+total, user_relocs, exec[i].relocation_count * sizeof(*reloc))) { @@ -1014,7 +1012,7 @@ validate_exec_list(struct drm_device *dev, invalid_flags |= EXEC_OBJECT_NEEDS_GTT; for (i = 0; i < count; i++) { - char __user *ptr = to_user_ptr(exec[i].relocs_ptr); + char __user *ptr = u64_to_user_ptr(exec[i].relocs_ptr); int length; /* limited by fault_in_pages_readable() */ if (exec[i].flags & invalid_flags) @@ -1689,7 +1687,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, return -ENOMEM; } ret = copy_from_user(exec_list, - to_user_ptr(args->buffers_ptr), + u64_to_user_ptr(args->buffers_ptr), sizeof(*exec_list) * args->buffer_count); if (ret != 0) { DRM_DEBUG("copy %d exec entries failed %d\n", @@ -1725,7 +1723,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); if (!ret) { struct drm_i915_gem_exec_object __user *user_exec_list = - to_user_ptr(args->buffers_ptr); + u64_to_user_ptr(args->buffers_ptr); /* Copy the new buffer offsets back to the user's exec list. */ for (i = 0; i < args->buffer_count; i++) { @@ -1777,7 +1775,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, return -ENOMEM; } ret = copy_from_user(exec2_list, - to_user_ptr(args->buffers_ptr), + u64_to_user_ptr(args->buffers_ptr), sizeof(*exec2_list) * args->buffer_count); if (ret != 0) { DRM_DEBUG("copy %d exec entries failed %d\n", @@ -1790,7 +1788,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, if (!ret) { /* Copy the new buffer offsets back to the user's exec list. */ struct drm_i915_gem_exec_object2 __user *user_exec_list = - to_user_ptr(args->buffers_ptr); + u64_to_user_ptr(args->buffers_ptr); int i; for (i = 0; i < args->buffer_count; i++) { diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 2fcb4afade19..a6eb5c47a49c 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -166,7 +166,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, struct drm_i915_gem_object *obj; int ret = 0; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) return -ENOENT; @@ -297,7 +297,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); if (&obj->base == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 08b173cd8e3c..60cba1956c0d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13058,7 +13058,7 @@ verify_crtc_state(struct drm_crtc *crtc, bool active; old_state = old_crtc_state->state; - __drm_atomic_helper_crtc_destroy_state(crtc, old_crtc_state); + __drm_atomic_helper_crtc_destroy_state(old_crtc_state); pipe_config = to_intel_crtc_state(old_crtc_state); memset(pipe_config, 0, sizeof(*pipe_config)); pipe_config->base.crtc = crtc; @@ -15033,8 +15033,7 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_i915_gem_object *obj; struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; - obj = to_intel_bo(drm_gem_object_lookup(dev, filp, - mode_cmd.handles[0])); + obj = to_intel_bo(drm_gem_object_lookup(filp, mode_cmd.handles[0])); if (&obj->base == NULL) return ERR_PTR(-ENOENT); @@ -15918,7 +15917,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) struct intel_crtc_state *crtc_state = crtc->config; int pixclk = 0; - __drm_atomic_helper_crtc_destroy_state(&crtc->base, &crtc_state->base); + __drm_atomic_helper_crtc_destroy_state(&crtc_state->base); memset(crtc_state, 0, sizeof(*crtc_state)); crtc_state->base.crtc = &crtc->base; diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index bdf64dec190e..ef8e67690f3d 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -370,12 +370,12 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, uint64_t conn_configured = 0, mask; int pass = 0; - save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool), + save_enabled = kcalloc(fb_helper->connector_count, sizeof(bool), GFP_KERNEL); if (!save_enabled) return false; - memcpy(save_enabled, enabled, dev->mode_config.num_connector); + memcpy(save_enabled, enabled, fb_helper->connector_count); mask = (1 << fb_helper->connector_count) - 1; retry: for (i = 0; i < fb_helper->connector_count; i++) { @@ -522,7 +522,7 @@ retry: if (fallback) { bail: DRM_DEBUG_KMS("Not using firmware configuration\n"); - memcpy(enabled, save_enabled, dev->mode_config.num_connector); + memcpy(enabled, save_enabled, fb_helper->connector_count); kfree(save_enabled); return false; } diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index b9b042cc619f..eb93f90bb74d 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1121,7 +1121,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, } crtc = to_intel_crtc(drmmode_crtc); - new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv, + new_bo = to_intel_bo(drm_gem_object_lookup(file_priv, put_image_rec->bo_handle)); if (&new_bo->base == NULL) { ret = -ENOENT; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index efaee7a7f933..f0b1602c3258 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1638,6 +1638,12 @@ static int pwm_setup_backlight(struct intel_connector *connector, return -ENODEV; } + /* + * FIXME: pwm_apply_args() should be removed when switching to + * the atomic PWM API. + */ + pwm_apply_args(panel->backlight.pwm); + retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS, CRC_PMIC_PWM_PERIOD_NS); if (retval < 0) { diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 2453fb1c68a7..1f14b602882b 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -25,6 +25,7 @@ #include <drm/drm_fb_cma_helper.h> #include <drm/drm_plane_helper.h> #include <drm/drm_of.h> +#include <video/imx-ipu-v3.h> #include "imx-drm.h" @@ -252,13 +253,6 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) if (ret) goto err_kms; - /* - * with vblank_disable_allowed = true, vblank interrupt will be - * disabled by drm timer once a current process gives up ownership - * of vblank event. (after drm_vblank_put function is called) - */ - drm->vblank_disable_allowed = true; - platform_set_drvdata(drm->platformdev, drm); /* Now try and bind all our sub-components */ @@ -444,6 +438,13 @@ static int compare_of(struct device *dev, void *data) { struct device_node *np = data; + /* Special case for DI, dev->of_node may not be set yet */ + if (strcmp(dev->driver->name, "imx-ipuv3-crtc") == 0) { + struct ipu_client_platformdata *pdata = dev->platform_data; + + return pdata->of_node == np; + } + /* Special case for LDB, one device for two channels */ if (of_node_cmp(np->name, "lvds-channel") == 0) { np = of_get_parent(np); diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index dee8e8b3523b..b2c30b8d9816 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -473,7 +473,7 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc, &ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs, - ipu_crtc->dev->of_node); + pdata->of_node); if (ret) { dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); goto err_put_resources; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 3095fc182f07..24aa3bad1e76 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -146,7 +146,7 @@ static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc static void mtk_drm_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state) { - __drm_atomic_helper_crtc_destroy_state(crtc, state); + __drm_atomic_helper_crtc_destroy_state(state); kfree(to_mtk_crtc_state(state)); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index b1223d54d0ab..06a417b2f91e 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -243,7 +243,7 @@ static struct drm_driver mtk_drm_driver = { .enable_vblank = mtk_drm_crtc_enable_vblank, .disable_vblank = mtk_drm_crtc_disable_vblank, - .gem_free_object = mtk_drm_gem_free_object, + .gem_free_object_unlocked = mtk_drm_gem_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = mtk_drm_gem_dumb_create, .dumb_map_offset = mtk_drm_gem_dumb_map_offset, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c index 33d30c19f35f..147df85399ab 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c @@ -138,7 +138,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev, if (drm_format_num_planes(cmd->pixel_format) != 1) return ERR_PTR(-EINVAL); - gem = drm_gem_object_lookup(dev, file, cmd->handles[0]); + gem = drm_gem_object_lookup(file, cmd->handles[0]); if (!gem) return ERR_PTR(-ENOENT); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index a773bfaea913..fa2ec0cd00e8 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -139,7 +139,7 @@ int mtk_drm_gem_dumb_map_offset(struct drm_file *file_priv, struct drm_gem_object *obj; int ret; - obj = drm_gem_object_lookup(dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("failed to lookup gem object.\n"); return -EINVAL; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index c898788f3dd3..51bc8988fc26 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -116,7 +116,7 @@ static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane static void mtk_drm_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - __drm_atomic_helper_plane_destroy_state(plane, state); + __drm_atomic_helper_plane_destroy_state(state); kfree(to_mtk_plane_state(state)); } diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index a7bf6a90eae5..2ac3fcbfea7b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -75,7 +75,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, return 0; } - obj = drm_gem_object_lookup(dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) return -ENOENT; diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index 9147444d5bf2..615cbb08ba29 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -53,7 +53,7 @@ mgag200_user_framebuffer_create(struct drm_device *dev, struct mga_framebuffer *mga_fb; int ret; - obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); if (obj == NULL) return ERR_PTR(-ENOENT); @@ -358,7 +358,7 @@ mgag200_dumb_mmap_offset(struct drm_file *file, struct drm_gem_object *obj; struct mgag200_bo *bo; - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 3a48889dd9e5..9527dafc3e69 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -427,7 +427,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, } if (handle) { - cursor_bo = drm_gem_object_lookup(dev, file_priv, handle); + cursor_bo = drm_gem_object_lookup(file_priv, handle); if (!cursor_bo) return -ENOENT; } else { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index ce779d956d57..88fe256c1931 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -518,7 +518,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, goto set_cursor; } - cursor_bo = drm_gem_object_lookup(dev, file, handle); + cursor_bo = drm_gem_object_lookup(file, handle); if (!cursor_bo) return -ENOENT; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 9788989ea21c..9c654092ef78 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -622,7 +622,7 @@ static int msm_ioctl_gem_cpu_prep(struct drm_device *dev, void *data, return -EINVAL; } - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; @@ -640,7 +640,7 @@ static int msm_ioctl_gem_cpu_fini(struct drm_device *dev, void *data, struct drm_gem_object *obj; int ret; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; @@ -661,7 +661,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, if (args->pad) return -EINVAL; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 17e0c9eb1900..461dc8b873f0 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -145,8 +145,7 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev, int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format); for (i = 0; i < n; i++) { - bos[i] = drm_gem_object_lookup(dev, file, - mode_cmd->handles[i]); + bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]); if (!bos[i]) { ret = -ENXIO; goto out_unref; diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index d9759bf3482e..1a061e3e8b9e 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -184,21 +184,7 @@ fail: return ret; } -static void msm_crtc_fb_gamma_set(struct drm_crtc *crtc, - u16 red, u16 green, u16 blue, int regno) -{ - DBG("fbdev: set gamma"); -} - -static void msm_crtc_fb_gamma_get(struct drm_crtc *crtc, - u16 *red, u16 *green, u16 *blue, int regno) -{ - DBG("fbdev: get gamma"); -} - static const struct drm_fb_helper_funcs msm_fb_helper_funcs = { - .gamma_set = msm_crtc_fb_gamma_set, - .gamma_get = msm_crtc_fb_gamma_get, .fb_probe = msm_fbdev_create, }; diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 9bbe1c5e7151..7daf4054dd2b 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -374,7 +374,7 @@ int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, int ret = 0; /* GEM does all our handle to object mapping */ - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) { ret = -ENOENT; goto fail; diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index a9a001150b9e..b89ca5174863 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -28,11 +28,6 @@ #define BO_LOCKED 0x4000 #define BO_PINNED 0x2000 -static inline void __user *to_user_ptr(u64 address) -{ - return (void __user *)(uintptr_t)address; -} - static struct msm_gem_submit *submit_create(struct drm_device *dev, struct msm_gpu *gpu, int nr) { @@ -78,7 +73,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, struct drm_gem_object *obj; struct msm_gem_object *msm_obj; void __user *userptr = - to_user_ptr(args->bos + (i * sizeof(submit_bo))); + u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); if (ret) { @@ -288,7 +283,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob for (i = 0; i < nr_relocs; i++) { struct drm_msm_gem_submit_reloc submit_reloc; void __user *userptr = - to_user_ptr(relocs + (i * sizeof(submit_reloc))); + u64_to_user_ptr(relocs + (i * sizeof(submit_reloc))); uint32_t iova, off; bool valid; @@ -395,7 +390,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, for (i = 0; i < args->nr_cmds; i++) { struct drm_msm_gem_submit_cmd submit_cmd; void __user *userptr = - to_user_ptr(args->cmds + (i * sizeof(submit_cmd))); + u64_to_user_ptr(args->cmds + (i * sizeof(submit_cmd))); struct msm_gem_object *msm_obj; uint32_t iova; diff --git a/drivers/gpu/drm/nouveau/dispnv04/arb.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c index 82bd4658aa58..a555681c3096 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/arb.c +++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c @@ -23,7 +23,7 @@ #include <drm/drmP.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "hw.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 55ccbf006b5e..6f318c54da33 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -28,8 +28,9 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_plane_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" +#include "nouveau_ttm.h" #include "nouveau_bo.h" #include "nouveau_gem.h" #include "nouveau_encoder.h" @@ -995,7 +996,7 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, if (width != 64 || height != 64) return -EINVAL; - gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); + gem = drm_gem_object_lookup(file_priv, buffer_handle); if (!gem) return -ENOENT; cursor = nouveau_gem_object(gem); diff --git a/drivers/gpu/drm/nouveau/dispnv04/cursor.c b/drivers/gpu/drm/nouveau/dispnv04/cursor.c index 4e61173c3353..c83116a308a4 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/cursor.c +++ b/drivers/gpu/drm/nouveau/dispnv04/cursor.c @@ -1,6 +1,6 @@ #include <drm/drmP.h> #include <drm/drm_mode.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "nouveau_crtc.h" #include "hw.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/dac.c b/drivers/gpu/drm/nouveau/dispnv04/dac.c index b48eec395f07..b6cc7766e6f7 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dac.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dac.c @@ -27,7 +27,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_encoder.h" #include "nouveau_connector.h" #include "nouveau_crtc.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index 05bfd151d1d8..c2947ef7d4fc 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -27,7 +27,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "nouveau_encoder.h" #include "nouveau_connector.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index b4a6bc433ef5..aea81a547e85 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -25,7 +25,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "hw.h" #include "nouveau_encoder.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.h b/drivers/gpu/drm/nouveau/dispnv04/disp.h index 6c9a1e89810f..7030307d2d48 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.h @@ -1,6 +1,6 @@ #ifndef __NV04_DISPLAY_H__ #define __NV04_DISPLAY_H__ - +#include <subdev/bios.h> #include <subdev/bios/pll.h> #include "nouveau_display.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c index 956a833b8200..74856a8b8f35 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/hw.c +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c @@ -23,7 +23,7 @@ */ #include <drm/drmP.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "hw.h" #include <subdev/bios/pll.h> diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index aeebdd402478..ec444eac6258 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -27,7 +27,7 @@ #include <drm/drm_crtc.h> #include <drm/drm_fourcc.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_bo.h" #include "nouveau_connector.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c index 903c473d266f..2b83b2c39d1d 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c @@ -26,7 +26,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_encoder.h" #include "nouveau_crtc.h" #include "hw.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c index 54e9fb9eb5c0..477a8d072af4 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c @@ -25,7 +25,7 @@ */ #include <drm/drmP.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "nouveau_encoder.h" #include "nouveau_connector.h" diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index 163317d26de9..a665b78b2af5 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -26,7 +26,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "nouveau_encoder.h" #include "nouveau_connector.h" diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index 4993a863adb9..c612dc1f1eb4 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h @@ -7,6 +7,7 @@ enum nvkm_devidx { NVKM_SUBDEV_PCI, NVKM_SUBDEV_VBIOS, NVKM_SUBDEV_DEVINIT, + NVKM_SUBDEV_TOP, NVKM_SUBDEV_IBUS, NVKM_SUBDEV_GPIO, NVKM_SUBDEV_I2C, @@ -131,6 +132,7 @@ struct nvkm_device { struct nvkm_secboot *secboot; struct nvkm_therm *therm; struct nvkm_timer *timer; + struct nvkm_top *top; struct nvkm_volt *volt; struct nvkm_engine *bsp; @@ -200,6 +202,7 @@ struct nvkm_device_chip { int (*secboot )(struct nvkm_device *, int idx, struct nvkm_secboot **); int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **); int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **); + int (*top )(struct nvkm_device *, int idx, struct nvkm_top **); int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **); int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h index 48bf128456a1..9ebfd8782366 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h @@ -38,11 +38,9 @@ struct nvkm_engine_func { }; int nvkm_engine_ctor(const struct nvkm_engine_func *, struct nvkm_device *, - int index, u32 pmc_enable, bool enable, - struct nvkm_engine *); + int index, bool enable, struct nvkm_engine *); int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *, - int index, u32 pmc_enable, bool enable, - struct nvkm_engine **); + int index, bool enable, struct nvkm_engine **); struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *); void nvkm_engine_unref(struct nvkm_engine **); void nvkm_engine_tile(struct nvkm_engine *, int region); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h index 3b5dc9c63069..57adefa8b08e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h @@ -6,7 +6,6 @@ struct nvkm_subdev { const struct nvkm_subdev_func *func; struct nvkm_device *device; enum nvkm_devidx index; - u32 pmc_enable; struct mutex mutex; u32 debug; @@ -24,7 +23,7 @@ struct nvkm_subdev_func { extern const char *nvkm_subdev_name[NVKM_SUBDEV_NR]; void nvkm_subdev_ctor(const struct nvkm_subdev_func *, struct nvkm_device *, - int index, u32 pmc_enable, struct nvkm_subdev *); + int index, struct nvkm_subdev *); void nvkm_subdev_del(struct nvkm_subdev **); int nvkm_subdev_preinit(struct nvkm_subdev *); int nvkm_subdev_init(struct nvkm_subdev *); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h index 81c0bc66a9f8..e6baf039c269 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h @@ -40,7 +40,6 @@ struct nvkm_falcon_func { u32 *data; u32 size; } data; - u32 pmc_enable; void (*init)(struct nvkm_falcon *); void (*intr)(struct nvkm_falcon *, struct nvkm_fifo_chan *); struct nvkm_sclass sclass[]; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h index 3128d21a5d1a..b1fcc416732f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/xtensa.h @@ -15,7 +15,6 @@ int nvkm_xtensa_new_(const struct nvkm_xtensa_func *, struct nvkm_device *, int index, bool enable, u32 addr, struct nvkm_engine **); struct nvkm_xtensa_func { - u32 pmc_enable; u32 fifo_val; u32 unkd28; struct nvkm_sclass sclass[]; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h index 193626c69517..709d786f1808 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h @@ -7,6 +7,7 @@ struct nvkm_devinit { const struct nvkm_devinit_func *func; struct nvkm_subdev subdev; bool post; + bool force_post; }; u32 nvkm_devinit_mmio(struct nvkm_devinit *, u32 addr); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h index 85ab72c7f821..0a734fd06acf 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h @@ -55,6 +55,9 @@ struct nvkm_fb { struct nvkm_fb_tile region[16]; int regions; } tile; + + struct nvkm_memory *mmu_rd; + struct nvkm_memory *mmu_wr; }; bool nvkm_fb_memtype_valid(struct nvkm_fb *, u32 memtype); @@ -87,6 +90,7 @@ int gf100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); int gk104_fb_new(struct nvkm_device *, int, struct nvkm_fb **); int gk20a_fb_new(struct nvkm_device *, int, struct nvkm_fb **); int gm107_fb_new(struct nvkm_device *, int, struct nvkm_fb **); +int gm200_fb_new(struct nvkm_device *, int, struct nvkm_fb **); #include <subdev/bios.h> #include <subdev/bios/ramcfg.h> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/iccsense.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/iccsense.h index 530c6215fe4f..3c2ddd975273 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/iccsense.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/iccsense.h @@ -3,15 +3,13 @@ #include <core/subdev.h> -struct nkvm_iccsense_rail; struct nvkm_iccsense { struct nvkm_subdev subdev; - u8 rail_count; bool data_valid; - struct nvkm_iccsense_rail *rails; + struct list_head sensors; + struct list_head rails; }; int gf100_iccsense_new(struct nvkm_device *, int index, struct nvkm_iccsense **); -int nvkm_iccsense_read(struct nvkm_iccsense *iccsense, u8 idx); int nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h index 4de05e718f83..2e80682b2da1 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h @@ -10,12 +10,18 @@ struct nvkm_mc { void nvkm_mc_intr(struct nvkm_mc *, bool *handled); void nvkm_mc_intr_unarm(struct nvkm_mc *); void nvkm_mc_intr_rearm(struct nvkm_mc *); +void nvkm_mc_reset(struct nvkm_mc *, enum nvkm_devidx); void nvkm_mc_unk260(struct nvkm_mc *, u32 data); int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **); +int nv11_mc_new(struct nvkm_device *, int, struct nvkm_mc **); +int nv17_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int nv44_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int nv50_mc_new(struct nvkm_device *, int, struct nvkm_mc **); +int g84_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int g98_mc_new(struct nvkm_device *, int, struct nvkm_mc **); +int gt215_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int gf100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); +int gk104_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h new file mode 100644 index 000000000000..8fb575a92c48 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h @@ -0,0 +1,17 @@ +#ifndef __NVKM_TOP_H__ +#define __NVKM_TOP_H__ +#include <core/subdev.h> + +struct nvkm_top { + const struct nvkm_top_func *func; + struct nvkm_subdev subdev; + struct list_head device; +}; + +u32 nvkm_top_reset(struct nvkm_top *, enum nvkm_devidx); +u32 nvkm_top_intr(struct nvkm_top *, u32 intr, u64 *subdevs); +enum nvkm_devidx nvkm_top_fault(struct nvkm_top *, int fault); +enum nvkm_devidx nvkm_top_engine(struct nvkm_top *, int, int *runl, int *engn); + +int gk104_top_new(struct nvkm_device *, int, struct nvkm_top **); +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index a59e524c028c..eb7de487a2b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -29,7 +29,7 @@ #include <nvif/cla06f.h> #include <nvif/unpack.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_gem.h" #include "nouveau_chan.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index cdf522770cfa..db76b94e6e26 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -6,7 +6,7 @@ #include <drm/drm_edid.h> #include <acpi/video.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_acpi.h" #define NOUVEAU_DSM_LED 0x02 diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 89eb46040b13..f5101be806cb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -32,7 +32,7 @@ #include <linux/backlight.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "nouveau_encoder.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 4dca65a63b92..a1570b109434 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -24,7 +24,7 @@ #include <drm/drmP.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_reg.h" #include "dispnv04/hw.h" #include "nouveau_encoder.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 74a8a2ca89ee..5e3f3e826476 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -30,7 +30,7 @@ #include <linux/dma-mapping.h> #include <linux/swiotlb.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 879655c03ae9..b1d2527c5625 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -34,7 +34,7 @@ /*XXX*/ #include <core/client.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_bo.h" #include "nouveau_chan.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index e81aefe5ffa7..c1084088f9e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -34,7 +34,7 @@ #include <drm/drm_crtc_helper.h> #include "nouveau_reg.h" -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "dispnv04/hw.h" #include "nouveau_acpi.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 3d0dc199b253..411c12cdb249 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -32,7 +32,7 @@ #include <nvif/class.h> #include <nvif/if0001.h> #include "nouveau_debugfs.h" -#include "nouveau_drm.h" +#include "nouveau_drv.h" static int nouveau_debugfs_vbios_image(struct seq_file *m, void *data) diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.h b/drivers/gpu/drm/nouveau/nouveau_debugfs.h index b8c03ff5bf05..eab58811417a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.h +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.h @@ -5,7 +5,7 @@ #if defined(CONFIG_DEBUG_FS) -#include "nouveau_drm.h" +#include "nouveau_drv.h" struct nouveau_debugfs { struct nvif_object ctrl; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index cf6e6171b428..7c77f960c8b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -279,7 +279,7 @@ nouveau_user_framebuffer_create(struct drm_device *dev, struct drm_gem_object *gem; int ret = -ENOMEM; - gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); + gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); if (!gem) return ERR_PTR(-ENOENT); @@ -916,7 +916,7 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, { struct drm_gem_object *gem; - gem = drm_gem_object_lookup(dev, file_priv, handle); + gem = drm_gem_object_lookup(file_priv, handle); if (gem) { struct nouveau_bo *bo = nouveau_gem_object(gem); *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 5a57d8b472c4..24273bacd885 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -3,7 +3,7 @@ #include <subdev/mmu.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" struct nouveau_framebuffer { struct drm_framebuffer base; diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index d168c63533c1..2634a1a79888 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -24,7 +24,7 @@ * */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" void diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index e17e15ec7d43..87d52d36f4fc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -25,7 +25,7 @@ #include <drm/drmP.h> #include <drm/drm_dp_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_connector.h" #include "nouveau_encoder.h" #include "nouveau_crtc.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index db5c7d0cc25c..5c4d4dff2da8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -22,13 +22,11 @@ * Authors: Ben Skeggs */ -#include <linux/apple-gmux.h> #include <linux/console.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/pm_runtime.h> -#include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include "drmP.h" @@ -44,7 +42,7 @@ #include <nvif/cla06f.h> #include <nvif/if0004.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_ttm.h" #include "nouveau_gem.h" @@ -315,13 +313,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev, bool boot = false; int ret; - /* - * apple-gmux is needed on dual GPU MacBook Pro - * to probe the panel if we're the inactive GPU. - */ - if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) && - apple_gmux_present() && pdev != vga_default_device() && - !vga_switcheroo_handler_flags()) + if (vga_switcheroo_client_probe_defer(pdev)) return -EPROBE_DEFER; /* remove conflicting drivers (vesafb, efifb etc) */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5c363ed1c842..822a0212cd48 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1,5 +1,5 @@ -#ifndef __NOUVEAU_DRMCLI_H__ -#define __NOUVEAU_DRMCLI_H__ +#ifndef __NOUVEAU_DRV_H__ +#define __NOUVEAU_DRV_H__ #define DRIVER_AUTHOR "Nouveau Project" #define DRIVER_EMAIL "nouveau@lists.freedesktop.org" diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 3bae706126bd..57aaf98a26f9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -43,7 +43,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_gem.h" #include "nouveau_bo.h" #include "nouveau_fbcon.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 9a8c5b727f59..4bb9ab892ae1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -34,7 +34,7 @@ #include <nvif/notify.h> #include <nvif/event.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 185aaaa0c85d..72e2399bce39 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -24,7 +24,7 @@ * */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fence.h" #include "nouveau_abi16.h" @@ -368,7 +368,6 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, int nr_buffers, struct validate_op *op) { struct nouveau_cli *cli = nouveau_cli(file_priv); - struct drm_device *dev = chan->drm->dev; int trycnt = 0; int ret, i; struct nouveau_bo *res_bo = NULL; @@ -388,7 +387,7 @@ retry: struct drm_gem_object *gem; struct nouveau_bo *nvbo; - gem = drm_gem_object_lookup(dev, file_priv, b->handle); + gem = drm_gem_object_lookup(file_priv, b->handle); if (!gem) { NV_PRINTK(err, cli, "Unknown handle 0x%08x\n", b->handle); ret = -ENOENT; @@ -864,7 +863,7 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, bool write = !!(req->flags & NOUVEAU_GEM_CPU_PREP_WRITE); int ret; - gem = drm_gem_object_lookup(dev, file_priv, req->handle); + gem = drm_gem_object_lookup(file_priv, req->handle); if (!gem) return -ENOENT; nvbo = nouveau_gem_object(gem); @@ -896,7 +895,7 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, struct drm_gem_object *gem; struct nouveau_bo *nvbo; - gem = drm_gem_object_lookup(dev, file_priv, req->handle); + gem = drm_gem_object_lookup(file_priv, req->handle); if (!gem) return -ENOENT; nvbo = nouveau_gem_object(gem); @@ -914,7 +913,7 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data, struct drm_gem_object *gem; int ret; - gem = drm_gem_object_lookup(dev, file_priv, req->handle); + gem = drm_gem_object_lookup(file_priv, req->handle); if (!gem) return -ENOENT; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h index e4049faca780..7e32da2e037a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.h +++ b/drivers/gpu/drm/nouveau/nouveau_gem.h @@ -3,7 +3,7 @@ #include <drm/drmP.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_bo.h" #define nouveau_bo_tile_layout(nvbo) \ diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c index 67edd2f5b71a..1ff4166af26e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c @@ -31,7 +31,7 @@ #include <drm/drmP.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_hwmon.h" #include <nvkm/subdev/iccsense.h> @@ -689,7 +689,7 @@ nouveau_hwmon_init(struct drm_device *dev) goto error; } - if (iccsense && iccsense->data_valid && iccsense->rail_count) { + if (iccsense && iccsense->data_valid && !list_empty(&iccsense->rails)) { ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_power_attrgroup); if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_nvif.c b/drivers/gpu/drm/nouveau/nouveau_nvif.c index 55eb942847fa..15f0925ea13b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_nvif.c +++ b/drivers/gpu/drm/nouveau/nouveau_nvif.c @@ -36,7 +36,7 @@ #include <nvif/event.h> #include <nvif/ioctl.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_usif.h" static void diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.h b/drivers/gpu/drm/nouveau/nouveau_platform.h index f41056d0f5f4..a90d72767b8b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.h +++ b/drivers/gpu/drm/nouveau/nouveau_platform.h @@ -21,7 +21,7 @@ */ #ifndef __NOUVEAU_PLATFORM_H__ #define __NOUVEAU_PLATFORM_H__ -#include "nouveau_drm.h" +#include "nouveau_drv.h" extern struct platform_driver nouveau_platform_driver; #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index dd32ad6db53d..a0a9704cfe2b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -25,7 +25,7 @@ #include <drm/drmP.h> #include <linux/dma-buf.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_gem.h" struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *obj) diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 8c3053a177d6..db35ab5883ac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -1,7 +1,7 @@ #include <linux/pagemap.h> #include <linux/slab.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_ttm.h" struct nouveau_sgdma_be { diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index d2e7d209f651..bcee91497eb9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -24,7 +24,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_ttm.h" #include "nouveau_gem.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c index e9f52ef0be83..675e9e077a95 100644 --- a/drivers/gpu/drm/nouveau/nouveau_usif.c +++ b/drivers/gpu/drm/nouveau/nouveau_usif.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_usif.h" #include "nouveau_abi16.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index af89c3665b2a..c6a180a0c284 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -4,7 +4,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_acpi.h" #include "nouveau_fbcon.h" #include "nouveau_vga.h" diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 789dc2993b0d..0f3e4bb411cc 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -22,7 +22,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fbcon.h" diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c index 3022d24ed88b..1915b7b82a59 100644 --- a/drivers/gpu/drm/nouveau/nv04_fence.c +++ b/drivers/gpu/drm/nouveau/nv04_fence.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index 2c35213da275..4e3de34ff6f4 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nv10_fence.h" diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index 6a141c9bf5b7..7d5e562a55c5 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c @@ -26,7 +26,7 @@ #include <nvif/class.h> #include <nvif/cl0002.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nv10_fence.h" diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a43445caae60..3ffc2b0057bf 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -39,7 +39,7 @@ #include <nvif/cl507d.h> #include <nvif/cl507e.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_gem.h" #include "nouveau_connector.h" @@ -1305,7 +1305,6 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = crtc->dev; struct drm_gem_object *gem = NULL; struct nouveau_bo *nvbo = NULL; int ret = 0; @@ -1314,7 +1313,7 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, if (width != 64 || height != 64) return -EINVAL; - gem = drm_gem_object_lookup(dev, file_priv, handle); + gem = drm_gem_object_lookup(file_priv, handle); if (unlikely(!gem)) return -ENOENT; nvbo = nouveau_gem_object(gem); diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index e05499d6ed83..33d9ee0fac40 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fbcon.h" diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index 3695ccce68c7..4d6f202b7770 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -26,7 +26,7 @@ #include <nvif/class.h> #include <nvif/cl0002.h> -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nv10_fence.h" diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index 412c5be5a9ca..18bde9d8e6d6 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index c97395b4a312..a0913359ac05 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fbcon.h" diff --git a/drivers/gpu/drm/nouveau/nvc0_fence.c b/drivers/gpu/drm/nouveau/nvc0_fence.c index becf19abda2d..b79775788bbd 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fence.c +++ b/drivers/gpu/drm/nouveau/nvc0_fence.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nouveau_drm.h" +#include "nouveau_drv.h" #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nvkm/core/engine.c b/drivers/gpu/drm/nouveau/nvkm/core/engine.c index 8a7bae7bd995..ee8e5831fe37 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/engine.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/engine.c @@ -137,11 +137,10 @@ nvkm_engine_func = { int nvkm_engine_ctor(const struct nvkm_engine_func *func, - struct nvkm_device *device, int index, u32 pmc_enable, - bool enable, struct nvkm_engine *engine) + struct nvkm_device *device, int index, bool enable, + struct nvkm_engine *engine) { - nvkm_subdev_ctor(&nvkm_engine_func, device, index, - pmc_enable, &engine->subdev); + nvkm_subdev_ctor(&nvkm_engine_func, device, index, &engine->subdev); engine->func = func; if (!nvkm_boolopt(device->cfgopt, nvkm_subdev_name[index], enable)) { @@ -155,11 +154,10 @@ nvkm_engine_ctor(const struct nvkm_engine_func *func, int nvkm_engine_new_(const struct nvkm_engine_func *func, - struct nvkm_device *device, int index, u32 pmc_enable, - bool enable, struct nvkm_engine **pengine) + struct nvkm_device *device, int index, bool enable, + struct nvkm_engine **pengine) { if (!(*pengine = kzalloc(sizeof(**pengine), GFP_KERNEL))) return -ENOMEM; - return nvkm_engine_ctor(func, device, index, pmc_enable, - enable, *pengine); + return nvkm_engine_ctor(func, device, index, enable, *pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index 3bf08cb1a289..b18557858f19 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -24,6 +24,7 @@ #include <core/subdev.h> #include <core/device.h> #include <core/option.h> +#include <subdev/mc.h> static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR]; @@ -50,6 +51,7 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = { [NVKM_SUBDEV_SECBOOT ] = "secboot", [NVKM_SUBDEV_THERM ] = "therm", [NVKM_SUBDEV_TIMER ] = "tmr", + [NVKM_SUBDEV_TOP ] = "top", [NVKM_SUBDEV_VOLT ] = "volt", [NVKM_ENGINE_BSP ] = "bsp", [NVKM_ENGINE_CE0 ] = "ce0", @@ -89,7 +91,6 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_device *device = subdev->device; const char *action = suspend ? "suspend" : "fini"; - u32 pmc_enable = subdev->pmc_enable; s64 time; nvkm_trace(subdev, "%s running...\n", action); @@ -104,11 +105,7 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend) } } - if (pmc_enable) { - nvkm_mask(device, 0x000200, pmc_enable, 0x00000000); - nvkm_mask(device, 0x000200, pmc_enable, pmc_enable); - nvkm_rd32(device, 0x000200); - } + nvkm_mc_reset(device->mc, subdev->index); time = ktime_to_us(ktime_get()) - time; nvkm_trace(subdev, "%s completed in %lldus\n", action, time); @@ -193,14 +190,13 @@ nvkm_subdev_del(struct nvkm_subdev **psubdev) void nvkm_subdev_ctor(const struct nvkm_subdev_func *func, - struct nvkm_device *device, int index, u32 pmc_enable, + struct nvkm_device *device, int index, struct nvkm_subdev *subdev) { const char *name = nvkm_subdev_name[index]; subdev->func = func; subdev->device = device; subdev->index = index; - subdev->pmc_enable = pmc_enable; __mutex_init(&subdev->mutex, name, &nvkm_subdev_lock_class[index]); subdev->debug = nvkm_dbgopt(device->dbgopt, name); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c index 3ef01071f073..8e2e24a74774 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c @@ -27,7 +27,6 @@ static const struct nvkm_xtensa_func g84_bsp = { - .pmc_enable = 0x04008000, .fifo_val = 0x1111, .unkd28 = 0x90044, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c index 92a9f35df1a6..ad9f855c9a40 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c @@ -40,7 +40,6 @@ gf100_ce0 = { .code.size = sizeof(gf100_ce_code), .data.data = gf100_ce_data, .data.size = sizeof(gf100_ce_data), - .pmc_enable = 0x00000040, .init = gf100_ce_init, .intr = gt215_ce_intr, .sclass = { @@ -55,7 +54,6 @@ gf100_ce1 = { .code.size = sizeof(gf100_ce_code), .data.data = gf100_ce_data, .data.size = sizeof(gf100_ce_data), - .pmc_enable = 0x00000080, .init = gf100_ce_init, .intr = gt215_ce_intr, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c index e2b944dce9b8..9e0b53a10f77 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c @@ -97,17 +97,5 @@ int gk104_ce_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine) { - if (index == NVKM_ENGINE_CE0) { - return nvkm_engine_new_(&gk104_ce, device, index, - 0x00000040, true, pengine); - } else - if (index == NVKM_ENGINE_CE1) { - return nvkm_engine_new_(&gk104_ce, device, index, - 0x00000080, true, pengine); - } else - if (index == NVKM_ENGINE_CE2) { - return nvkm_engine_new_(&gk104_ce, device, index, - 0x00200000, true, pengine); - } - return -ENODEV; + return nvkm_engine_new_(&gk104_ce, device, index, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c index 4c2f42919c1f..c0df7daa85e2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c @@ -39,17 +39,5 @@ int gm107_ce_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine) { - if (index == NVKM_ENGINE_CE0) { - return nvkm_engine_new_(&gm107_ce, device, index, - 0x00000040, true, pengine); - } else - if (index == NVKM_ENGINE_CE1) { - return nvkm_engine_new_(&gm107_ce, device, index, - 0x00000080, true, pengine); - } else - if (index == NVKM_ENGINE_CE2) { - return nvkm_engine_new_(&gm107_ce, device, index, - 0x00200000, true, pengine); - } - return -ENODEV; + return nvkm_engine_new_(&gm107_ce, device, index, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c index 13f07b32cd9c..c6fa8b20737e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c @@ -38,17 +38,5 @@ int gm200_ce_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine) { - if (index == NVKM_ENGINE_CE0) { - return nvkm_engine_new_(&gm200_ce, device, index, - 0x00000040, true, pengine); - } else - if (index == NVKM_ENGINE_CE1) { - return nvkm_engine_new_(&gm200_ce, device, index, - 0x00000080, true, pengine); - } else - if (index == NVKM_ENGINE_CE2) { - return nvkm_engine_new_(&gm200_ce, device, index, - 0x00200000, true, pengine); - } - return -ENODEV; + return nvkm_engine_new_(&gm200_ce, device, index, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c index 402dcbcc2192..63ac51a54fd3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c @@ -67,7 +67,6 @@ gt215_ce = { .code.size = sizeof(gt215_ce_code), .data.data = gt215_ce_data, .data.size = sizeof(gt215_ce_data), - .pmc_enable = 0x00802000, .intr = gt215_ce_intr, .sclass = { { -1, -1, GT212_DMA }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c index bfd01625ec7f..68ffb520531e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c @@ -130,6 +130,5 @@ int g84_cipher_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine) { - return nvkm_engine_new_(&g84_cipher, device, index, - 0x00004000, true, pengine); + return nvkm_engine_new_(&g84_cipher, device, index, true, pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 9f32c8739254..4572debcb0c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -146,7 +146,7 @@ nv11_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv11_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -190,7 +190,7 @@ nv17_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -212,7 +212,7 @@ nv18_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -256,7 +256,7 @@ nv1f_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -278,7 +278,7 @@ nv20_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -300,7 +300,7 @@ nv25_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -322,7 +322,7 @@ nv28_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -344,7 +344,7 @@ nv2a_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -366,7 +366,7 @@ nv30_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -388,7 +388,7 @@ nv31_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -411,7 +411,7 @@ nv34_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -434,7 +434,7 @@ nv35_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -456,7 +456,7 @@ nv36_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv04_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv04_pci_new, .timer = nv04_timer_new, @@ -479,7 +479,7 @@ nv40_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -505,7 +505,7 @@ nv41_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv41_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -531,7 +531,7 @@ nv42_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv41_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -557,7 +557,7 @@ nv43_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv41_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -609,7 +609,7 @@ nv45_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv04_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -661,7 +661,7 @@ nv47_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv41_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -687,7 +687,7 @@ nv49_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv41_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -739,7 +739,7 @@ nv4b_chipset = { .gpio = nv10_gpio_new, .i2c = nv04_i2c_new, .imem = nv40_instmem_new, - .mc = nv04_mc_new, + .mc = nv17_mc_new, .mmu = nv41_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, @@ -926,7 +926,7 @@ nv84_chipset = { .gpio = nv50_gpio_new, .i2c = nv50_i2c_new, .imem = nv50_instmem_new, - .mc = nv50_mc_new, + .mc = g84_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g84_pci_new, @@ -958,7 +958,7 @@ nv86_chipset = { .gpio = nv50_gpio_new, .i2c = nv50_i2c_new, .imem = nv50_instmem_new, - .mc = nv50_mc_new, + .mc = g84_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g84_pci_new, @@ -990,7 +990,7 @@ nv92_chipset = { .gpio = nv50_gpio_new, .i2c = nv50_i2c_new, .imem = nv50_instmem_new, - .mc = nv50_mc_new, + .mc = g84_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g84_pci_new, @@ -1022,7 +1022,7 @@ nv94_chipset = { .gpio = g94_gpio_new, .i2c = g94_i2c_new, .imem = nv50_instmem_new, - .mc = nv50_mc_new, + .mc = g84_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, @@ -1054,7 +1054,7 @@ nv96_chipset = { .gpio = g94_gpio_new, .i2c = g94_i2c_new, .imem = nv50_instmem_new, - .mc = nv50_mc_new, + .mc = g84_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, @@ -1118,7 +1118,7 @@ nva0_chipset = { .gpio = g94_gpio_new, .i2c = nv50_i2c_new, .imem = nv50_instmem_new, - .mc = g98_mc_new, + .mc = g84_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, @@ -1150,7 +1150,7 @@ nva3_chipset = { .gpio = g94_gpio_new, .i2c = g94_i2c_new, .imem = nv50_instmem_new, - .mc = g98_mc_new, + .mc = gt215_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, @@ -1184,7 +1184,7 @@ nva5_chipset = { .gpio = g94_gpio_new, .i2c = g94_i2c_new, .imem = nv50_instmem_new, - .mc = g98_mc_new, + .mc = gt215_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, @@ -1217,7 +1217,7 @@ nva8_chipset = { .gpio = g94_gpio_new, .i2c = g94_i2c_new, .imem = nv50_instmem_new, - .mc = g98_mc_new, + .mc = gt215_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, @@ -1314,7 +1314,7 @@ nvaf_chipset = { .gpio = g94_gpio_new, .i2c = g94_i2c_new, .imem = nv50_instmem_new, - .mc = g98_mc_new, + .mc = gt215_mc_new, .mmu = nv50_mmu_new, .mxm = nv50_mxm_new, .pci = g94_pci_new, @@ -1676,13 +1676,14 @@ nve4_chipset = { .iccsense = gf100_iccsense_new, .imem = nv50_instmem_new, .ltc = gk104_ltc_new, - .mc = gf100_mc_new, + .mc = gk104_mc_new, .mmu = gf100_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk104_pmu_new, .therm = gf119_therm_new, .timer = nv41_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gk104_ce_new, .ce[1] = gk104_ce_new, @@ -1714,13 +1715,14 @@ nve6_chipset = { .iccsense = gf100_iccsense_new, .imem = nv50_instmem_new, .ltc = gk104_ltc_new, - .mc = gf100_mc_new, + .mc = gk104_mc_new, .mmu = gf100_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk104_pmu_new, .therm = gf119_therm_new, .timer = nv41_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gk104_ce_new, .ce[1] = gk104_ce_new, @@ -1752,13 +1754,14 @@ nve7_chipset = { .iccsense = gf100_iccsense_new, .imem = nv50_instmem_new, .ltc = gk104_ltc_new, - .mc = gf100_mc_new, + .mc = gk104_mc_new, .mmu = gf100_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk104_pmu_new, .therm = gf119_therm_new, .timer = nv41_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gk104_ce_new, .ce[1] = gk104_ce_new, @@ -1789,6 +1792,7 @@ nvea_chipset = { .mmu = gf100_mmu_new, .pmu = gk20a_pmu_new, .timer = gk20a_timer_new, + .top = gk104_top_new, .volt = gk20a_volt_new, .ce[2] = gk104_ce_new, .dma = gf119_dma_new, @@ -1814,13 +1818,14 @@ nvf0_chipset = { .iccsense = gf100_iccsense_new, .imem = nv50_instmem_new, .ltc = gk104_ltc_new, - .mc = gf100_mc_new, + .mc = gk104_mc_new, .mmu = gf100_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk110_pmu_new, .therm = gf119_therm_new, .timer = nv41_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gk104_ce_new, .ce[1] = gk104_ce_new, @@ -1851,13 +1856,14 @@ nvf1_chipset = { .iccsense = gf100_iccsense_new, .imem = nv50_instmem_new, .ltc = gk104_ltc_new, - .mc = gf100_mc_new, + .mc = gk104_mc_new, .mmu = gf100_mmu_new, .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gk110_pmu_new, .therm = gf119_therm_new, .timer = nv41_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gk104_ce_new, .ce[1] = gk104_ce_new, @@ -1895,6 +1901,7 @@ nv106_chipset = { .pmu = gk208_pmu_new, .therm = gf119_therm_new, .timer = nv41_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gk104_ce_new, .ce[1] = gk104_ce_new, @@ -1932,6 +1939,7 @@ nv108_chipset = { .pmu = gk208_pmu_new, .therm = gf119_therm_new, .timer = nv41_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gk104_ce_new, .ce[1] = gk104_ce_new, @@ -1969,6 +1977,41 @@ nv117_chipset = { .pmu = gm107_pmu_new, .therm = gm107_therm_new, .timer = gk20a_timer_new, + .top = gk104_top_new, + .volt = gk104_volt_new, + .ce[0] = gm107_ce_new, + .ce[2] = gm107_ce_new, + .disp = gm107_disp_new, + .dma = gf119_dma_new, + .fifo = gm107_fifo_new, + .gr = gm107_gr_new, + .sw = gf100_sw_new, +}; + +static const struct nvkm_device_chip +nv118_chipset = { + .name = "GM108", + .bar = gf100_bar_new, + .bios = nvkm_bios_new, + .bus = gf100_bus_new, + .clk = gk104_clk_new, + .devinit = gm107_devinit_new, + .fb = gm107_fb_new, + .fuse = gm107_fuse_new, + .gpio = gk104_gpio_new, + .i2c = gf119_i2c_new, + .ibus = gk104_ibus_new, + .iccsense = gf100_iccsense_new, + .imem = nv50_instmem_new, + .ltc = gm107_ltc_new, + .mc = gk20a_mc_new, + .mmu = gf100_mmu_new, + .mxm = nv50_mxm_new, + .pci = gk104_pci_new, + .pmu = gm107_pmu_new, + .therm = gm107_therm_new, + .timer = gk20a_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gm107_ce_new, .ce[2] = gm107_ce_new, @@ -1986,7 +2029,7 @@ nv120_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, - .fb = gm107_fb_new, + .fb = gm200_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, .i2c = gm200_i2c_new, @@ -2001,6 +2044,7 @@ nv120_chipset = { .pmu = gm107_pmu_new, .secboot = gm200_secboot_new, .timer = gk20a_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gm200_ce_new, .ce[1] = gm200_ce_new, @@ -2019,7 +2063,7 @@ nv124_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, - .fb = gm107_fb_new, + .fb = gm200_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, .i2c = gm200_i2c_new, @@ -2034,6 +2078,7 @@ nv124_chipset = { .pmu = gm107_pmu_new, .secboot = gm200_secboot_new, .timer = gk20a_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gm200_ce_new, .ce[1] = gm200_ce_new, @@ -2052,7 +2097,7 @@ nv126_chipset = { .bios = nvkm_bios_new, .bus = gf100_bus_new, .devinit = gm200_devinit_new, - .fb = gm107_fb_new, + .fb = gm200_fb_new, .fuse = gm107_fuse_new, .gpio = gk104_gpio_new, .i2c = gm200_i2c_new, @@ -2067,6 +2112,7 @@ nv126_chipset = { .pmu = gm107_pmu_new, .secboot = gm200_secboot_new, .timer = gk20a_timer_new, + .top = gk104_top_new, .volt = gk104_volt_new, .ce[0] = gm200_ce_new, .ce[1] = gm200_ce_new, @@ -2093,6 +2139,7 @@ nv12b_chipset = { .mmu = gf100_mmu_new, .secboot = gm20b_secboot_new, .timer = gk20a_timer_new, + .top = gk104_top_new, .ce[2] = gm200_ce_new, .volt = gm20b_volt_new, .dma = gf119_dma_new, @@ -2150,6 +2197,7 @@ nvkm_device_subdev(struct nvkm_device *device, int index) _(SECBOOT , device->secboot , &device->secboot->subdev); _(THERM , device->therm , &device->therm->subdev); _(TIMER , device->timer , &device->timer->subdev); + _(TOP , device->top , &device->top->subdev); _(VOLT , device->volt , &device->volt->subdev); #undef _ default: @@ -2523,6 +2571,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x106: device->chip = &nv106_chipset; break; case 0x108: device->chip = &nv108_chipset; break; case 0x117: device->chip = &nv117_chipset; break; + case 0x118: device->chip = &nv118_chipset; break; case 0x120: device->chip = &nv120_chipset; break; case 0x124: device->chip = &nv124_chipset; break; case 0x126: device->chip = &nv126_chipset; break; @@ -2604,6 +2653,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, _(NVKM_SUBDEV_SECBOOT , secboot); _(NVKM_SUBDEV_THERM , therm); _(NVKM_SUBDEV_TIMER , timer); + _(NVKM_SUBDEV_TOP , top); _(NVKM_SUBDEV_VOLT , volt); _(NVKM_ENGINE_BSP , bsp); _(NVKM_ENGINE_CE0 , ce[0]); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h index e80f6ab1c415..1a06ac175f55 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h @@ -22,6 +22,7 @@ #include <subdev/pmu.h> #include <subdev/therm.h> #include <subdev/timer.h> +#include <subdev/top.h> #include <subdev/volt.h> #include <subdev/secboot.h> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c index 785fa76d0fbf..1efe91b1e22b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c @@ -298,8 +298,7 @@ nvkm_disp_ctor(const struct nvkm_disp_func *func, struct nvkm_device *device, disp->func = func; disp->head.nr = heads; - ret = nvkm_engine_ctor(&nvkm_disp, device, index, 0, - true, &disp->engine); + ret = nvkm_engine_ctor(&nvkm_disp, device, index, true, &disp->engine); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c index 9769fc0d5351..f11ebdd16c77 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c @@ -152,6 +152,5 @@ nvkm_dma_new_(const struct nvkm_dma_func *func, struct nvkm_device *device, return -ENOMEM; dma->func = func; - return nvkm_engine_ctor(&nvkm_dma, device, index, - 0, true, &dma->engine); + return nvkm_engine_ctor(&nvkm_dma, device, index, true, &dma->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c index 74000602fbb1..2e7b4e2105ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c @@ -348,6 +348,6 @@ nvkm_falcon_new_(const struct nvkm_falcon_func *func, falcon->data.size = func->data.size; *pengine = &falcon->engine; - return nvkm_engine_ctor(&nvkm_falcon, device, index, func->pmc_enable, + return nvkm_engine_ctor(&nvkm_falcon, device, index, enable, &falcon->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index cfc7d5725a61..1c9682ae3a6b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -178,6 +178,17 @@ nvkm_fifo_class_get(struct nvkm_oclass *oclass, int index, const struct nvkm_fifo_chan_oclass *sclass; int c = 0; + if (fifo->func->class_get) { + int ret = fifo->func->class_get(fifo, index, &sclass); + if (ret == 0) { + oclass->base = sclass->base; + oclass->engn = sclass; + *class = &nvkm_fifo_class; + return 0; + } + return ret; + } + while ((sclass = fifo->func->chan[c])) { if (c++ == index) { oclass->base = sclass->base; @@ -261,8 +272,7 @@ nvkm_fifo_ctor(const struct nvkm_fifo_func *func, struct nvkm_device *device, fifo->nr = nr; bitmap_clear(fifo->mask, 0, fifo->nr); - ret = nvkm_engine_ctor(&nvkm_fifo, device, index, 0x00000100, - true, &fifo->engine); + ret = nvkm_engine_ctor(&nvkm_fifo, device, index, true, &fifo->engine); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 68acb36b3e6d..743f3a189f28 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -25,21 +25,36 @@ #include "changk104.h" #include <core/client.h> -#include <core/enum.h> #include <core/gpuobj.h> #include <subdev/bar.h> +#include <subdev/top.h> #include <engine/sw.h> #include <nvif/class.h> -void +static int +gk104_fifo_class_get(struct nvkm_fifo *base, int index, + const struct nvkm_fifo_chan_oclass **psclass) +{ + struct gk104_fifo *fifo = gk104_fifo(base); + int c = 0; + + while ((*psclass = fifo->func->chan[c])) { + if (c++ == index) + return 0; + } + + return c; +} + +static void gk104_fifo_uevent_fini(struct nvkm_fifo *fifo) { struct nvkm_device *device = fifo->engine.subdev.device; nvkm_mask(device, 0x002140, 0x80000000, 0x00000000); } -void +static void gk104_fifo_uevent_init(struct nvkm_fifo *fifo) { struct nvkm_device *device = fifo->engine.subdev.device; @@ -267,111 +282,6 @@ gk104_fifo_intr_dropped_fault(struct gk104_fifo *fifo) nvkm_error(subdev, "DROPPED_MMU_FAULT %08x\n", stat); } -static const struct nvkm_enum -gk104_fifo_fault_engine[] = { - { 0x00, "GR", NULL, NVKM_ENGINE_GR }, - { 0x03, "IFB", NULL, NVKM_ENGINE_IFB }, - { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, - { 0x05, "BAR3", NULL, NVKM_SUBDEV_INSTMEM }, - { 0x07, "PBDMA0", NULL, NVKM_ENGINE_FIFO }, - { 0x08, "PBDMA1", NULL, NVKM_ENGINE_FIFO }, - { 0x09, "PBDMA2", NULL, NVKM_ENGINE_FIFO }, - { 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD }, - { 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP }, - { 0x13, "PERF" }, - { 0x14, "MSPDEC", NULL, NVKM_ENGINE_MSPDEC }, - { 0x15, "CE0", NULL, NVKM_ENGINE_CE0 }, - { 0x16, "CE1", NULL, NVKM_ENGINE_CE1 }, - { 0x17, "PMU" }, - { 0x19, "MSENC", NULL, NVKM_ENGINE_MSENC }, - { 0x1b, "CE2", NULL, NVKM_ENGINE_CE2 }, - {} -}; - -static const struct nvkm_enum -gk104_fifo_fault_reason[] = { - { 0x00, "PDE" }, - { 0x01, "PDE_SIZE" }, - { 0x02, "PTE" }, - { 0x03, "VA_LIMIT_VIOLATION" }, - { 0x04, "UNBOUND_INST_BLOCK" }, - { 0x05, "PRIV_VIOLATION" }, - { 0x06, "RO_VIOLATION" }, - { 0x07, "WO_VIOLATION" }, - { 0x08, "PITCH_MASK_VIOLATION" }, - { 0x09, "WORK_CREATION" }, - { 0x0a, "UNSUPPORTED_APERTURE" }, - { 0x0b, "COMPRESSION_FAILURE" }, - { 0x0c, "UNSUPPORTED_KIND" }, - { 0x0d, "REGION_VIOLATION" }, - { 0x0e, "BOTH_PTES_VALID" }, - { 0x0f, "INFO_TYPE_POISONED" }, - {} -}; - -static const struct nvkm_enum -gk104_fifo_fault_hubclient[] = { - { 0x00, "VIP" }, - { 0x01, "CE0" }, - { 0x02, "CE1" }, - { 0x03, "DNISO" }, - { 0x04, "FE" }, - { 0x05, "FECS" }, - { 0x06, "HOST" }, - { 0x07, "HOST_CPU" }, - { 0x08, "HOST_CPU_NB" }, - { 0x09, "ISO" }, - { 0x0a, "MMU" }, - { 0x0b, "MSPDEC" }, - { 0x0c, "MSPPP" }, - { 0x0d, "MSVLD" }, - { 0x0e, "NISO" }, - { 0x0f, "P2P" }, - { 0x10, "PD" }, - { 0x11, "PERF" }, - { 0x12, "PMU" }, - { 0x13, "RASTERTWOD" }, - { 0x14, "SCC" }, - { 0x15, "SCC_NB" }, - { 0x16, "SEC" }, - { 0x17, "SSYNC" }, - { 0x18, "GR_CE" }, - { 0x19, "CE2" }, - { 0x1a, "XV" }, - { 0x1b, "MMU_NB" }, - { 0x1c, "MSENC" }, - { 0x1d, "DFALCON" }, - { 0x1e, "SKED" }, - { 0x1f, "AFALCON" }, - {} -}; - -static const struct nvkm_enum -gk104_fifo_fault_gpcclient[] = { - { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" }, - { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" }, - { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" }, - { 0x09, "L1_3" }, { 0x0a, "T1_3" }, { 0x0b, "PE_3" }, - { 0x0c, "RAST" }, - { 0x0d, "GCC" }, - { 0x0e, "GPCCS" }, - { 0x0f, "PROP_0" }, - { 0x10, "PROP_1" }, - { 0x11, "PROP_2" }, - { 0x12, "PROP_3" }, - { 0x13, "L1_4" }, { 0x14, "T1_4" }, { 0x15, "PE_4" }, - { 0x16, "L1_5" }, { 0x17, "T1_5" }, { 0x18, "PE_5" }, - { 0x19, "L1_6" }, { 0x1a, "T1_6" }, { 0x1b, "PE_6" }, - { 0x1c, "L1_7" }, { 0x1d, "T1_7" }, { 0x1e, "PE_7" }, - { 0x1f, "GPM" }, - { 0x20, "LTP_UTLB_0" }, - { 0x21, "LTP_UTLB_1" }, - { 0x22, "LTP_UTLB_2" }, - { 0x23, "LTP_UTLB_3" }, - { 0x24, "GPC_RGG_UTLB" }, - {} -}; - static void gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) { @@ -390,14 +300,14 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) struct nvkm_engine *engine = NULL; struct nvkm_fifo_chan *chan; unsigned long flags; - char gpcid[8] = ""; + char gpcid[8] = "", en[16] = ""; - er = nvkm_enum_find(gk104_fifo_fault_reason, reason); - eu = nvkm_enum_find(gk104_fifo_fault_engine, unit); + er = nvkm_enum_find(fifo->func->fault.reason, reason); + eu = nvkm_enum_find(fifo->func->fault.engine, unit); if (hub) { - ec = nvkm_enum_find(gk104_fifo_fault_hubclient, client); + ec = nvkm_enum_find(fifo->func->fault.hubclient, client); } else { - ec = nvkm_enum_find(gk104_fifo_fault_gpcclient, client); + ec = nvkm_enum_find(fifo->func->fault.gpcclient, client); snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc); } @@ -418,13 +328,27 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) } } + if (eu == NULL) { + enum nvkm_devidx engidx = nvkm_top_fault(device->top, unit); + if (engidx < NVKM_SUBDEV_NR) { + const char *src = nvkm_subdev_name[engidx]; + char *dst = en; + do { + *dst++ = toupper(*src++); + } while(*src); + engine = nvkm_device_engine(device, engidx); + } + } else { + snprintf(en, sizeof(en), "%s", eu->name); + } + chan = nvkm_fifo_chan_inst(&fifo->base, (u64)inst << 12, &flags); nvkm_error(subdev, "%s fault at %010llx engine %02x [%s] client %02x [%s%s] " "reason %02x [%s] on channel %d [%010llx %s]\n", write ? "write" : "read", (u64)vahi << 32 | valo, - unit, eu ? eu->name : "", client, gpcid, ec ? ec->name : "", + unit, en, client, gpcid, ec ? ec->name : "", reason, er ? er->name : "", chan ? chan->chid : -1, (u64)inst << 12, chan ? chan->object.client->name : "unknown"); @@ -557,7 +481,7 @@ gk104_fifo_intr_engine(struct gk104_fifo *fifo) nvkm_fifo_uevent(&fifo->base); } -void +static void gk104_fifo_intr(struct nvkm_fifo *base) { struct gk104_fifo *fifo = gk104_fifo(base); @@ -649,7 +573,7 @@ gk104_fifo_intr(struct nvkm_fifo *base) } } -void +static void gk104_fifo_fini(struct nvkm_fifo *base) { struct gk104_fifo *fifo = gk104_fifo(base); @@ -659,13 +583,15 @@ gk104_fifo_fini(struct nvkm_fifo *base) nvkm_mask(device, 0x002140, 0x10000000, 0x10000000); } -int +static int gk104_fifo_oneinit(struct nvkm_fifo *base) { struct gk104_fifo *fifo = gk104_fifo(base); struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; - int ret, i; + struct nvkm_top *top = device->top; + int engn, runl, pbid, ret, i, j; + enum nvkm_devidx engidx; u32 *map; /* Determine number of PBDMAs by checking valid enable bits. */ @@ -680,86 +606,26 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) for (i = 0; i < fifo->pbdma_nr; i++) map[i] = nvkm_rd32(device, 0x002390 + (i * 0x04)); - /* Read device topology from HW. */ - for (i = 0; i < 64; i++) { - int type = -1, pbid = -1, engidx = -1; - int engn = -1, runl = -1, intr = -1, mcen = -1; - int fault = -1, j; - u32 data, addr = 0; - - do { - data = nvkm_rd32(device, 0x022700 + (i * 0x04)); - nvkm_trace(subdev, "%02x: %08x\n", i, data); - switch (data & 0x00000003) { - case 0x00000000: /* NOT_VALID */ - continue; - case 0x00000001: /* DATA */ - addr = (data & 0x00fff000); - fault = (data & 0x000000f8) >> 3; - break; - case 0x00000002: /* ENUM */ - if (data & 0x00000020) - engn = (data & 0x3c000000) >> 26; - if (data & 0x00000010) - runl = (data & 0x01e00000) >> 21; - if (data & 0x00000008) - intr = (data & 0x000f8000) >> 15; - if (data & 0x00000004) - mcen = (data & 0x00003e00) >> 9; - break; - case 0x00000003: /* ENGINE_TYPE */ - type = (data & 0x7ffffffc) >> 2; - break; - } - } while ((data & 0x80000000) && ++i < 64); - - if (!data) - continue; - + /* Determine runlist configuration from topology device info. */ + i = 0; + while ((int)(engidx = nvkm_top_engine(top, i++, &runl, &engn)) >= 0) { /* Determine which PBDMA handles requests for this engine. */ - for (j = 0; runl >= 0 && j < fifo->pbdma_nr; j++) { + for (j = 0, pbid = -1; j < fifo->pbdma_nr; j++) { if (map[j] & (1 << runl)) { pbid = j; break; } } - /* Translate engine type to NVKM engine identifier. */ - switch (type) { - case 0x00000000: engidx = NVKM_ENGINE_GR; break; - case 0x00000001: engidx = NVKM_ENGINE_CE0; break; - case 0x00000002: engidx = NVKM_ENGINE_CE1; break; - case 0x00000003: engidx = NVKM_ENGINE_CE2; break; - case 0x00000008: engidx = NVKM_ENGINE_MSPDEC; break; - case 0x00000009: engidx = NVKM_ENGINE_MSPPP; break; - case 0x0000000a: engidx = NVKM_ENGINE_MSVLD; break; - case 0x0000000b: engidx = NVKM_ENGINE_MSENC; break; - case 0x0000000c: engidx = NVKM_ENGINE_VIC; break; - case 0x0000000d: engidx = NVKM_ENGINE_SEC; break; - case 0x0000000e: engidx = NVKM_ENGINE_NVENC0; break; - case 0x0000000f: engidx = NVKM_ENGINE_NVENC1; break; - case 0x00000010: engidx = NVKM_ENGINE_NVDEC; break; - break; - default: - break; - } + nvkm_debug(subdev, "engine %2d: runlist %2d pbdma %2d\n", + engn, runl, pbid); - nvkm_debug(subdev, "%02x (%8s): engine %2d runlist %2d " - "pbdma %2d intr %2d reset %2d " - "fault %2d addr %06x\n", type, - engidx < 0 ? NULL : nvkm_subdev_name[engidx], - engn, runl, pbid, intr, mcen, fault, addr); - - /* Mark the engine as supported if everything checks out. */ - if (engn >= 0 && runl >= 0) { - fifo->engine[engn].engine = engidx < 0 ? NULL : - nvkm_device_engine(device, engidx); - fifo->engine[engn].runl = runl; - fifo->engine[engn].pbid = pbid; - fifo->engine_nr = max(fifo->engine_nr, engn + 1); - fifo->runlist[runl].engm |= 1 << engn; - fifo->runlist_nr = max(fifo->runlist_nr, runl + 1); - } + fifo->engine[engn].engine = nvkm_device_engine(device, engidx); + fifo->engine[engn].runl = runl; + fifo->engine[engn].pbid = pbid; + fifo->engine_nr = max(fifo->engine_nr, engn + 1); + fifo->runlist[runl].engm |= 1 << engn; + fifo->runlist_nr = max(fifo->runlist_nr, runl + 1); } kfree(map); @@ -796,7 +662,7 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) return 0; } -void +static void gk104_fifo_init(struct nvkm_fifo *base) { struct gk104_fifo *fifo = gk104_fifo(base); @@ -825,7 +691,7 @@ gk104_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, 0x002140, 0x7fffffff); } -void * +static void * gk104_fifo_dtor(struct nvkm_fifo *base) { struct gk104_fifo *fifo = gk104_fifo(base); @@ -842,29 +708,154 @@ gk104_fifo_dtor(struct nvkm_fifo *base) return fifo; } +static const struct nvkm_fifo_func +gk104_fifo_ = { + .dtor = gk104_fifo_dtor, + .oneinit = gk104_fifo_oneinit, + .init = gk104_fifo_init, + .fini = gk104_fifo_fini, + .intr = gk104_fifo_intr, + .uevent_init = gk104_fifo_uevent_init, + .uevent_fini = gk104_fifo_uevent_fini, + .class_get = gk104_fifo_class_get, +}; + int -gk104_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device, +gk104_fifo_new_(const struct gk104_fifo_func *func, struct nvkm_device *device, int index, int nr, struct nvkm_fifo **pfifo) { struct gk104_fifo *fifo; if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL))) return -ENOMEM; + fifo->func = func; INIT_WORK(&fifo->recover.work, gk104_fifo_recover_work); *pfifo = &fifo->base; - return nvkm_fifo_ctor(func, device, index, nr, &fifo->base); + return nvkm_fifo_ctor(&gk104_fifo_, device, index, nr, &fifo->base); } -static const struct nvkm_fifo_func +const struct nvkm_enum +gk104_fifo_fault_engine[] = { + { 0x00, "GR", NULL, NVKM_ENGINE_GR }, + { 0x01, "DISPLAY" }, + { 0x02, "CAPTURE" }, + { 0x03, "IFB", NULL, NVKM_ENGINE_IFB }, + { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, + { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, + { 0x06, "SCHED" }, + { 0x07, "HOST0" }, + { 0x08, "HOST1" }, + { 0x09, "HOST2" }, + { 0x0a, "HOST3" }, + { 0x0b, "HOST4" }, + { 0x0c, "HOST5" }, + { 0x0d, "HOST6" }, + { 0x0e, "HOST7" }, + { 0x0f, "HOSTSR" }, + { 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD }, + { 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP }, + { 0x13, "PERF" }, + { 0x14, "MSPDEC", NULL, NVKM_ENGINE_MSPDEC }, + { 0x15, "CE0", NULL, NVKM_ENGINE_CE0 }, + { 0x16, "CE1", NULL, NVKM_ENGINE_CE1 }, + { 0x17, "PMU" }, + { 0x18, "PTP" }, + { 0x19, "MSENC", NULL, NVKM_ENGINE_MSENC }, + { 0x1b, "CE2", NULL, NVKM_ENGINE_CE2 }, + {} +}; + +const struct nvkm_enum +gk104_fifo_fault_reason[] = { + { 0x00, "PDE" }, + { 0x01, "PDE_SIZE" }, + { 0x02, "PTE" }, + { 0x03, "VA_LIMIT_VIOLATION" }, + { 0x04, "UNBOUND_INST_BLOCK" }, + { 0x05, "PRIV_VIOLATION" }, + { 0x06, "RO_VIOLATION" }, + { 0x07, "WO_VIOLATION" }, + { 0x08, "PITCH_MASK_VIOLATION" }, + { 0x09, "WORK_CREATION" }, + { 0x0a, "UNSUPPORTED_APERTURE" }, + { 0x0b, "COMPRESSION_FAILURE" }, + { 0x0c, "UNSUPPORTED_KIND" }, + { 0x0d, "REGION_VIOLATION" }, + { 0x0e, "BOTH_PTES_VALID" }, + { 0x0f, "INFO_TYPE_POISONED" }, + {} +}; + +const struct nvkm_enum +gk104_fifo_fault_hubclient[] = { + { 0x00, "VIP" }, + { 0x01, "CE0" }, + { 0x02, "CE1" }, + { 0x03, "DNISO" }, + { 0x04, "FE" }, + { 0x05, "FECS" }, + { 0x06, "HOST" }, + { 0x07, "HOST_CPU" }, + { 0x08, "HOST_CPU_NB" }, + { 0x09, "ISO" }, + { 0x0a, "MMU" }, + { 0x0b, "MSPDEC" }, + { 0x0c, "MSPPP" }, + { 0x0d, "MSVLD" }, + { 0x0e, "NISO" }, + { 0x0f, "P2P" }, + { 0x10, "PD" }, + { 0x11, "PERF" }, + { 0x12, "PMU" }, + { 0x13, "RASTERTWOD" }, + { 0x14, "SCC" }, + { 0x15, "SCC_NB" }, + { 0x16, "SEC" }, + { 0x17, "SSYNC" }, + { 0x18, "GR_CE" }, + { 0x19, "CE2" }, + { 0x1a, "XV" }, + { 0x1b, "MMU_NB" }, + { 0x1c, "MSENC" }, + { 0x1d, "DFALCON" }, + { 0x1e, "SKED" }, + { 0x1f, "AFALCON" }, + {} +}; + +const struct nvkm_enum +gk104_fifo_fault_gpcclient[] = { + { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" }, + { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" }, + { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" }, + { 0x09, "L1_3" }, { 0x0a, "T1_3" }, { 0x0b, "PE_3" }, + { 0x0c, "RAST" }, + { 0x0d, "GCC" }, + { 0x0e, "GPCCS" }, + { 0x0f, "PROP_0" }, + { 0x10, "PROP_1" }, + { 0x11, "PROP_2" }, + { 0x12, "PROP_3" }, + { 0x13, "L1_4" }, { 0x14, "T1_4" }, { 0x15, "PE_4" }, + { 0x16, "L1_5" }, { 0x17, "T1_5" }, { 0x18, "PE_5" }, + { 0x19, "L1_6" }, { 0x1a, "T1_6" }, { 0x1b, "PE_6" }, + { 0x1c, "L1_7" }, { 0x1d, "T1_7" }, { 0x1e, "PE_7" }, + { 0x1f, "GPM" }, + { 0x20, "LTP_UTLB_0" }, + { 0x21, "LTP_UTLB_1" }, + { 0x22, "LTP_UTLB_2" }, + { 0x23, "LTP_UTLB_3" }, + { 0x24, "GPC_RGG_UTLB" }, + {} +}; + +static const struct gk104_fifo_func gk104_fifo = { - .dtor = gk104_fifo_dtor, - .oneinit = gk104_fifo_oneinit, - .init = gk104_fifo_init, - .fini = gk104_fifo_fini, - .intr = gk104_fifo_intr, - .uevent_init = gk104_fifo_uevent_init, - .uevent_fini = gk104_fifo_uevent_fini, + .fault.engine = gk104_fifo_fault_engine, + .fault.reason = gk104_fifo_fault_reason, + .fault.hubclient = gk104_fifo_fault_hubclient, + .fault.gpcclient = gk104_fifo_fault_gpcclient, .chan = { &gk104_fifo_gpfifo_oclass, NULL diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 9e5d00ba34a2..679f3ec311e9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -3,10 +3,12 @@ #define gk104_fifo(p) container_of((p), struct gk104_fifo, base) #include "priv.h" +#include <core/enum.h> #include <subdev/mmu.h> struct gk104_fifo_chan; struct gk104_fifo { + const struct gk104_fifo_func *func; struct nvkm_fifo base; struct { @@ -39,15 +41,19 @@ struct gk104_fifo { } user; }; -int gk104_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *, +struct gk104_fifo_func { + struct { + const struct nvkm_enum *engine; + const struct nvkm_enum *reason; + const struct nvkm_enum *hubclient; + const struct nvkm_enum *gpcclient; + } fault; + + const struct nvkm_fifo_chan_oclass *chan[]; +}; + +int gk104_fifo_new_(const struct gk104_fifo_func *, struct nvkm_device *, int index, int nr, struct nvkm_fifo **); -void *gk104_fifo_dtor(struct nvkm_fifo *); -int gk104_fifo_oneinit(struct nvkm_fifo *); -void gk104_fifo_init(struct nvkm_fifo *); -void gk104_fifo_fini(struct nvkm_fifo *); -void gk104_fifo_intr(struct nvkm_fifo *); -void gk104_fifo_uevent_init(struct nvkm_fifo *); -void gk104_fifo_uevent_fini(struct nvkm_fifo *); void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl); @@ -70,4 +76,11 @@ gk104_fifo_engine_subdev(int engine) return 0; } } + +extern const struct nvkm_enum gk104_fifo_fault_engine[]; +extern const struct nvkm_enum gk104_fifo_fault_reason[]; +extern const struct nvkm_enum gk104_fifo_fault_hubclient[]; +extern const struct nvkm_enum gk104_fifo_fault_gpcclient[]; + +extern const struct nvkm_enum gm107_fifo_fault_engine[]; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index 41307fcd4bb3..b2f8ab7bf847 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -24,15 +24,12 @@ #include "gk104.h" #include "changk104.h" -static const struct nvkm_fifo_func +static const struct gk104_fifo_func gk110_fifo = { - .dtor = gk104_fifo_dtor, - .oneinit = gk104_fifo_oneinit, - .init = gk104_fifo_init, - .fini = gk104_fifo_fini, - .intr = gk104_fifo_intr, - .uevent_init = gk104_fifo_uevent_init, - .uevent_fini = gk104_fifo_uevent_fini, + .fault.engine = gk104_fifo_fault_engine, + .fault.reason = gk104_fifo_fault_reason, + .fault.hubclient = gk104_fifo_fault_hubclient, + .fault.gpcclient = gk104_fifo_fault_gpcclient, .chan = { &gk110_fifo_gpfifo_oclass, NULL diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index ce01c1a7d41c..160617d376e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -24,15 +24,12 @@ #include "gk104.h" #include "changk104.h" -static const struct nvkm_fifo_func +static const struct gk104_fifo_func gk208_fifo = { - .dtor = gk104_fifo_dtor, - .oneinit = gk104_fifo_oneinit, - .init = gk104_fifo_init, - .fini = gk104_fifo_fini, - .intr = gk104_fifo_intr, - .uevent_init = gk104_fifo_uevent_init, - .uevent_fini = gk104_fifo_uevent_fini, + .fault.engine = gk104_fifo_fault_engine, + .fault.reason = gk104_fifo_fault_reason, + .fault.hubclient = gk104_fifo_fault_hubclient, + .fault.gpcclient = gk104_fifo_fault_gpcclient, .chan = { &gk104_fifo_gpfifo_oclass, NULL diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c index b47fe98f4181..be9f5c16ed7d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c @@ -22,15 +22,12 @@ #include "gk104.h" #include "changk104.h" -static const struct nvkm_fifo_func +static const struct gk104_fifo_func gk20a_fifo = { - .dtor = gk104_fifo_dtor, - .oneinit = gk104_fifo_oneinit, - .init = gk104_fifo_init, - .fini = gk104_fifo_fini, - .intr = gk104_fifo_intr, - .uevent_init = gk104_fifo_uevent_init, - .uevent_fini = gk104_fifo_uevent_fini, + .fault.engine = gk104_fifo_fault_engine, + .fault.reason = gk104_fifo_fault_reason, + .fault.hubclient = gk104_fifo_fault_hubclient, + .fault.gpcclient = gk104_fifo_fault_gpcclient, .chan = { &gk104_fifo_gpfifo_oclass, NULL diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index 6d59d65794a1..bd1ff877aa06 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -24,15 +24,35 @@ #include "gk104.h" #include "changk104.h" -static const struct nvkm_fifo_func +const struct nvkm_enum +gm107_fifo_fault_engine[] = { + { 0x01, "DISPLAY" }, + { 0x02, "CAPTURE" }, + { 0x03, "IFB", NULL, NVKM_ENGINE_IFB }, + { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, + { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, + { 0x06, "SCHED" }, + { 0x07, "HOST0" }, + { 0x08, "HOST1" }, + { 0x09, "HOST2" }, + { 0x0a, "HOST3" }, + { 0x0b, "HOST4" }, + { 0x0c, "HOST5" }, + { 0x0d, "HOST6" }, + { 0x0e, "HOST7" }, + { 0x0f, "HOSTSR" }, + { 0x13, "PERF" }, + { 0x17, "PMU" }, + { 0x18, "PTP" }, + {} +}; + +static const struct gk104_fifo_func gm107_fifo = { - .dtor = gk104_fifo_dtor, - .oneinit = gk104_fifo_oneinit, - .init = gk104_fifo_init, - .fini = gk104_fifo_fini, - .intr = gk104_fifo_intr, - .uevent_init = gk104_fifo_uevent_init, - .uevent_fini = gk104_fifo_uevent_fini, + .fault.engine = gm107_fifo_fault_engine, + .fault.reason = gk104_fifo_fault_reason, + .fault.hubclient = gk104_fifo_fault_hubclient, + .fault.gpcclient = gk104_fifo_fault_gpcclient, .chan = { &gk110_fifo_gpfifo_oclass, NULL diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index 4bdd43078df9..b069f785c5d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -24,15 +24,12 @@ #include "gk104.h" #include "changk104.h" -static const struct nvkm_fifo_func +static const struct gk104_fifo_func gm200_fifo = { - .dtor = gk104_fifo_dtor, - .oneinit = gk104_fifo_oneinit, - .init = gk104_fifo_init, - .fini = gk104_fifo_fini, - .intr = gk104_fifo_intr, - .uevent_init = gk104_fifo_uevent_init, - .uevent_fini = gk104_fifo_uevent_fini, + .fault.engine = gm107_fifo_fault_engine, + .fault.reason = gk104_fifo_fault_reason, + .fault.hubclient = gk104_fifo_fault_hubclient, + .fault.gpcclient = gk104_fifo_fault_gpcclient, .chan = { &gm200_fifo_gpfifo_oclass, NULL diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c index 4c91d4aa1e9e..2ed87c2e8299 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c @@ -22,15 +22,12 @@ #include "gk104.h" #include "changk104.h" -static const struct nvkm_fifo_func +static const struct gk104_fifo_func gm20b_fifo = { - .dtor = gk104_fifo_dtor, - .oneinit = gk104_fifo_oneinit, - .init = gk104_fifo_init, - .fini = gk104_fifo_fini, - .intr = gk104_fifo_intr, - .uevent_init = gk104_fifo_uevent_init, - .uevent_fini = gk104_fifo_uevent_fini, + .fault.engine = gm107_fifo_fault_engine, + .fault.reason = gk104_fifo_fault_reason, + .fault.hubclient = gk104_fifo_fault_hubclient, + .fault.gpcclient = gk104_fifo_fault_gpcclient, .chan = { &gm200_fifo_gpfifo_oclass, NULL diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index cb1432e9be08..f6dfb37d9429 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -7,6 +7,7 @@ int nvkm_fifo_ctor(const struct nvkm_fifo_func *, struct nvkm_device *, int index, int nr, struct nvkm_fifo *); void nvkm_fifo_uevent(struct nvkm_fifo *); +struct nvkm_fifo_chan_oclass; struct nvkm_fifo_func { void *(*dtor)(struct nvkm_fifo *); int (*oneinit)(struct nvkm_fifo *); @@ -17,6 +18,8 @@ struct nvkm_fifo_func { void (*start)(struct nvkm_fifo *, unsigned long *); void (*uevent_init)(struct nvkm_fifo *); void (*uevent_fini)(struct nvkm_fifo *); + int (*class_get)(struct nvkm_fifo *, int index, + const struct nvkm_fifo_chan_oclass **); const struct nvkm_fifo_chan_oclass *chan[]; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c index 090765ff070d..467065d1b4e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c @@ -128,9 +128,8 @@ nvkm_gr = { int nvkm_gr_ctor(const struct nvkm_gr_func *func, struct nvkm_device *device, - int index, u32 pmc_enable, bool enable, struct nvkm_gr *gr) + int index, bool enable, struct nvkm_gr *gr) { gr->func = func; - return nvkm_engine_ctor(&nvkm_gr, device, index, pmc_enable, - enable, &gr->engine); + return nvkm_engine_ctor(&nvkm_gr, device, index, enable, &gr->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c index 56f392d3d4fd..b02d8f50ea6a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c @@ -1181,20 +1181,20 @@ gf100_grctx_generate_r418bb8(struct gf100_gr *gr) /* GPC_BROADCAST */ nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | - gr->magic_not_rop_nr); + gr->screen_tile_row_offset); for (i = 0; i < 6; i++) nvkm_wr32(device, 0x418b08 + (i * 4), data[i]); /* GPC_BROADCAST.TP_BROADCAST */ nvkm_wr32(device, 0x419bd0, (gr->tpc_total << 8) | - gr->magic_not_rop_nr | data2[0]); + gr->screen_tile_row_offset | data2[0]); nvkm_wr32(device, 0x419be4, data2[1]); for (i = 0; i < 6; i++) nvkm_wr32(device, 0x419b00 + (i * 4), data[i]); /* UNK78xx */ nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | - gr->magic_not_rop_nr); + gr->screen_tile_row_offset); for (i = 0; i < 6; i++) nvkm_wr32(device, 0x40780c + (i * 4), data[i]); } @@ -1238,6 +1238,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; + u32 idle_timeout; nvkm_mc_unk260(device->mc, 0); @@ -1247,7 +1248,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_gr_mmio(gr, grctx->tpc); gf100_gr_mmio(gr, grctx->ppc); - nvkm_wr32(device, 0x404154, 0x00000000); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->bundle(info); grctx->pagepool(info); @@ -1261,7 +1262,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_grctx_generate_r406800(gr); gf100_gr_icmd(gr, grctx->icmd); - nvkm_wr32(device, 0x404154, 0x00000400); + nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); nvkm_mc_unk260(device->mc, 1); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h index 3c8673958f22..ac895edce164 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -81,8 +81,6 @@ void gk104_grctx_generate_bundle(struct gf100_grctx *); void gk104_grctx_generate_pagepool(struct gf100_grctx *); void gk104_grctx_generate_unkn(struct gf100_gr *); void gk104_grctx_generate_r418bb8(struct gf100_gr *); -void gk104_grctx_generate_rop_active_fbps(struct gf100_gr *); - void gm107_grctx_generate_bundle(struct gf100_grctx *); void gm107_grctx_generate_pagepool(struct gf100_grctx *); @@ -98,7 +96,6 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *); void gm107_grctx_generate_attrib(struct gf100_grctx *); extern const struct gf100_grctx_func gm200_grctx; -void gm200_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); void gm200_grctx_generate_tpcid(struct gf100_gr *); void gm200_grctx_generate_405b60(struct gf100_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c index 74de7a96c22a..f521de11a299 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c @@ -223,6 +223,7 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; + u32 idle_timeout; int i; nvkm_mc_unk260(device->mc, 0); @@ -233,7 +234,7 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_gr_mmio(gr, grctx->tpc); gf100_gr_mmio(gr, grctx->ppc); - nvkm_wr32(device, 0x404154, 0x00000000); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->bundle(info); grctx->pagepool(info); @@ -250,7 +251,7 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); gf100_gr_icmd(gr, grctx->icmd); - nvkm_wr32(device, 0x404154, 0x00000400); + nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); nvkm_mc_unk260(device->mc, 1); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c index a843e3689c3c..9ba337778ef5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -924,38 +924,30 @@ gk104_grctx_generate_r418bb8(struct gf100_gr *gr) /* GPC_BROADCAST */ nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | - gr->magic_not_rop_nr); + gr->screen_tile_row_offset); for (i = 0; i < 6; i++) nvkm_wr32(device, 0x418b08 + (i * 4), data[i]); /* GPC_BROADCAST.TP_BROADCAST */ nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) | - gr->magic_not_rop_nr | data2[0]); + gr->screen_tile_row_offset | data2[0]); nvkm_wr32(device, 0x41bfe4, data2[1]); for (i = 0; i < 6; i++) nvkm_wr32(device, 0x41bf00 + (i * 4), data[i]); /* UNK78xx */ nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | - gr->magic_not_rop_nr); + gr->screen_tile_row_offset); for (i = 0; i < 6; i++) nvkm_wr32(device, 0x40780c + (i * 4), data[i]); } void -gk104_grctx_generate_rop_active_fbps(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 fbp_count = nvkm_rd32(device, 0x120074); - nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */ - nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ -} - -void gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; + u32 idle_timeout; int i; nvkm_mc_unk260(device->mc, 0); @@ -966,7 +958,7 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_gr_mmio(gr, grctx->tpc); gf100_gr_mmio(gr, grctx->ppc); - nvkm_wr32(device, 0x404154, 0x00000000); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->bundle(info); grctx->pagepool(info); @@ -982,11 +974,10 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - gk104_grctx_generate_rop_active_fbps(gr); nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); gf100_gr_icmd(gr, grctx->icmd); - nvkm_wr32(device, 0x404154, 0x00000400); + nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); nvkm_mc_unk260(device->mc, 1); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c index ad0a6cfe7580..da7c35a6a3d2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c @@ -29,15 +29,14 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; - int idle_timeout_save; + u32 idle_timeout; int i; gf100_gr_mmio(gr, gr->fuc_sw_ctx); gf100_gr_wait_idle(gr); - idle_timeout_save = nvkm_rd32(device, 0x404154); - nvkm_wr32(device, 0x404154, 0x00000000); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->attrib(info); @@ -53,13 +52,11 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - gk104_grctx_generate_rop_active_fbps(gr); - nvkm_mask(device, 0x5044b0, 0x08000000, 0x08000000); gf100_gr_wait_idle(gr); - nvkm_wr32(device, 0x404154, idle_timeout_save); + nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_wait_idle(gr); gf100_gr_mthd(gr, gr->fuc_method); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c index 95f59e3169f2..6d3c5011e18c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -920,13 +920,15 @@ gm107_grctx_generate_attrib(struct gf100_grctx *info) const u32 bs = attrib * gr->ppc_tpc_nr[gpc][ppc]; const u32 u = 0x418ea0 + (n * 0x04); const u32 o = PPC_UNIT(gpc, ppc, 0); + if (!(gr->ppc_mask[gpc] & (1 << ppc))) + continue; mmio_wr32(info, o + 0xc0, bs); mmio_wr32(info, o + 0xf4, bo); bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc]; mmio_wr32(info, o + 0xe4, as); mmio_wr32(info, o + 0xf8, ao); ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc]; - mmio_wr32(info, u, ((bs / 3 /*XXX*/) << 16) | bs); + mmio_wr32(info, u, ((bs / 3) << 16) | bs); } } } @@ -957,6 +959,7 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; + u32 idle_timeout; int i; gf100_gr_mmio(gr, grctx->hub); @@ -965,7 +968,7 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_gr_mmio(gr, grctx->tpc); gf100_gr_mmio(gr, grctx->ppc); - nvkm_wr32(device, 0x404154, 0x00000000); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->bundle(info); grctx->pagepool(info); @@ -984,10 +987,8 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - gk104_grctx_generate_rop_active_fbps(gr); - gf100_gr_icmd(gr, grctx->icmd); - nvkm_wr32(device, 0x404154, 0x00000400); + nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, grctx->mthd); nvkm_mask(device, 0x419e00, 0x00808080, 0x00808080); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c index e586699fc43f..db209d33f486 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c @@ -33,7 +33,7 @@ gm200_grctx_generate_tpcid(struct gf100_gr *gr) struct nvkm_device *device = gr->base.engine.subdev.device; int gpc, tpc, id; - for (tpc = 0, id = 0; tpc < 4; tpc++) { + for (tpc = 0, id = 0; tpc < TPC_MAX_PER_GPC; tpc++) { for (gpc = 0; gpc < gr->gpc_nr; gpc++) { if (tpc < gr->tpc_nr[gpc]) { nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), id); @@ -45,15 +45,6 @@ gm200_grctx_generate_tpcid(struct gf100_gr *gr) } } -static void -gm200_grctx_generate_rop_active_fbps(struct gf100_gr *gr) -{ - struct nvkm_device *device = gr->base.engine.subdev.device; - const u32 fbp_count = nvkm_rd32(device, 0x12006c); - nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */ - nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ -} - void gm200_grctx_generate_405b60(struct gf100_gr *gr) { @@ -86,17 +77,17 @@ gm200_grctx_generate_405b60(struct gf100_gr *gr) nvkm_wr32(device, 0x405ba0 + (i * 4), gpcs[i]); } -void +static void gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; - u32 tmp; + u32 idle_timeout, tmp; int i; gf100_gr_mmio(gr, gr->fuc_sw_ctx); - nvkm_wr32(device, 0x404154, 0x00000000); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->bundle(info); grctx->pagepool(info); @@ -113,8 +104,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - gm200_grctx_generate_rop_active_fbps(gr); - for (tmp = 0, i = 0; i < gr->gpc_nr; i++) tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 4); nvkm_wr32(device, 0x4041c4, tmp); @@ -122,7 +111,7 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gm200_grctx_generate_405b60(gr); gf100_gr_icmd(gr, gr->fuc_bundle); - nvkm_wr32(device, 0x404154, 0x00000800); + nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_mthd(gr, gr->fuc_method); nvkm_mask(device, 0x418e94, 0xffffffff, 0xc4230000); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c index a8827efa90ae..e5702e3e0a5a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c @@ -40,15 +40,14 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) { struct nvkm_device *device = gr->base.engine.subdev.device; const struct gf100_grctx_func *grctx = gr->func->grctx; - int idle_timeout_save; + u32 idle_timeout; int i, tmp; gf100_gr_mmio(gr, gr->fuc_sw_ctx); gf100_gr_wait_idle(gr); - idle_timeout_save = nvkm_rd32(device, 0x404154); - nvkm_wr32(device, 0x404154, 0x00000000); + idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000); grctx->attrib(info); @@ -63,7 +62,6 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); - gk104_grctx_generate_rop_active_fbps(gr); nvkm_wr32(device, 0x408908, nvkm_rd32(device, 0x410108) | 0x80000000); for (tmp = 0, i = 0; i < gr->gpc_nr; i++) @@ -74,7 +72,7 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) gf100_gr_wait_idle(gr); - nvkm_wr32(device, 0x404154, idle_timeout_save); + nvkm_wr32(device, 0x404154, idle_timeout); gf100_gr_wait_idle(gr); gf100_gr_mthd(gr, gr->fuc_method); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc index dc60509f76f7..4984b0069dfd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc @@ -291,12 +291,13 @@ init: // Main program loop, very simple, sleeps until woken up by the interrupt // handler, pulls a command from the queue and executes its handler // -main: - bset $flags $p0 +wait: sleep $p0 + bset $flags $p0 +main: mov $r13 #cmd_queue call(queue_get) - bra $p1 #main + bra $p1 #wait // 0x0000-0x0003 are all context transfers cmpu b32 $r14 0x04 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h index 5f4ddfee48a2..8cb240b65ec2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h @@ -370,9 +370,10 @@ uint32_t gf100_grgpc_code[] = { 0xf11f29f0, 0xf0080007, 0x02d00203, -/* 0x04bb: main */ +/* 0x04bb: wait */ 0xf404bd00, - 0x28f40031, + 0x31f40028, +/* 0x04c1: main */ 0x1cd7f000, 0xf43921f4, 0xe4b0f401, @@ -384,10 +385,10 @@ uint32_t gf100_grgpc_code[] = { 0x0018fe05, 0x05b421f5, /* 0x04eb: main_not_ctx_xfer */ - 0x94d30ef4, + 0x94d90ef4, 0xf5f010ef, 0x7e21f501, - 0xc60ef403, + 0xcc0ef403, /* 0x04f8: ih */ 0x80f900f9, 0xf90188fe, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h index 03381b163cfc..550d6ba0933b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h @@ -397,9 +397,10 @@ uint32_t gf117_grgpc_code[] = { 0x080007f1, 0xd00203f0, 0x04bd0002, -/* 0x0508: main */ - 0xf40031f4, - 0xd7f00028, +/* 0x0508: wait */ + 0xf40028f4, +/* 0x050e: main */ + 0xd7f00031, 0x3921f424, 0xb0f401f4, 0x18f404e4, @@ -409,13 +410,13 @@ uint32_t gf117_grgpc_code[] = { 0xfd01e4b6, 0x18fe051e, 0x0121f500, - 0xd30ef406, + 0xd90ef406, /* 0x0538: main_not_ctx_xfer */ 0xf010ef94, 0x21f501f5, 0x0ef4037e, /* 0x0545: ih */ - 0xf900f9c6, + 0xf900f9cc, 0x0188fe80, 0x90f980f9, 0xb0f9a0f9, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h index 99d9b48a3b50..271b59d365e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h @@ -397,9 +397,10 @@ uint32_t gk104_grgpc_code[] = { 0x080007f1, 0xd00203f0, 0x04bd0002, -/* 0x0508: main */ - 0xf40031f4, - 0xd7f00028, +/* 0x0508: wait */ + 0xf40028f4, +/* 0x050e: main */ + 0xd7f00031, 0x3921f424, 0xb0f401f4, 0x18f404e4, @@ -409,13 +410,13 @@ uint32_t gk104_grgpc_code[] = { 0xfd01e4b6, 0x18fe051e, 0x0121f500, - 0xd30ef406, + 0xd90ef406, /* 0x0538: main_not_ctx_xfer */ 0xf010ef94, 0x21f501f5, 0x0ef4037e, /* 0x0545: ih */ - 0xf900f9c6, + 0xf900f9cc, 0x0188fe80, 0x90f980f9, 0xb0f9a0f9, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h index f7267696cbfd..73b4a32c5d29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h @@ -397,9 +397,10 @@ uint32_t gk110_grgpc_code[] = { 0x300007f1, 0xd00203f0, 0x04bd0002, -/* 0x0508: main */ - 0xf40031f4, - 0xd7f00028, +/* 0x0508: wait */ + 0xf40028f4, +/* 0x050e: main */ + 0xd7f00031, 0x3921f424, 0xb0f401f4, 0x18f404e4, @@ -409,13 +410,13 @@ uint32_t gk110_grgpc_code[] = { 0xfd01e4b6, 0x18fe051e, 0x0121f500, - 0xd30ef406, + 0xd90ef406, /* 0x0538: main_not_ctx_xfer */ 0xf010ef94, 0x21f501f5, 0x0ef4037e, /* 0x0545: ih */ - 0xf900f9c6, + 0xf900f9cc, 0x0188fe80, 0x90f980f9, 0xb0f9a0f9, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h index 387d1fa3e231..018169818317 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h @@ -349,9 +349,10 @@ uint32_t gk208_grgpc_code[] = { 0x801f29f0, 0xf6023000, 0x04bd0002, -/* 0x0448: main */ - 0xf40031f4, - 0x240d0028, +/* 0x0448: wait */ + 0xf40028f4, +/* 0x044e: main */ + 0x240d0031, 0x0000377e, 0xb0f401f4, 0x18f404e4, @@ -362,10 +363,10 @@ uint32_t gk208_grgpc_code[] = { 0x0018fe05, 0x00051f7e, /* 0x0477: main_not_ctx_xfer */ - 0x94d40ef4, + 0x94da0ef4, 0xf5f010ef, 0x02f87e01, - 0xc70ef400, + 0xcd0ef400, /* 0x0484: ih */ 0x80f900f9, 0xf90188fe, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h index fa9f3c0c5994..eca007f03fa9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h @@ -427,9 +427,10 @@ uint32_t gm107_grgpc_code[] = { 0x1f29f024, 0x02300080, 0xbd0002f6, -/* 0x0571: main */ - 0x0031f404, - 0x0d0028f4, +/* 0x0571: wait */ + 0x0028f404, +/* 0x0577: main */ + 0x0d0031f4, 0x00377e24, 0xf401f400, 0xf404e4b0, @@ -439,13 +440,13 @@ uint32_t gm107_grgpc_code[] = { 0xfd01e4b6, 0x18fe051e, 0x06487e00, - 0xd40ef400, + 0xda0ef400, /* 0x05a0: main_not_ctx_xfer */ 0xf010ef94, 0xf87e01f5, 0x0ef40002, /* 0x05ad: ih */ - 0xf900f9c7, + 0xf900f9cd, 0x0188fe80, 0x90f980f9, 0xb0f9a0f9, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc index e3a2fb308271..4d416d4f82d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc @@ -218,13 +218,14 @@ init: // Main program loop, very simple, sleeps until woken up by the interrupt // handler, pulls a command from the queue and executes its handler // -main: +wait: // sleep until we have something to do - bset $flags $p0 sleep $p0 + bset $flags $p0 +main: mov $r13 #cmd_queue call(queue_get) - bra $p1 #main + bra $p1 #wait // context switch, requested by GPU? cmpu b32 $r14 0x4001 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h index 397921a9a46c..8015b40a61d6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h @@ -584,9 +584,10 @@ uint32_t gf100_grhub_code[] = { 0x080007f1, 0xd00203f0, 0x04bd0001, -/* 0x0564: main */ - 0xf40031f4, - 0xd7f00028, +/* 0x0564: wait */ + 0xf40028f4, +/* 0x056a: main */ + 0xd7f00031, 0x3921f410, 0xb1f401f4, 0xf54001e4, @@ -650,7 +651,7 @@ uint32_t gf100_grhub_code[] = { 0x170007f1, 0xd00203f0, 0x04bd0009, - 0xff080ef5, + 0xff0e0ef5, /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, @@ -675,12 +676,12 @@ uint32_t gf100_grhub_code[] = { 0xf501f5f0, 0xf5037e21, /* 0x06b3: main_done */ - 0xbdfeb50e, + 0xbdfebb0e, 0x1f29f024, 0x080007f1, 0xd00203f0, 0x04bd0002, - 0xfea00ef5, + 0xfea60ef5, /* 0x06c8: ih */ 0x80f900f9, 0xf90188fe, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h index 50c97163dcdb..2af90ec6852a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h @@ -584,9 +584,10 @@ uint32_t gf117_grhub_code[] = { 0x080007f1, 0xd00203f0, 0x04bd0001, -/* 0x0564: main */ - 0xf40031f4, - 0xd7f00028, +/* 0x0564: wait */ + 0xf40028f4, +/* 0x056a: main */ + 0xd7f00031, 0x3921f410, 0xb1f401f4, 0xf54001e4, @@ -650,7 +651,7 @@ uint32_t gf117_grhub_code[] = { 0x170007f1, 0xd00203f0, 0x04bd0009, - 0xff080ef5, + 0xff0e0ef5, /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, @@ -675,12 +676,12 @@ uint32_t gf117_grhub_code[] = { 0xf501f5f0, 0xf5037e21, /* 0x06b3: main_done */ - 0xbdfeb50e, + 0xbdfebb0e, 0x1f29f024, 0x080007f1, 0xd00203f0, 0x04bd0002, - 0xfea00ef5, + 0xfea60ef5, /* 0x06c8: ih */ 0x80f900f9, 0xf90188fe, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h index 125824b394bb..e8b8c1c94700 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h @@ -584,9 +584,10 @@ uint32_t gk104_grhub_code[] = { 0x080007f1, 0xd00203f0, 0x04bd0001, -/* 0x0564: main */ - 0xf40031f4, - 0xd7f00028, +/* 0x0564: wait */ + 0xf40028f4, +/* 0x056a: main */ + 0xd7f00031, 0x3921f410, 0xb1f401f4, 0xf54001e4, @@ -650,7 +651,7 @@ uint32_t gk104_grhub_code[] = { 0x170007f1, 0xd00203f0, 0x04bd0009, - 0xff080ef5, + 0xff0e0ef5, /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, @@ -675,12 +676,12 @@ uint32_t gk104_grhub_code[] = { 0xf501f5f0, 0xf5037e21, /* 0x06b3: main_done */ - 0xbdfeb50e, + 0xbdfebb0e, 0x1f29f024, 0x080007f1, 0xd00203f0, 0x04bd0002, - 0xfea00ef5, + 0xfea60ef5, /* 0x06c8: ih */ 0x80f900f9, 0xf90188fe, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h index 0a1b8c0b8b82..f4ed2fb6f714 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h @@ -584,9 +584,10 @@ uint32_t gk110_grhub_code[] = { 0x300007f1, 0xd00203f0, 0x04bd0001, -/* 0x0564: main */ - 0xf40031f4, - 0xd7f00028, +/* 0x0564: wait */ + 0xf40028f4, +/* 0x056a: main */ + 0xd7f00031, 0x3921f410, 0xb1f401f4, 0xf54001e4, @@ -650,7 +651,7 @@ uint32_t gk110_grhub_code[] = { 0x170007f1, 0xd00203f0, 0x04bd0009, - 0xff080ef5, + 0xff0e0ef5, /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, @@ -675,12 +676,12 @@ uint32_t gk110_grhub_code[] = { 0xf501f5f0, 0xf5037e21, /* 0x06b3: main_done */ - 0xbdfeb50e, + 0xbdfebb0e, 0x1f29f024, 0x300007f1, 0xd00203f0, 0x04bd0002, - 0xfea00ef5, + 0xfea60ef5, /* 0x06c8: ih */ 0x80f900f9, 0xf90188fe, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h index 16869d0b109b..ed488973c117 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h @@ -531,9 +531,10 @@ uint32_t gk208_grhub_code[] = { 0x1f19f014, 0x02300080, 0xbd0001f6, -/* 0x0491: main */ - 0x0031f404, - 0x0d0028f4, +/* 0x0491: wait */ + 0x0028f404, +/* 0x0497: main */ + 0x0d0031f4, 0x00377e10, 0xf401f400, 0x4001e4b1, @@ -590,7 +591,7 @@ uint32_t gk208_grhub_code[] = { 0x09f60217, 0xf504bd00, /* 0x056b: main_not_ctx_switch */ - 0xb0ff2a0e, + 0xb0ff300e, 0x1bf401e4, 0x7ef2b20c, 0xf4000820, @@ -612,11 +613,11 @@ uint32_t gk208_grhub_code[] = { 0x7e01f5f0, 0xf50002f8, /* 0x05b7: main_done */ - 0xbdfede0e, + 0xbdfee40e, 0x1f29f024, 0x02300080, 0xbd0002f6, - 0xcc0ef504, + 0xd20ef504, /* 0x05c9: ih */ 0xf900f9fe, 0x0188fe80, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h index d6343d2a614c..5c9051839557 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h @@ -531,9 +531,10 @@ uint32_t gm107_grhub_code[] = { 0x1f19f014, 0x02300080, 0xbd0001f6, -/* 0x0491: main */ - 0x0031f404, - 0x0d0028f4, +/* 0x0491: wait */ + 0x0028f404, +/* 0x0497: main */ + 0x0d0031f4, 0x00377e10, 0xf401f400, 0x4001e4b1, @@ -590,7 +591,7 @@ uint32_t gm107_grhub_code[] = { 0x09f60217, 0xf504bd00, /* 0x056b: main_not_ctx_switch */ - 0xb0ff2a0e, + 0xb0ff300e, 0x1bf401e4, 0x7ef2b20c, 0xf4000820, @@ -612,11 +613,11 @@ uint32_t gm107_grhub_code[] = { 0x7e01f5f0, 0xf50002f8, /* 0x05b7: main_done */ - 0xbdfede0e, + 0xbdfee40e, 0x1f29f024, 0x02300080, 0xbd0002f6, - 0xcc0ef504, + 0xd20ef504, /* 0x05c9: ih */ 0xf900f9fe, 0x0188fe80, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index b2de290da16f..9513badb8220 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -702,6 +702,13 @@ gf100_gr_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +int +gf100_gr_rops(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + return (nvkm_rd32(device, 0x409604) & 0x001f0000) >> 16; +} + void gf100_gr_zbc_init(struct gf100_gr *gr) { @@ -1609,32 +1616,12 @@ gf100_gr_oneinit(struct nvkm_gr *base) { struct gf100_gr *gr = gf100_gr(base); struct nvkm_device *device = gr->base.engine.subdev.device; - int ret, i, j; + int i, j; nvkm_pmu_pgob(device->pmu, false); - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false, - &gr->unk4188b4); - if (ret) - return ret; - - ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false, - &gr->unk4188b8); - if (ret) - return ret; - - nvkm_kmap(gr->unk4188b4); - for (i = 0; i < 0x1000; i += 4) - nvkm_wo32(gr->unk4188b4, i, 0x00000010); - nvkm_done(gr->unk4188b4); - - nvkm_kmap(gr->unk4188b8); - for (i = 0; i < 0x1000; i += 4) - nvkm_wo32(gr->unk4188b8, i, 0x00000010); - nvkm_done(gr->unk4188b8); - - gr->rop_nr = (nvkm_rd32(device, 0x409604) & 0x001f0000) >> 16; - gr->gpc_nr = nvkm_rd32(device, 0x409604) & 0x0000001f; + gr->rop_nr = gr->func->rops(gr); + gr->gpc_nr = nvkm_rd32(device, 0x409604) & 0x0000001f; for (i = 0; i < gr->gpc_nr; i++) { gr->tpc_nr[i] = nvkm_rd32(device, GPC_UNIT(i, 0x2608)); gr->tpc_total += gr->tpc_nr[i]; @@ -1651,38 +1638,38 @@ gf100_gr_oneinit(struct nvkm_gr *base) switch (device->chipset) { case 0xc0: if (gr->tpc_total == 11) { /* 465, 3/4/4/0, 4 */ - gr->magic_not_rop_nr = 0x07; + gr->screen_tile_row_offset = 0x07; } else if (gr->tpc_total == 14) { /* 470, 3/3/4/4, 5 */ - gr->magic_not_rop_nr = 0x05; + gr->screen_tile_row_offset = 0x05; } else if (gr->tpc_total == 15) { /* 480, 3/4/4/4, 6 */ - gr->magic_not_rop_nr = 0x06; + gr->screen_tile_row_offset = 0x06; } break; case 0xc3: /* 450, 4/0/0/0, 2 */ - gr->magic_not_rop_nr = 0x03; + gr->screen_tile_row_offset = 0x03; break; case 0xc4: /* 460, 3/4/0/0, 4 */ - gr->magic_not_rop_nr = 0x01; + gr->screen_tile_row_offset = 0x01; break; case 0xc1: /* 2/0/0/0, 1 */ - gr->magic_not_rop_nr = 0x01; + gr->screen_tile_row_offset = 0x01; break; case 0xc8: /* 4/4/3/4, 5 */ - gr->magic_not_rop_nr = 0x06; + gr->screen_tile_row_offset = 0x06; break; case 0xce: /* 4/4/0/0, 4 */ - gr->magic_not_rop_nr = 0x03; + gr->screen_tile_row_offset = 0x03; break; case 0xcf: /* 4/0/0/0, 3 */ - gr->magic_not_rop_nr = 0x03; + gr->screen_tile_row_offset = 0x03; break; case 0xd7: case 0xd9: /* 1/0/0/0, 1 */ case 0xea: /* gk20a */ case 0x12b: /* gm20b */ - gr->magic_not_rop_nr = 0x01; + gr->screen_tile_row_offset = 0x01; break; } @@ -1729,8 +1716,6 @@ gf100_gr_dtor(struct nvkm_gr *base) gf100_gr_dtor_init(gr->fuc_sw_ctx); gf100_gr_dtor_init(gr->fuc_sw_nonctx); - nvkm_memory_del(&gr->unk4188b8); - nvkm_memory_del(&gr->unk4188b4); return gr; } @@ -1776,7 +1761,7 @@ gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device, gr->firmware = nvkm_boolopt(device->cfgopt, "NvGrUseFW", func->fecs.ucode == NULL); - ret = nvkm_gr_ctor(&gf100_gr_, device, index, 0x08001000, + ret = nvkm_gr_ctor(&gf100_gr_, device, index, gr->firmware || func->fecs.ucode != NULL, &gr->base); if (ret) @@ -1815,6 +1800,7 @@ int gf100_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; + struct nvkm_fb *fb = device->fb; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; @@ -1827,8 +1813,8 @@ gf100_gr_init(struct gf100_gr *gr) nvkm_wr32(device, GPC_BCAST(0x088c), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8); - nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8); + nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8); + nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); gf100_gr_mmio(gr, gr->func->mmio); @@ -1851,9 +1837,9 @@ gf100_gr_init(struct gf100_gr *gr) for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]); + gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); + gr->tpc_total); nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); } @@ -1946,6 +1932,7 @@ gf100_gr = { .mmio = gf100_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, + .rops = gf100_gr_rops, .grctx = &gf100_grctx, .sclass = { { -1, -1, FERMI_TWOD_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index f0c6acb0f8fd..2b98abdb9270 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -31,7 +31,8 @@ #include <subdev/mmu.h> #define GPC_MAX 32 -#define TPC_MAX (GPC_MAX * 8) +#define TPC_MAX_PER_GPC 8 +#define TPC_MAX (GPC_MAX * TPC_MAX_PER_GPC) #define ROP_BCAST(r) (0x408800 + (r)) #define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r)) @@ -100,15 +101,12 @@ struct gf100_gr { u8 ppc_mask[GPC_MAX]; u8 ppc_tpc_nr[GPC_MAX][4]; - struct nvkm_memory *unk4188b4; - struct nvkm_memory *unk4188b8; - struct gf100_gr_data mmio_data[4]; struct gf100_gr_mmio mmio_list[4096/8]; u32 size; u32 *data; - u8 magic_not_rop_nr; + u8 screen_tile_row_offset; }; int gf100_gr_ctor(const struct gf100_gr_func *, struct nvkm_device *, @@ -121,6 +119,8 @@ struct gf100_gr_func { void (*dtor)(struct gf100_gr *); int (*init)(struct gf100_gr *); void (*init_gpc_mmu)(struct gf100_gr *); + void (*init_rop_active_fbps)(struct gf100_gr *); + void (*init_ppc_exceptions)(struct gf100_gr *); void (*set_hww_esr_report_mask)(struct gf100_gr *); const struct gf100_gr_pack *mmio; struct { @@ -129,18 +129,23 @@ struct gf100_gr_func { struct { struct gf100_gr_ucode *ucode; } gpccs; + int (*rops)(struct gf100_gr *); int ppc_nr; const struct gf100_grctx_func *grctx; struct nvkm_sclass sclass[]; }; int gf100_gr_init(struct gf100_gr *); +int gf100_gr_rops(struct gf100_gr *); int gk104_gr_init(struct gf100_gr *); +void gk104_gr_init_rop_active_fbps(struct gf100_gr *); +void gk104_gr_init_ppc_exceptions(struct gf100_gr *); int gk20a_gr_init(struct gf100_gr *); int gm200_gr_init(struct gf100_gr *); +int gm200_gr_rops(struct gf100_gr *); #define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c index 8f253e0a22f4..d736dcd55ea2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c @@ -118,6 +118,7 @@ gf104_gr = { .mmio = gf104_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, + .rops = gf100_gr_rops, .grctx = &gf104_grctx, .sclass = { { -1, -1, FERMI_TWOD_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 815a5aafa245..2f0d24498427 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -109,6 +109,7 @@ gf108_gr = { .mmio = gf108_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, + .rops = gf100_gr_rops, .grctx = &gf108_grctx, .sclass = { { -1, -1, FERMI_TWOD_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index d081ee41fc14..d1d942eb86af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -90,6 +90,7 @@ gf110_gr = { .mmio = gf110_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, + .rops = gf100_gr_rops, .grctx = &gf110_grctx, .sclass = { { -1, -1, FERMI_TWOD_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index d8e8af4d3b30..70335f65c51e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -126,6 +126,7 @@ gf117_gr = { .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, + .rops = gf100_gr_rops, .ppc_nr = 1, .grctx = &gf117_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c index 01faf9a73774..8d8e4cafe28f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c @@ -181,6 +181,7 @@ gf119_gr = { .mmio = gf119_gr_pack_mmio, .fecs.ucode = &gf100_gr_fecs_ucode, .gpccs.ucode = &gf100_gr_gpccs_ucode, + .rops = gf100_gr_rops, .grctx = &gf119_grctx, .sclass = { { -1, -1, FERMI_TWOD_A }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index abf54928a1a4..ec22da6c99fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -24,6 +24,8 @@ #include "gf100.h" #include "ctxgf100.h" +#include <subdev/fb.h> + #include <nvif/class.h> /******************************************************************************* @@ -177,10 +179,35 @@ gk104_gr_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ +void +gk104_gr_init_rop_active_fbps(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const u32 fbp_count = nvkm_rd32(device, 0x120074); + nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */ + nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ +} + +void +gk104_gr_init_ppc_exceptions(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + int gpc, ppc; + + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { + for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) { + if (!(gr->ppc_mask[gpc] & (1 << ppc))) + continue; + nvkm_wr32(device, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000); + } + } +} + int gk104_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; + struct nvkm_fb *fb = device->fb; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; @@ -193,8 +220,8 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_wr32(device, GPC_BCAST(0x088c), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8); - nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8); + nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8); + nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); gf100_gr_mmio(gr, gr->func->mmio); @@ -218,15 +245,17 @@ gk104_gr_init(struct gf100_gr *gr) for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]); + gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); + gr->tpc_total); nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); } nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); + gr->func->init_rop_active_fbps(gr); + nvkm_wr32(device, 0x400500, 0x00010001); nvkm_wr32(device, 0x400100, 0xffffffff); @@ -246,8 +275,9 @@ gk104_gr_init(struct gf100_gr *gr) nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000); + gr->func->init_ppc_exceptions(gr); + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - nvkm_wr32(device, GPC_UNIT(gpc, 0x3038), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000); @@ -309,9 +339,12 @@ gk104_gr_gpccs_ucode = { static const struct gf100_gr_func gk104_gr = { .init = gk104_gr_init, + .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk104_gr_pack_mmio, .fecs.ucode = &gk104_gr_fecs_ucode, .gpccs.ucode = &gk104_gr_gpccs_ucode, + .rops = gf100_gr_rops, .ppc_nr = 1, .grctx = &gk104_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index 32aa2946e7b7..f31b171a4102 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -183,9 +183,12 @@ gk110_gr_gpccs_ucode = { static const struct gf100_gr_func gk110_gr = { .init = gk104_gr_init, + .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, + .rops = gf100_gr_rops, .ppc_nr = 2, .grctx = &gk110_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c index 22f88afbf35f..d76dd178007f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c @@ -103,9 +103,12 @@ gk110b_gr_pack_mmio[] = { static const struct gf100_gr_func gk110b_gr = { .init = gk104_gr_init, + .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk110b_gr_pack_mmio, .fecs.ucode = &gk110_gr_fecs_ucode, .gpccs.ucode = &gk110_gr_gpccs_ucode, + .rops = gf100_gr_rops, .ppc_nr = 2, .grctx = &gk110b_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c index ee7554fc87dc..14bbe6ed02a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c @@ -162,9 +162,12 @@ gk208_gr_gpccs_ucode = { static const struct gf100_gr_func gk208_gr = { .init = gk104_gr_init, + .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gk208_gr_pack_mmio, .fecs.ucode = &gk208_gr_fecs_ucode, .gpccs.ucode = &gk208_gr_gpccs_ucode, + .rops = gf100_gr_rops, .ppc_nr = 1, .grctx = &gk208_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index 7ffb8a626196..4ca8ed15191c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -239,9 +239,6 @@ gk20a_gr_init(struct gf100_gr *gr) return ret; /* MMU debug buffer */ - nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(gr->unk4188b4) >> 8); - nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8); - if (gr->func->init_gpc_mmu) gr->func->init_gpc_mmu(gr); @@ -267,7 +264,7 @@ gk20a_gr_init(struct gf100_gr *gr) for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]); + gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | gr->tpc_total); nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); @@ -275,6 +272,8 @@ gk20a_gr_init(struct gf100_gr *gr) nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); + gr->func->init_rop_active_fbps(gr); + /* Enable FIFO access */ nvkm_wr32(device, 0x400500, 0x00010001); @@ -312,7 +311,9 @@ gk20a_gr_init(struct gf100_gr *gr) static const struct gf100_gr_func gk20a_gr = { .init = gk20a_gr_init, + .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .set_hww_esr_report_mask = gk20a_gr_set_hww_esr_report_mask, + .rops = gf100_gr_rops, .ppc_nr = 1, .grctx = &gk20a_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 56e960212e5d..45f965f608a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -26,6 +26,7 @@ #include <subdev/bios.h> #include <subdev/bios/P0260.h> +#include <subdev/fb.h> #include <nvif/class.h> @@ -311,17 +312,18 @@ int gm107_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; + struct nvkm_fb *fb = device->fb; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; - int gpc, tpc, ppc, rop; + int gpc, tpc, rop; int i; nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000); nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000); - nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8); - nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8); + nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8); + nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8); gf100_gr_mmio(gr, gr->func->mmio); @@ -347,15 +349,17 @@ gm107_gr_init(struct gf100_gr *gr) for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]); + gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); + gr->tpc_total); nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); } nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); + gr->func->init_rop_active_fbps(gr); + nvkm_wr32(device, 0x400500, 0x00010001); nvkm_wr32(device, 0x400100, 0xffffffff); @@ -373,9 +377,9 @@ gm107_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x405844, 0x00ffffff); nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + gr->func->init_ppc_exceptions(gr); + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - for (ppc = 0; ppc < 2 /* gr->ppc_nr[gpc] */; ppc++) - nvkm_wr32(device, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000); @@ -438,9 +442,12 @@ gm107_gr_gpccs_ucode = { static const struct gf100_gr_func gm107_gr = { .init = gm107_gr_init, + .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, .mmio = gm107_gr_pack_mmio, .fecs.ucode = &gm107_gr_fecs_ucode, .gpccs.ucode = &gm107_gr_gpccs_ucode, + .rops = gf100_gr_rops, .ppc_nr = 2, .grctx = &gm107_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c index 058fc1d22c09..4dfa4513bb6c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c @@ -33,27 +33,45 @@ ******************************************************************************/ int +gm200_gr_rops(struct gf100_gr *gr) +{ + return nvkm_rd32(gr->base.engine.subdev.device, 0x12006c); +} + +static void +gm200_gr_init_gpc_mmu(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + + nvkm_wr32(device, 0x418880, nvkm_rd32(device, 0x100c80) & 0xf0001fff); + nvkm_wr32(device, 0x418890, 0x00000000); + nvkm_wr32(device, 0x418894, 0x00000000); + + nvkm_wr32(device, 0x4188b4, nvkm_rd32(device, 0x100cc8)); + nvkm_wr32(device, 0x4188b8, nvkm_rd32(device, 0x100ccc)); + nvkm_wr32(device, 0x4188b0, nvkm_rd32(device, 0x100cc4)); +} + +static void +gm200_gr_init_rop_active_fbps(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const u32 fbp_count = nvkm_rd32(device, 0x12006c); + nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */ + nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */ +} + +int gm200_gr_init(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); - u32 data[TPC_MAX / 8] = {}, tmp; + u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; - int gpc, tpc, ppc, rop; + int gpc, tpc, rop; int i; - tmp = nvkm_rd32(device, 0x100c80); /*XXX: mask? */ - nvkm_wr32(device, 0x418880, 0x00001000 | (tmp & 0x00000fff)); - nvkm_wr32(device, 0x418890, 0x00000000); - nvkm_wr32(device, 0x418894, 0x00000000); - nvkm_wr32(device, 0x4188b4, nvkm_memory_addr(gr->unk4188b4) >> 8); - nvkm_wr32(device, 0x4188b8, nvkm_memory_addr(gr->unk4188b8) >> 8); - nvkm_mask(device, 0x4188b0, 0x00040000, 0x00040000); - - /*XXX: belongs in fb */ - nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(gr->unk4188b4) >> 8); - nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8); - nvkm_mask(device, 0x100cc4, 0x00040000, 0x00040000); + gr->func->init_gpc_mmu(gr); gf100_gr_mmio(gr, gr->fuc_sw_nonctx); @@ -79,9 +97,9 @@ gm200_gr_init(struct gf100_gr *gr) for (gpc = 0; gpc < gr->gpc_nr; gpc++) { nvkm_wr32(device, GPC_UNIT(gpc, 0x0914), - gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]); + gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]); nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 | - gr->tpc_total); + gr->tpc_total); nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918); } @@ -89,6 +107,8 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800)); nvkm_wr32(device, GPC_BCAST(0x033c), nvkm_rd32(device, 0x100804)); + gr->func->init_rop_active_fbps(gr); + nvkm_wr32(device, 0x400500, 0x00010001); nvkm_wr32(device, 0x400100, 0xffffffff); nvkm_wr32(device, 0x40013c, 0xffffffff); @@ -106,9 +126,9 @@ gm200_gr_init(struct gf100_gr *gr) nvkm_wr32(device, 0x405844, 0x00ffffff); nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008); + gr->func->init_ppc_exceptions(gr); + for (gpc = 0; gpc < gr->gpc_nr; gpc++) { - for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) - nvkm_wr32(device, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000); nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000); @@ -189,6 +209,10 @@ gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device, static const struct gf100_gr_func gm200_gr = { .init = gm200_gr_init, + .init_gpc_mmu = gm200_gr_init_gpc_mmu, + .init_rop_active_fbps = gm200_gr_init_rop_active_fbps, + .init_ppc_exceptions = gk104_gr_init_ppc_exceptions, + .rops = gm200_gr_rops, .ppc_nr = 2, .grctx = &gm200_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c index 29732bc14415..69479af1d829 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c @@ -42,7 +42,7 @@ gm20b_gr_init_gpc_mmu(struct gf100_gr *gr) } val = nvkm_rd32(device, 0x100c80); - val &= 0xf000087f; + val &= 0xf000187f; nvkm_wr32(device, 0x418880, val); nvkm_wr32(device, 0x418890, 0); nvkm_wr32(device, 0x418894, 0); @@ -66,7 +66,9 @@ static const struct gf100_gr_func gm20b_gr = { .init = gk20a_gr_init, .init_gpc_mmu = gm20b_gr_init_gpc_mmu, + .init_rop_active_fbps = gk104_gr_init_rop_active_fbps, .set_hww_esr_report_mask = gm20b_gr_set_hww_esr_report_mask, + .rops = gm200_gr_rops, .ppc_nr = 1, .grctx = &gm20b_grctx, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c index 85c5b7fea5f5..9c2e985dc079 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c @@ -1422,6 +1422,5 @@ nv04_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr) spin_lock_init(&gr->lock); *pgr = &gr->base; - return nvkm_gr_ctor(&nv04_gr, device, index, 0x00001000, - true, &gr->base); + return nvkm_gr_ctor(&nv04_gr, device, index, true, &gr->base); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c index 4542867fa9e6..4ebbfbdd8240 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c @@ -1182,7 +1182,7 @@ nv10_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, spin_lock_init(&gr->lock); *pgr = &gr->base; - return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base); + return nvkm_gr_ctor(func, device, index, true, &gr->base); } static const struct nvkm_gr_func diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c index 5caef65d3c6e..d1dc92999dc0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c @@ -337,7 +337,7 @@ nv20_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, return -ENOMEM; *pgr = &gr->base; - return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base); + return nvkm_gr_ctor(func, device, index, true, &gr->base); } static const struct nvkm_gr_func diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c index 05a895496fc6..5f1ad8344ea9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c @@ -438,7 +438,7 @@ nv40_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, *pgr = &gr->base; INIT_LIST_HEAD(&gr->chan); - return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base); + return nvkm_gr_ctor(func, device, index, true, &gr->base); } static const struct nvkm_gr_func diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c index b19b912d5787..fca67de43f2b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c @@ -768,7 +768,7 @@ nv50_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, spin_lock_init(&gr->lock); *pgr = &gr->base; - return nvkm_gr_ctor(func, device, index, 0x00201000, true, &gr->base); + return nvkm_gr_ctor(func, device, index, true, &gr->base); } static const struct nvkm_gr_func diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h index a234590be88e..d8adcdf6985a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h @@ -7,8 +7,7 @@ struct nvkm_fb_tile; struct nvkm_fifo_chan; int nvkm_gr_ctor(const struct nvkm_gr_func *, struct nvkm_device *, - int index, u32 pmc_enable, bool enable, - struct nvkm_gr *); + int index, bool enable, struct nvkm_gr *); bool nv04_gr_idle(struct nvkm_gr *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c index 34ff0014a6c1..c0e11a071843 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c @@ -39,6 +39,5 @@ g84_mpeg = { int g84_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg) { - return nvkm_engine_new_(&g84_mpeg, device, index, 0x00000002, - true, pmpeg); + return nvkm_engine_new_(&g84_mpeg, device, index, true, pmpeg); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c index d4d8942b1347..003ac915eaad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c @@ -278,7 +278,7 @@ nv31_mpeg_new_(const struct nv31_mpeg_func *func, struct nvkm_device *device, mpeg->func = func; *pmpeg = &mpeg->engine; - return nvkm_engine_ctor(&nv31_mpeg_, device, index, 0x00000002, + return nvkm_engine_ctor(&nv31_mpeg_, device, index, true, &mpeg->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c index d433cfa4a8ab..e536f37e24b0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c @@ -212,6 +212,5 @@ nv44_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg) INIT_LIST_HEAD(&mpeg->chan); *pmpeg = &mpeg->engine; - return nvkm_engine_ctor(&nv44_mpeg, device, index, 0x00000002, - true, &mpeg->engine); + return nvkm_engine_ctor(&nv44_mpeg, device, index, true, &mpeg->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c index c3a85dffc782..4e528851e9c0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c @@ -130,6 +130,5 @@ nv50_mpeg = { int nv50_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg) { - return nvkm_engine_new_(&nv50_mpeg, device, index, 0x00400002, - true, pmpeg); + return nvkm_engine_new_(&nv50_mpeg, device, index, true, pmpeg); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c index 1f1a99e927b2..f30cf1dcfb30 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c @@ -35,7 +35,6 @@ g98_mspdec_init(struct nvkm_falcon *mspdec) static const struct nvkm_falcon_func g98_mspdec = { - .pmc_enable = 0x01020000, .init = g98_mspdec_init, .sclass = { { -1, -1, G98_MSPDEC }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c index 371fd6c3c663..cfe1aa81bd14 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c @@ -35,7 +35,6 @@ gf100_mspdec_init(struct nvkm_falcon *mspdec) static const struct nvkm_falcon_func gf100_mspdec = { - .pmc_enable = 0x00020000, .init = gf100_mspdec_init, .sclass = { { -1, -1, GF100_MSPDEC }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c index de804a15bfd4..24272b4927bc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c @@ -27,7 +27,6 @@ static const struct nvkm_falcon_func gk104_mspdec = { - .pmc_enable = 0x00020000, .init = gf100_mspdec_init, .sclass = { { -1, -1, GK104_MSPDEC }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c index 835631713c95..cf6e59ad6ee2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c @@ -27,7 +27,6 @@ static const struct nvkm_falcon_func gt215_mspdec = { - .pmc_enable = 0x01020000, .init = g98_mspdec_init, .sclass = { { -1, -1, GT212_MSPDEC }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c index 73f633ae2ee7..c45dbf79d1f9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c @@ -35,7 +35,6 @@ g98_msppp_init(struct nvkm_falcon *msppp) static const struct nvkm_falcon_func g98_msppp = { - .pmc_enable = 0x00400002, .init = g98_msppp_init, .sclass = { { -1, -1, G98_MSPPP }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c index c42c0c07e2db..803c62ab516e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c @@ -35,7 +35,6 @@ gf100_msppp_init(struct nvkm_falcon *msppp) static const struct nvkm_falcon_func gf100_msppp = { - .pmc_enable = 0x00000002, .init = gf100_msppp_init, .sclass = { { -1, -1, GF100_MSPPP }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c index 00e7795f1d51..49cbf72cee4b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c @@ -27,7 +27,6 @@ static const struct nvkm_falcon_func gt215_msppp = { - .pmc_enable = 0x00400002, .init = g98_msppp_init, .sclass = { { -1, -1, GT212_MSPPP }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c index 47e2929bfaf0..4a2a9f0494af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c @@ -35,7 +35,6 @@ g98_msvld_init(struct nvkm_falcon *msvld) static const struct nvkm_falcon_func g98_msvld = { - .pmc_enable = 0x04008000, .init = g98_msvld_init, .sclass = { { -1, -1, G98_MSVLD }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c index 1ac581ba9f96..1695e532c081 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c @@ -35,7 +35,6 @@ gf100_msvld_init(struct nvkm_falcon *msvld) static const struct nvkm_falcon_func gf100_msvld = { - .pmc_enable = 0x00008000, .init = gf100_msvld_init, .sclass = { { -1, -1, GF100_MSVLD }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c index 4bba16e0f560..b640cd63ebe8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c @@ -27,7 +27,6 @@ static const struct nvkm_falcon_func gk104_msvld = { - .pmc_enable = 0x00008000, .init = gf100_msvld_init, .sclass = { { -1, -1, GK104_MSVLD }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c index e17cb5605b2d..201e8ef3519e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c @@ -27,7 +27,6 @@ static const struct nvkm_falcon_func gt215_msvld = { - .pmc_enable = 0x04008000, .init = g98_msvld_init, .sclass = { { -1, -1, GT212_MSVLD }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c index 511800f6a43b..a0f540ef257b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c @@ -27,7 +27,6 @@ static const struct nvkm_falcon_func mcp89_msvld = { - .pmc_enable = 0x04008000, .init = g98_msvld_init, .sclass = { { -1, -1, IGT21A_MSVLD }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c index f19fabef8d73..8616636ad7b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c @@ -863,5 +863,5 @@ nvkm_pm_ctor(const struct nvkm_pm_func *func, struct nvkm_device *device, pm->func = func; INIT_LIST_HEAD(&pm->domains); INIT_LIST_HEAD(&pm->sources); - return nvkm_engine_ctor(&nvkm_pm, device, index, 0, true, &pm->engine); + return nvkm_engine_ctor(&nvkm_pm, device, index, true, &pm->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c index 995c2c5ec150..6d2a7f0afbb5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c @@ -66,7 +66,6 @@ g98_sec = { .code.size = sizeof(g98_sec_code), .data.data = g98_sec_data, .data.size = sizeof(g98_sec_data), - .pmc_enable = 0x00004000, .intr = g98_sec_intr, .sclass = { { -1, -1, G98_SEC }, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c index 53c1f7e75b54..7be3198e11de 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c @@ -106,5 +106,5 @@ nvkm_sw_new_(const struct nvkm_sw_func *func, struct nvkm_device *device, INIT_LIST_HEAD(&sw->chan); sw->func = func; - return nvkm_engine_ctor(&nvkm_sw, device, index, 0, true, &sw->engine); + return nvkm_engine_ctor(&nvkm_sw, device, index, true, &sw->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c index 4188c77ac927..7a96178786c4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c @@ -27,7 +27,6 @@ static const struct nvkm_xtensa_func g84_vp = { - .pmc_enable = 0x01020000, .fifo_val = 0x111, .unkd28 = 0x9c544, .sclass = { diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c index a3d4f5bcec7a..06bdb67a0205 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c @@ -187,6 +187,6 @@ nvkm_xtensa_new_(const struct nvkm_xtensa_func *func, xtensa->addr = addr; *pengine = &xtensa->engine; - return nvkm_engine_ctor(&nvkm_xtensa, device, index, func->pmc_enable, + return nvkm_engine_ctor(&nvkm_xtensa, device, index, enable, &xtensa->engine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild index 642d27dc99a3..3f5d38d74fba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild @@ -19,4 +19,5 @@ include $(src)/nvkm/subdev/pmu/Kbuild include $(src)/nvkm/subdev/secboot/Kbuild include $(src)/nvkm/subdev/therm/Kbuild include $(src)/nvkm/subdev/timer/Kbuild +include $(src)/nvkm/subdev/top/Kbuild include $(src)/nvkm/subdev/volt/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index a9433ad45b1e..c561d148cebc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -77,7 +77,7 @@ void nvkm_bar_ctor(const struct nvkm_bar_func *func, struct nvkm_device *device, int index, struct nvkm_bar *bar) { - nvkm_subdev_ctor(&nvkm_bar, device, index, 0, &bar->subdev); + nvkm_subdev_ctor(&nvkm_bar, device, index, &bar->subdev); bar->func = func; spin_lock_init(&bar->lock); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c index 79536897efaa..e15b9627b07e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c @@ -105,7 +105,7 @@ nvkm_bios_new(struct nvkm_device *device, int index, struct nvkm_bios **pbios) if (!(bios = *pbios = kzalloc(sizeof(*bios), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_bios, device, index, 0, &bios->subdev); + nvkm_subdev_ctor(&nvkm_bios, device, index, &bios->subdev); ret = nvbios_shadow(bios); if (ret) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c index 125ec2ed6c2e..91a7dc56e406 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c @@ -81,9 +81,11 @@ static u16 pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { struct bit_entry bit_C; + u16 data = 0x0000; - if (!bit_entry(bios, 'C', &bit_C) && bit_C.length >= 10) { - u16 data = nvbios_rd16(bios, bit_C.offset + 8); + if (!bit_entry(bios, 'C', &bit_C)) { + if (bit_C.version == 1 && bit_C.length >= 10) + data = nvbios_rd16(bios, bit_C.offset + 8); if (data) { *ver = nvbios_rd08(bios, data + 0); *hdr = nvbios_rd08(bios, data + 1); @@ -94,7 +96,7 @@ pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) } if (bmp_version(bios) >= 0x0524) { - u16 data = nvbios_rd16(bios, bios->bmp_offset + 142); + data = nvbios_rd16(bios, bios->bmp_offset + 142); if (data) { *ver = nvbios_rd08(bios, data + 0); *hdr = 1; @@ -105,7 +107,7 @@ pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) } *ver = 0x00; - return 0x0000; + return data; } static struct pll_mapping * @@ -156,7 +158,7 @@ pll_map_reg(struct nvkm_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len) } map = pll_map(bios); - while (map->reg) { + while (map && map->reg) { if (map->reg == reg && *ver >= 0x20) { u16 addr = (data += hdr); *type = map->type; @@ -198,7 +200,7 @@ pll_map_type(struct nvkm_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len) } map = pll_map(bios); - while (map->reg) { + while (map && map->reg) { if (map->type == type && *ver >= 0x20) { u16 addr = (data += hdr); *reg = map->reg; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c index dc5a10f18bdb..52ad73bce5fe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c @@ -58,7 +58,7 @@ nvkm_bus_new_(const struct nvkm_bus_func *func, struct nvkm_device *device, struct nvkm_bus *bus; if (!(bus = *pbus = kzalloc(sizeof(*bus), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_bus, device, index, 0, &bus->subdev); + nvkm_subdev_ctor(&nvkm_bus, device, index, &bus->subdev); bus->func = func; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c index 889cce2eb727..7102c25320fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -564,7 +564,7 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device, int ret, idx, arglen; const char *mode; - nvkm_subdev_ctor(&nvkm_clk, device, index, 0, &clk->subdev); + nvkm_subdev_ctor(&nvkm_clk, device, index, &clk->subdev); clk->func = func; INIT_LIST_HEAD(&clk->states); clk->domains = func->domains; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c index 5f25402f6b09..4756019ddf3f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c @@ -83,6 +83,12 @@ nvkm_devinit_preinit(struct nvkm_subdev *subdev) if (init->func->preinit) init->func->preinit(init); + /* Override the post flag during the first call if NvForcePost is set */ + if (init->force_post) { + init->post = init->force_post; + init->force_post = false; + } + /* unlock the extended vga crtc regs */ nvkm_lockvgac(subdev->device, false); return 0; @@ -124,7 +130,7 @@ nvkm_devinit_ctor(const struct nvkm_devinit_func *func, struct nvkm_device *device, int index, struct nvkm_devinit *init) { - nvkm_subdev_ctor(&nvkm_devinit, device, index, 0, &init->subdev); + nvkm_subdev_ctor(&nvkm_devinit, device, index, &init->subdev); init->func = func; - init->post = nvkm_boolopt(device->cfgopt, "NvForcePost", false); + init->force_post = nvkm_boolopt(device->cfgopt, "NvForcePost", false); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c index 2923598b5fe9..8b1b34c3ad26 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c @@ -97,9 +97,11 @@ gf100_devinit_preinit(struct nvkm_devinit *base) struct nvkm_subdev *subdev = &init->base.subdev; struct nvkm_device *device = subdev->device; - /* This bit is set by devinit, and flips back to 0 on suspend */ - if (!base->post) - base->post = ((nvkm_rd32(device, 0x2240c) & BIT(1)) == 0); + /* + * This bit is set by devinit, and flips back to 0 on suspend. We + * can use it as a reliable way to know whether we should run devinit. + */ + base->post = ((nvkm_rd32(device, 0x2240c) & BIT(1)) == 0); } static const struct nvkm_devinit_func diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild index 08105701af7e..842d5de96d73 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild @@ -23,6 +23,7 @@ nvkm-y += nvkm/subdev/fb/gf100.o nvkm-y += nvkm/subdev/fb/gk104.o nvkm-y += nvkm/subdev/fb/gk20a.o nvkm-y += nvkm/subdev/fb/gm107.o +nvkm-y += nvkm/subdev/fb/gm200.o nvkm-y += nvkm/subdev/fb/ram.o nvkm-y += nvkm/subdev/fb/ramnv04.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index a719b9becb73..ce90242b8cce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -24,6 +24,7 @@ #include "priv.h" #include "ram.h" +#include <core/memory.h> #include <subdev/bios.h> #include <subdev/bios/M0203.h> #include <engine/gr.h> @@ -98,6 +99,7 @@ static int nvkm_fb_oneinit(struct nvkm_subdev *subdev) { struct nvkm_fb *fb = nvkm_fb(subdev); + if (fb->func->ram_new) { int ret = fb->func->ram_new(fb, &fb->ram); if (ret) { @@ -105,6 +107,13 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev) return ret; } } + + if (fb->func->oneinit) { + int ret = fb->func->oneinit(fb); + if (ret) + return ret; + } + return 0; } @@ -134,6 +143,9 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev) struct nvkm_fb *fb = nvkm_fb(subdev); int i; + nvkm_memory_del(&fb->mmu_wr); + nvkm_memory_del(&fb->mmu_rd); + for (i = 0; i < fb->tile.regions; i++) fb->func->tile.fini(fb, i, &fb->tile.region[i]); @@ -156,7 +168,7 @@ void nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, int index, struct nvkm_fb *fb) { - nvkm_subdev_ctor(&nvkm_fb, device, index, 0, &fb->subdev); + nvkm_subdev_ctor(&nvkm_fb, device, index, &fb->subdev); fb->func = func; fb->tile.regions = fb->func->tile.regions; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index 008bb9849f3b..e649ead5ccfc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c @@ -24,6 +24,9 @@ #include "gf100.h" #include "ram.h" +#include <core/memory.h> +#include <core/option.h> + extern const u8 gf100_pte_storage_type_map[256]; bool @@ -46,6 +49,28 @@ gf100_fb_intr(struct nvkm_fb *base) nvkm_debug(subdev, "PBFB intr\n"); } +int +gf100_fb_oneinit(struct nvkm_fb *fb) +{ + struct nvkm_device *device = fb->subdev.device; + int ret, size = 0x1000; + + size = nvkm_longopt(device->cfgopt, "MmuDebugBufferSize", size); + size = min(size, 0x1000); + + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000, + false, &fb->mmu_rd); + if (ret) + return ret; + + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000, + false, &fb->mmu_wr); + if (ret) + return ret; + + return 0; +} + void gf100_fb_init(struct nvkm_fb *base) { @@ -98,6 +123,7 @@ gf100_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device, static const struct nvkm_fb_func gf100_fb = { .dtor = gf100_fb_dtor, + .oneinit = gf100_fb_oneinit, .init = gf100_fb_init, .intr = gf100_fb_intr, .ram_new = gf100_ram_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c index 0edb3c316f5c..b41f0f70038c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c @@ -27,6 +27,7 @@ static const struct nvkm_fb_func gk104_fb = { .dtor = gf100_fb_dtor, + .oneinit = gf100_fb_oneinit, .init = gf100_fb_init, .intr = gf100_fb_intr, .ram_new = gk104_ram_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c index 81447eb4c948..7306f7dfc3b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c @@ -21,15 +21,20 @@ */ #include "priv.h" +#include <core/memory.h> + static void gk20a_fb_init(struct nvkm_fb *fb) { struct nvkm_device *device = fb->subdev.device; nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */ + nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->mmu_wr) >> 8); + nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->mmu_rd) >> 8); } static const struct nvkm_fb_func gk20a_fb = { + .oneinit = gf100_fb_oneinit, .init = gk20a_fb_init, .memtype_valid = gf100_fb_memtype_valid, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c index 2a91df8655dd..4869fdb753c9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c @@ -27,6 +27,7 @@ static const struct nvkm_fb_func gm107_fb = { .dtor = gf100_fb_dtor, + .oneinit = gf100_fb_oneinit, .init = gf100_fb_init, .intr = gf100_fb_intr, .ram_new = gm107_ram_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c new file mode 100644 index 000000000000..44f5716f64d8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c @@ -0,0 +1,60 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ +#include "gf100.h" +#include "ram.h" + +#include <core/memory.h> + +static void +gm200_fb_init(struct nvkm_fb *base) +{ + struct gf100_fb *fb = gf100_fb(base); + struct nvkm_device *device = fb->base.subdev.device; + + if (fb->r100c10_page) + nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8); + + nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */ + + nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->base.mmu_wr) >> 8); + nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->base.mmu_rd) >> 8); + nvkm_mask(device, 0x100cc4, 0x00060000, + min(nvkm_memory_size(fb->base.mmu_rd) >> 16, (u64)2) << 17); +} + +static const struct nvkm_fb_func +gm200_fb = { + .dtor = gf100_fb_dtor, + .oneinit = gf100_fb_oneinit, + .init = gm200_fb_init, + .intr = gf100_fb_intr, + .ram_new = gm107_ram_new, + .memtype_valid = gf100_fb_memtype_valid, +}; + +int +gm200_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) +{ + return gf100_fb_new_(&gm200_fb, device, index, pfb); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index 62b9feb531dc..d97d640e60a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -6,6 +6,7 @@ struct nvkm_bios; struct nvkm_fb_func { void *(*dtor)(struct nvkm_fb *); + int (*oneinit)(struct nvkm_fb *); void (*init)(struct nvkm_fb *); void (*intr)(struct nvkm_fb *); @@ -58,5 +59,6 @@ void nv44_fb_tile_prog(struct nvkm_fb *, int, struct nvkm_fb_tile *); void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, u32 pitch, u32 flags, struct nvkm_fb_tile *); +int gf100_fb_oneinit(struct nvkm_fb *); bool gf100_fb_memtype_valid(struct nvkm_fb *, u32); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c index f4144979a79c..1c3c18ea8ced 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c @@ -47,7 +47,7 @@ nvkm_fuse_new_(const struct nvkm_fuse_func *func, struct nvkm_device *device, struct nvkm_fuse *fuse; if (!(fuse = *pfuse = kzalloc(sizeof(*fuse), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_fuse, device, index, 0, &fuse->subdev); + nvkm_subdev_ctor(&nvkm_fuse, device, index, &fuse->subdev); fuse->func = func; spin_lock_init(&fuse->lock); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c index d45ec99f0e38..77c649723ad7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c @@ -216,7 +216,7 @@ nvkm_gpio_new_(const struct nvkm_gpio_func *func, struct nvkm_device *device, if (!(gpio = *pgpio = kzalloc(sizeof(*gpio), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_gpio, device, index, 0, &gpio->subdev); + nvkm_subdev_ctor(&nvkm_gpio, device, index, &gpio->subdev); gpio->func = func; return nvkm_event_init(&nvkm_gpio_intr_func, 2, func->lines, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 243a71ff0a0d..4f197b15acf6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c @@ -254,7 +254,7 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device, if (!(i2c = *pi2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_i2c, device, index, 0, &i2c->subdev); + nvkm_subdev_ctor(&nvkm_i2c, device, index, &i2c->subdev); i2c->func = func; INIT_LIST_HEAD(&i2c->pad); INIT_LIST_HEAD(&i2c->bus); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c index 72d6330d243d..2c6b374f1420 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c @@ -117,6 +117,6 @@ gf100_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev *ibus; if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&gf100_ibus, device, index, 0, ibus); + nvkm_subdev_ctor(&gf100_ibus, device, index, ibus); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c index f69f263c5906..3905a80da811 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c @@ -46,6 +46,6 @@ gf117_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev *ibus; if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&gf117_ibus, device, index, 0, ibus); + nvkm_subdev_ctor(&gf117_ibus, device, index, ibus); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c index b5cee3f89aaa..c673853f3213 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c @@ -120,6 +120,6 @@ gk104_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev *ibus; if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&gk104_ibus, device, index, 0, ibus); + nvkm_subdev_ctor(&gk104_ibus, device, index, ibus); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c index 3484079e885a..b7159b338fac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c @@ -84,6 +84,6 @@ gk20a_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev *ibus; if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&gk20a_ibus, device, index, 0, ibus); + nvkm_subdev_ctor(&gk20a_ibus, device, index, ibus); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c index ef0b7f3b1128..c63328152bfa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c @@ -35,6 +35,6 @@ gm200_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev *ibus; if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&gm200_ibus, device, index, 0, ibus); + nvkm_subdev_ctor(&gm200_ibus, device, index, ibus); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c index c44a85228074..323c79abe468 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c @@ -30,15 +30,14 @@ static bool nvkm_iccsense_validate_device(struct i2c_adapter *i2c, u8 addr, - enum nvbios_extdev_type type, u8 rail) + enum nvbios_extdev_type type) { switch (type) { case NVBIOS_EXTDEV_INA209: case NVBIOS_EXTDEV_INA219: - return rail == 0 && nv_rd16i2cr(i2c, addr, 0x0) >= 0; + return nv_rd16i2cr(i2c, addr, 0x0) >= 0; case NVBIOS_EXTDEV_INA3221: - return rail <= 3 && - nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 && + return nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 && nv_rd16i2cr(i2c, addr, 0xfe) == 0x5449; default: return false; @@ -67,8 +66,9 @@ nvkm_iccsense_ina2x9_read(struct nvkm_iccsense *iccsense, struct nvkm_iccsense_rail *rail, u8 shunt_reg, u8 bus_reg) { - return nvkm_iccsense_poll_lane(rail->i2c, rail->addr, shunt_reg, 0, - bus_reg, 3, rail->mohm, 10 * 4); + return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr, + shunt_reg, 0, bus_reg, 3, rail->mohm, + 10 * 4); } static int @@ -89,37 +89,87 @@ static int nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense, struct nvkm_iccsense_rail *rail) { - return nvkm_iccsense_poll_lane(rail->i2c, rail->addr, - 1 + (rail->rail * 2), 3, - 2 + (rail->rail * 2), 3, rail->mohm, + return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr, + 1 + (rail->idx * 2), 3, + 2 + (rail->idx * 2), 3, rail->mohm, 40 * 8); } -int -nvkm_iccsense_read(struct nvkm_iccsense *iccsense, u8 idx) +static void +nvkm_iccsense_ina209_config(struct nvkm_iccsense *iccsense, + struct nvkm_iccsense_sensor *sensor) { - struct nvkm_iccsense_rail *rail; - - if (!iccsense || idx >= iccsense->rail_count) - return -EINVAL; + struct nvkm_subdev *subdev = &iccsense->subdev; + /* configuration: + * 0x0007: 0x0007 shunt and bus continous + * 0x0078: 0x0078 128 samples shunt + * 0x0780: 0x0780 128 samples bus + * 0x1800: 0x0000 +-40 mV shunt range + * 0x2000: 0x0000 16V FSR + */ + u16 value = 0x07ff; + nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value); + nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value); +} - rail = &iccsense->rails[idx]; - if (!rail->read) - return -ENODEV; +static void +nvkm_iccsense_ina3221_config(struct nvkm_iccsense *iccsense, + struct nvkm_iccsense_sensor *sensor) +{ + struct nvkm_subdev *subdev = &iccsense->subdev; + /* configuration: + * 0x0007: 0x0007 shunt and bus continous + * 0x0031: 0x0000 140 us conversion time shunt + * 0x01c0: 0x0000 140 us conversion time bus + * 0x0f00: 0x0f00 1024 samples + * 0x7000: 0x?000 channels + */ + u16 value = 0x0e07; + if (sensor->rail_mask & 0x1) + value |= 0x1 << 14; + if (sensor->rail_mask & 0x2) + value |= 0x1 << 13; + if (sensor->rail_mask & 0x4) + value |= 0x1 << 12; + nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value); + nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value); +} - return rail->read(iccsense, rail); +static void +nvkm_iccsense_sensor_config(struct nvkm_iccsense *iccsense, + struct nvkm_iccsense_sensor *sensor) +{ + switch (sensor->type) { + case NVBIOS_EXTDEV_INA209: + case NVBIOS_EXTDEV_INA219: + nvkm_iccsense_ina209_config(iccsense, sensor); + break; + case NVBIOS_EXTDEV_INA3221: + nvkm_iccsense_ina3221_config(iccsense, sensor); + break; + default: + break; + } } int nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense) { - int result = 0, i; - for (i = 0; i < iccsense->rail_count; ++i) { - int res = nvkm_iccsense_read(iccsense, i); - if (res >= 0) - result += res; - else + int result = 0; + struct nvkm_iccsense_rail *rail; + + if (!iccsense) + return -EINVAL; + + list_for_each_entry(rail, &iccsense->rails, head) { + int res; + if (!rail->read) + return -ENODEV; + + res = rail->read(iccsense, rail); + if (res < 0) return res; + result += res; } return result; } @@ -128,89 +178,158 @@ static void * nvkm_iccsense_dtor(struct nvkm_subdev *subdev) { struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev); + struct nvkm_iccsense_sensor *sensor, *tmps; + struct nvkm_iccsense_rail *rail, *tmpr; - if (iccsense->rails) - kfree(iccsense->rails); + list_for_each_entry_safe(sensor, tmps, &iccsense->sensors, head) { + list_del(&sensor->head); + kfree(sensor); + } + list_for_each_entry_safe(rail, tmpr, &iccsense->rails, head) { + list_del(&rail->head); + kfree(rail); + } return iccsense; } +static struct nvkm_iccsense_sensor* +nvkm_iccsense_create_sensor(struct nvkm_iccsense *iccsense, u8 id) +{ + + struct nvkm_subdev *subdev = &iccsense->subdev; + struct nvkm_bios *bios = subdev->device->bios; + struct nvkm_i2c *i2c = subdev->device->i2c; + struct nvbios_extdev_func extdev; + struct nvkm_i2c_bus *i2c_bus; + struct nvkm_iccsense_sensor *sensor; + u8 addr; + + if (!i2c || !bios || nvbios_extdev_parse(bios, id, &extdev)) + return NULL; + + if (extdev.type == 0xff) + return NULL; + + if (extdev.type != NVBIOS_EXTDEV_INA209 && + extdev.type != NVBIOS_EXTDEV_INA219 && + extdev.type != NVBIOS_EXTDEV_INA3221) { + iccsense->data_valid = false; + nvkm_error(subdev, "Unknown sensor type %x, power reading " + "disabled\n", extdev.type); + return NULL; + } + + if (extdev.bus) + i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC); + else + i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI); + if (!i2c_bus) + return NULL; + + addr = extdev.addr >> 1; + if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr, + extdev.type)) { + iccsense->data_valid = false; + nvkm_warn(subdev, "found invalid sensor id: %i, power reading" + "might be invalid\n", id); + return NULL; + } + + sensor = kmalloc(sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return NULL; + + list_add_tail(&sensor->head, &iccsense->sensors); + sensor->id = id; + sensor->type = extdev.type; + sensor->i2c = &i2c_bus->i2c; + sensor->addr = addr; + sensor->rail_mask = 0x0; + return sensor; +} + +static struct nvkm_iccsense_sensor* +nvkm_iccsense_get_sensor(struct nvkm_iccsense *iccsense, u8 id) +{ + struct nvkm_iccsense_sensor *sensor; + list_for_each_entry(sensor, &iccsense->sensors, head) { + if (sensor->id == id) + return sensor; + } + return nvkm_iccsense_create_sensor(iccsense, id); +} + static int nvkm_iccsense_oneinit(struct nvkm_subdev *subdev) { struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev); struct nvkm_bios *bios = subdev->device->bios; - struct nvkm_i2c *i2c = subdev->device->i2c; struct nvbios_iccsense stbl; int i; - if (!i2c || !bios || nvbios_iccsense_parse(bios, &stbl) - || !stbl.nr_entry) + if (!bios || nvbios_iccsense_parse(bios, &stbl) || !stbl.nr_entry) return 0; - iccsense->rails = kmalloc(sizeof(*iccsense->rails) * stbl.nr_entry, - GFP_KERNEL); - if (!iccsense->rails) - return -ENOMEM; - iccsense->data_valid = true; for (i = 0; i < stbl.nr_entry; ++i) { struct pwr_rail_t *r = &stbl.rail[i]; - struct nvbios_extdev_func extdev; struct nvkm_iccsense_rail *rail; - struct nvkm_i2c_bus *i2c_bus; - u8 addr; + struct nvkm_iccsense_sensor *sensor; if (!r->mode || r->resistor_mohm == 0) continue; - if (nvbios_extdev_parse(bios, r->extdev_id, &extdev)) + sensor = nvkm_iccsense_get_sensor(iccsense, r->extdev_id); + if (!sensor) continue; - if (extdev.type == 0xff) - continue; + rail = kmalloc(sizeof(*rail), GFP_KERNEL); + if (!rail) + return -ENOMEM; - if (extdev.bus) - i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC); - else - i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI); - if (!i2c_bus) - continue; - - addr = extdev.addr >> 1; - if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr, - extdev.type, r->rail)) { - iccsense->data_valid = false; - nvkm_warn(subdev, "found unknown or invalid rail entry" - " type 0x%x rail %i, power reading might be" - " invalid\n", extdev.type, r->rail); - continue; - } - - rail = &iccsense->rails[iccsense->rail_count]; - switch (extdev.type) { + switch (sensor->type) { case NVBIOS_EXTDEV_INA209: + if (r->rail != 0) + continue; rail->read = nvkm_iccsense_ina209_read; break; case NVBIOS_EXTDEV_INA219: + if (r->rail != 0) + continue; rail->read = nvkm_iccsense_ina219_read; break; case NVBIOS_EXTDEV_INA3221: + if (r->rail >= 3) + continue; rail->read = nvkm_iccsense_ina3221_read; break; + default: + continue; } - rail->addr = addr; - rail->rail = r->rail; + sensor->rail_mask |= 1 << r->rail; + rail->sensor = sensor; + rail->idx = r->rail; rail->mohm = r->resistor_mohm; - rail->i2c = &i2c_bus->i2c; - ++iccsense->rail_count; + list_add_tail(&rail->head, &iccsense->rails); } return 0; } +static int +nvkm_iccsense_init(struct nvkm_subdev *subdev) +{ + struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev); + struct nvkm_iccsense_sensor *sensor; + list_for_each_entry(sensor, &iccsense->sensors, head) + nvkm_iccsense_sensor_config(iccsense, sensor); + return 0; +} + struct nvkm_subdev_func iccsense_func = { .oneinit = nvkm_iccsense_oneinit, + .init = nvkm_iccsense_init, .dtor = nvkm_iccsense_dtor, }; @@ -218,7 +337,7 @@ void nvkm_iccsense_ctor(struct nvkm_device *device, int index, struct nvkm_iccsense *iccsense) { - nvkm_subdev_ctor(&iccsense_func, device, index, 0, &iccsense->subdev); + nvkm_subdev_ctor(&iccsense_func, device, index, &iccsense->subdev); } int @@ -227,6 +346,8 @@ nvkm_iccsense_new_(struct nvkm_device *device, int index, { if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL))) return -ENOMEM; + INIT_LIST_HEAD(&(*iccsense)->sensors); + INIT_LIST_HEAD(&(*iccsense)->rails); nvkm_iccsense_ctor(device, index, *iccsense); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h index ed398b81e86e..b72c31d2f908 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h @@ -2,12 +2,22 @@ #define __NVKM_ICCSENSE_PRIV_H__ #define nvkm_iccsense(p) container_of((p), struct nvkm_iccsense, subdev) #include <subdev/iccsense.h> +#include <subdev/bios/extdev.h> -struct nvkm_iccsense_rail { - int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *); +struct nvkm_iccsense_sensor { + struct list_head head; + int id; + enum nvbios_extdev_type type; struct i2c_adapter *i2c; u8 addr; - u8 rail; + u8 rail_mask; +}; + +struct nvkm_iccsense_rail { + struct list_head head; + int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *); + struct nvkm_iccsense_sensor *sensor; + u8 idx; u8 mohm; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c index 1d7dd38292b3..8ed8f65ff664 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -311,7 +311,7 @@ nvkm_instmem_ctor(const struct nvkm_instmem_func *func, struct nvkm_device *device, int index, struct nvkm_instmem *imem) { - nvkm_subdev_ctor(&nvkm_instmem, device, index, 0, &imem->subdev); + nvkm_subdev_ctor(&nvkm_instmem, device, index, &imem->subdev); imem->func = func; spin_lock_init(&imem->lock); INIT_LIST_HEAD(&imem->list); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index 85b1464c0194..39c2a38e54f7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -138,7 +138,7 @@ nvkm_ltc_new_(const struct nvkm_ltc_func *func, struct nvkm_device *device, if (!(ltc = *pltc = kzalloc(sizeof(*ltc), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_ltc, device, index, 0, <c->subdev); + nvkm_subdev_ctor(&nvkm_ltc, device, index, <c->subdev); ltc->func = func; ltc->zbc_min = 1; /* reserve 0 for disabled */ ltc->zbc_max = min(func->zbc, NVKM_LTC_MAX_ZBC_CNT) - 1; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild index bef325dcb4d0..49695ac7be2e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild @@ -1,7 +1,12 @@ nvkm-y += nvkm/subdev/mc/base.o nvkm-y += nvkm/subdev/mc/nv04.o +nvkm-y += nvkm/subdev/mc/nv11.o +nvkm-y += nvkm/subdev/mc/nv17.o nvkm-y += nvkm/subdev/mc/nv44.o nvkm-y += nvkm/subdev/mc/nv50.o +nvkm-y += nvkm/subdev/mc/g84.o nvkm-y += nvkm/subdev/mc/g98.o +nvkm-y += nvkm/subdev/mc/gt215.o nvkm-y += nvkm/subdev/mc/gf100.o +nvkm-y += nvkm/subdev/mc/gk104.o nvkm-y += nvkm/subdev/mc/gk20a.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c index 954fbbe56c4b..350a8caa84c8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c @@ -24,6 +24,7 @@ #include "priv.h" #include <core/option.h> +#include <subdev/top.h> void nvkm_mc_unk260(struct nvkm_mc *mc, u32 data) @@ -58,10 +59,19 @@ nvkm_mc_intr(struct nvkm_mc *mc, bool *handled) { struct nvkm_device *device = mc->subdev.device; struct nvkm_subdev *subdev; - const struct nvkm_mc_intr *map = mc->func->intr; - u32 stat, intr; + const struct nvkm_mc_map *map = mc->func->intr; + u32 stat, intr = nvkm_mc_intr_mask(mc); + u64 subdevs; + + stat = nvkm_top_intr(device->top, intr, &subdevs); + while (subdevs) { + enum nvkm_devidx subidx = __ffs64(subdevs); + subdev = nvkm_device_subdev(device, subidx); + if (subdev) + nvkm_subdev_intr(subdev); + subdevs &= ~BIT_ULL(subidx); + } - stat = intr = nvkm_mc_intr_mask(mc); while (map->stat) { if (intr & map->stat) { subdev = nvkm_device_subdev(device, map->unit); @@ -77,6 +87,36 @@ nvkm_mc_intr(struct nvkm_mc *mc, bool *handled) *handled = intr != 0; } +static void +nvkm_mc_reset_(struct nvkm_mc *mc, enum nvkm_devidx devidx) +{ + struct nvkm_device *device = mc->subdev.device; + const struct nvkm_mc_map *map; + u64 pmc_enable; + + if (!(pmc_enable = nvkm_top_reset(device->top, devidx))) { + for (map = mc->func->reset; map && map->stat; map++) { + if (map->unit == devidx) { + pmc_enable = map->stat; + break; + } + } + } + + if (pmc_enable) { + nvkm_mask(device, 0x000200, pmc_enable, 0x00000000); + nvkm_mask(device, 0x000200, pmc_enable, pmc_enable); + nvkm_rd32(device, 0x000200); + } +} + +void +nvkm_mc_reset(struct nvkm_mc *mc, enum nvkm_devidx devidx) +{ + if (likely(mc)) + nvkm_mc_reset_(mc, devidx); +} + static int nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend) { @@ -117,7 +157,7 @@ nvkm_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device, if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_mc, device, index, 0, &mc->subdev); + nvkm_subdev_ctor(&nvkm_mc, device, index, &mc->subdev); mc->func = func; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c new file mode 100644 index 000000000000..5c85b47f071d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_map +g84_mc_reset[] = { + { 0x04008000, NVKM_ENGINE_BSP }, + { 0x02004000, NVKM_ENGINE_CIPHER }, + { 0x01020000, NVKM_ENGINE_VP }, + { 0x00400002, NVKM_ENGINE_MPEG }, + { 0x00201000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +const struct nvkm_mc_map +g84_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00020000, NVKM_ENGINE_VP }, + { 0x00008000, NVKM_ENGINE_BSP }, + { 0x00004000, NVKM_ENGINE_CIPHER }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MPEG }, + { 0x0002d101, NVKM_SUBDEV_FB }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {}, +}; + +static const struct nvkm_mc_func +g84_mc = { + .init = nv50_mc_init, + .intr = g84_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_mask = nv04_mc_intr_mask, + .reset = g84_mc_reset, +}; + +int +g84_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&g84_mc, device, index, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c index 7344ad659105..0280b43cc10c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c @@ -23,24 +23,31 @@ */ #include "priv.h" -static const struct nvkm_mc_intr -g98_mc_intr[] = { - { 0x04000000, NVKM_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */ - { 0x00000001, NVKM_ENGINE_MSPPP }, +static const struct nvkm_mc_map +g98_mc_reset[] = { + { 0x04008000, NVKM_ENGINE_MSVLD }, + { 0x02004000, NVKM_ENGINE_SEC }, + { 0x01020000, NVKM_ENGINE_MSPDEC }, + { 0x00400002, NVKM_ENGINE_MSPPP }, + { 0x00201000, NVKM_ENGINE_GR }, { 0x00000100, NVKM_ENGINE_FIFO }, - { 0x00001000, NVKM_ENGINE_GR }, - { 0x00004000, NVKM_ENGINE_SEC }, /* NV84:NVA3 */ - { 0x00008000, NVKM_ENGINE_MSVLD }, + {} +}; + +static const struct nvkm_mc_map +g98_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, { 0x00020000, NVKM_ENGINE_MSPDEC }, - { 0x00040000, NVKM_SUBDEV_PMU }, /* NVA3:NVC0 */ - { 0x00080000, NVKM_SUBDEV_THERM }, /* NVA3:NVC0 */ - { 0x00100000, NVKM_SUBDEV_TIMER }, - { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */ - { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */ - { 0x00400000, NVKM_ENGINE_CE0 }, /* NVA3- */ + { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00004000, NVKM_ENGINE_SEC }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MSPPP }, + { 0x0002d101, NVKM_SUBDEV_FB }, { 0x10000000, NVKM_SUBDEV_BUS }, - { 0x80000000, NVKM_ENGINE_SW }, - { 0x0042d101, NVKM_SUBDEV_FB }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, {}, }; @@ -51,6 +58,7 @@ g98_mc = { .intr_unarm = nv04_mc_intr_unarm, .intr_rearm = nv04_mc_intr_rearm, .intr_mask = nv04_mc_intr_mask, + .reset = g98_mc_reset, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c index 122fe69e83e4..8397e223bd43 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c @@ -23,28 +23,38 @@ */ #include "priv.h" -const struct nvkm_mc_intr -gf100_mc_intr[] = { - { 0x04000000, NVKM_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */ - { 0x00000001, NVKM_ENGINE_MSPPP }, - { 0x00000020, NVKM_ENGINE_CE0 }, - { 0x00000040, NVKM_ENGINE_CE1 }, - { 0x00000080, NVKM_ENGINE_CE2 }, - { 0x00000100, NVKM_ENGINE_FIFO }, - { 0x00001000, NVKM_ENGINE_GR }, - { 0x00002000, NVKM_SUBDEV_FB }, +static const struct nvkm_mc_map +gf100_mc_reset[] = { + { 0x00020000, NVKM_ENGINE_MSPDEC }, { 0x00008000, NVKM_ENGINE_MSVLD }, - { 0x00040000, NVKM_SUBDEV_THERM }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000080, NVKM_ENGINE_CE1 }, + { 0x00000040, NVKM_ENGINE_CE0 }, + { 0x00000002, NVKM_ENGINE_MSPPP }, + {} +}; + +static const struct nvkm_mc_map +gf100_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, { 0x00020000, NVKM_ENGINE_MSPDEC }, - { 0x00100000, NVKM_SUBDEV_TIMER }, - { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */ - { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */ - { 0x01000000, NVKM_SUBDEV_PMU }, - { 0x02000000, NVKM_SUBDEV_LTC }, - { 0x08000000, NVKM_SUBDEV_FB }, - { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000040, NVKM_ENGINE_CE1 }, + { 0x00000020, NVKM_ENGINE_CE0 }, + { 0x00000001, NVKM_ENGINE_MSPPP }, { 0x40000000, NVKM_SUBDEV_IBUS }, - { 0x80000000, NVKM_ENGINE_SW }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x08000000, NVKM_SUBDEV_FB }, + { 0x02000000, NVKM_SUBDEV_LTC }, + { 0x01000000, NVKM_SUBDEV_PMU }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00040000, NVKM_SUBDEV_THERM }, + { 0x00002000, NVKM_SUBDEV_FB }, {}, }; @@ -87,6 +97,7 @@ gf100_mc = { .intr_unarm = gf100_mc_intr_unarm, .intr_rearm = gf100_mc_intr_rearm, .intr_mask = gf100_mc_intr_mask, + .reset = gf100_mc_reset, .unk260 = gf100_mc_unk260, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c new file mode 100644 index 000000000000..317464212c7d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +const struct nvkm_mc_map +gk104_mc_reset[] = { + { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +const struct nvkm_mc_map +gk104_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x40000000, NVKM_SUBDEV_IBUS }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x08000000, NVKM_SUBDEV_FB }, + { 0x02000000, NVKM_SUBDEV_LTC }, + { 0x01000000, NVKM_SUBDEV_PMU }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00040000, NVKM_SUBDEV_THERM }, + { 0x00002000, NVKM_SUBDEV_FB }, + {}, +}; + +static const struct nvkm_mc_func +gk104_mc = { + .init = nv50_mc_init, + .intr = gk104_mc_intr, + .intr_unarm = gf100_mc_intr_unarm, + .intr_rearm = gf100_mc_intr_rearm, + .intr_mask = gf100_mc_intr_mask, + .reset = gk104_mc_reset, + .unk260 = gf100_mc_unk260, +}; + +int +gk104_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&gk104_mc, device, index, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c index d92efb33bcc3..60b044f517ed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c @@ -26,10 +26,11 @@ static const struct nvkm_mc_func gk20a_mc = { .init = nv50_mc_init, - .intr = gf100_mc_intr, + .intr = gk104_mc_intr, .intr_unarm = gf100_mc_intr_unarm, .intr_rearm = gf100_mc_intr_rearm, .intr_mask = gf100_mc_intr_mask, + .reset = gk104_mc_reset, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c new file mode 100644 index 000000000000..aad0ba95bf18 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c @@ -0,0 +1,70 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ +#include "priv.h" + +static const struct nvkm_mc_map +gt215_mc_reset[] = { + { 0x04008000, NVKM_ENGINE_MSVLD }, + { 0x01020000, NVKM_ENGINE_MSPDEC }, + { 0x00802000, NVKM_ENGINE_CE0 }, + { 0x00400002, NVKM_ENGINE_MSPPP }, + { 0x00201000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +static const struct nvkm_mc_map +gt215_mc_intr[] = { + { 0x04000000, NVKM_ENGINE_DISP }, + { 0x00400000, NVKM_ENGINE_CE0 }, + { 0x00020000, NVKM_ENGINE_MSPDEC }, + { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MSPPP }, + { 0x00429101, NVKM_SUBDEV_FB }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + { 0x00080000, NVKM_SUBDEV_THERM }, + { 0x00040000, NVKM_SUBDEV_PMU }, + {}, +}; + +static const struct nvkm_mc_func +gt215_mc = { + .init = nv50_mc_init, + .intr = gt215_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_mask = nv04_mc_intr_mask, + .reset = gt215_mc_reset, +}; + +int +gt215_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(>215_mc, device, index, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c index d282ec1555f8..a062624e906b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c @@ -23,18 +23,20 @@ */ #include "priv.h" -const struct nvkm_mc_intr -nv04_mc_intr[] = { - { 0x00000001, NVKM_ENGINE_MPEG }, /* NV17- MPEG/ME */ +const struct nvkm_mc_map +nv04_mc_reset[] = { + { 0x00001000, NVKM_ENGINE_GR }, { 0x00000100, NVKM_ENGINE_FIFO }, + {} +}; + +static const struct nvkm_mc_map +nv04_mc_intr[] = { + { 0x01010000, NVKM_ENGINE_DISP }, { 0x00001000, NVKM_ENGINE_GR }, - { 0x00010000, NVKM_ENGINE_DISP }, - { 0x00020000, NVKM_ENGINE_VP }, /* NV40- */ - { 0x00100000, NVKM_SUBDEV_TIMER }, - { 0x01000000, NVKM_ENGINE_DISP }, /* NV04- PCRTC0 */ - { 0x02000000, NVKM_ENGINE_DISP }, /* NV11- PCRTC1 */ + { 0x00000100, NVKM_ENGINE_FIFO }, { 0x10000000, NVKM_SUBDEV_BUS }, - { 0x80000000, NVKM_ENGINE_SW }, + { 0x00100000, NVKM_SUBDEV_TIMER }, {} }; @@ -74,6 +76,7 @@ nv04_mc = { .intr_unarm = nv04_mc_intr_unarm, .intr_rearm = nv04_mc_intr_rearm, .intr_mask = nv04_mc_intr_mask, + .reset = nv04_mc_reset, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c new file mode 100644 index 000000000000..55f0b9166b52 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ +#include "priv.h" + +static const struct nvkm_mc_map +nv11_mc_intr[] = { + { 0x03010000, NVKM_ENGINE_DISP }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {} +}; + +static const struct nvkm_mc_func +nv11_mc = { + .init = nv04_mc_init, + .intr = nv11_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_mask = nv04_mc_intr_mask, + .reset = nv04_mc_reset, +}; + +int +nv11_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&nv11_mc, device, index, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c new file mode 100644 index 000000000000..c40fa67f79a5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ +#include "priv.h" + +const struct nvkm_mc_map +nv17_mc_reset[] = { + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000002, NVKM_ENGINE_MPEG }, + {} +}; + +const struct nvkm_mc_map +nv17_mc_intr[] = { + { 0x03010000, NVKM_ENGINE_DISP }, + { 0x00001000, NVKM_ENGINE_GR }, + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MPEG }, + { 0x10000000, NVKM_SUBDEV_BUS }, + { 0x00100000, NVKM_SUBDEV_TIMER }, + {} +}; + +static const struct nvkm_mc_func +nv17_mc = { + .init = nv04_mc_init, + .intr = nv17_mc_intr, + .intr_unarm = nv04_mc_intr_unarm, + .intr_rearm = nv04_mc_intr_rearm, + .intr_mask = nv04_mc_intr_mask, + .reset = nv17_mc_reset, +}; + +int +nv17_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc) +{ + return nvkm_mc_new_(&nv17_mc, device, index, pmc); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c index 9a3ac9965be0..cc56271db564 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c @@ -40,10 +40,11 @@ nv44_mc_init(struct nvkm_mc *mc) static const struct nvkm_mc_func nv44_mc = { .init = nv44_mc_init, - .intr = nv04_mc_intr, + .intr = nv17_mc_intr, .intr_unarm = nv04_mc_intr_unarm, .intr_rearm = nv04_mc_intr_rearm, .intr_mask = nv04_mc_intr_mask, + .reset = nv17_mc_reset, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c index 5f27d7b8fddd..343b6078580d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c @@ -23,21 +23,17 @@ */ #include "priv.h" -const struct nvkm_mc_intr +static const struct nvkm_mc_map nv50_mc_intr[] = { - { 0x04000000, NVKM_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */ - { 0x00000001, NVKM_ENGINE_MPEG }, - { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x04000000, NVKM_ENGINE_DISP }, { 0x00001000, NVKM_ENGINE_GR }, - { 0x00004000, NVKM_ENGINE_CIPHER }, /* NV84- */ - { 0x00008000, NVKM_ENGINE_BSP }, /* NV84- */ - { 0x00020000, NVKM_ENGINE_VP }, /* NV84- */ - { 0x00100000, NVKM_SUBDEV_TIMER }, - { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */ - { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */ + { 0x00000100, NVKM_ENGINE_FIFO }, + { 0x00000001, NVKM_ENGINE_MPEG }, + { 0x00001101, NVKM_SUBDEV_FB }, { 0x10000000, NVKM_SUBDEV_BUS }, - { 0x80000000, NVKM_ENGINE_SW }, - { 0x0002d101, NVKM_SUBDEV_FB }, + { 0x00200000, NVKM_SUBDEV_GPIO }, + { 0x00200000, NVKM_SUBDEV_I2C }, + { 0x00100000, NVKM_SUBDEV_TIMER }, {}, }; @@ -55,6 +51,7 @@ nv50_mc = { .intr_unarm = nv04_mc_intr_unarm, .intr_rearm = nv04_mc_intr_rearm, .intr_mask = nv04_mc_intr_mask, + .reset = nv17_mc_reset, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h index 307f6c692287..a12038118512 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h @@ -6,37 +6,42 @@ int nvkm_mc_new_(const struct nvkm_mc_func *, struct nvkm_device *, int index, struct nvkm_mc **); -struct nvkm_mc_intr { +struct nvkm_mc_map { u32 stat; u32 unit; }; struct nvkm_mc_func { void (*init)(struct nvkm_mc *); - const struct nvkm_mc_intr *intr; + const struct nvkm_mc_map *intr; /* disable reporting of interrupts to host */ void (*intr_unarm)(struct nvkm_mc *); /* enable reporting of interrupts to host */ void (*intr_rearm)(struct nvkm_mc *); /* retrieve pending interrupt mask (NV_PMC_INTR) */ u32 (*intr_mask)(struct nvkm_mc *); + const struct nvkm_mc_map *reset; void (*unk260)(struct nvkm_mc *, u32); }; void nv04_mc_init(struct nvkm_mc *); -extern const struct nvkm_mc_intr nv04_mc_intr[]; void nv04_mc_intr_unarm(struct nvkm_mc *); void nv04_mc_intr_rearm(struct nvkm_mc *); u32 nv04_mc_intr_mask(struct nvkm_mc *); +extern const struct nvkm_mc_map nv04_mc_reset[]; + +extern const struct nvkm_mc_map nv17_mc_intr[]; +extern const struct nvkm_mc_map nv17_mc_reset[]; void nv44_mc_init(struct nvkm_mc *); void nv50_mc_init(struct nvkm_mc *); -extern const struct nvkm_mc_intr nv50_mc_intr[]; -extern const struct nvkm_mc_intr gf100_mc_intr[]; void gf100_mc_intr_unarm(struct nvkm_mc *); void gf100_mc_intr_rearm(struct nvkm_mc *); u32 gf100_mc_intr_mask(struct nvkm_mc *); void gf100_mc_unk260(struct nvkm_mc *, u32); + +extern const struct nvkm_mc_map gk104_mc_intr[]; +extern const struct nvkm_mc_map gk104_mc_reset[]; #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index e04a2296ecd0..5df9669ea39c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -524,7 +524,7 @@ void nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device, int index, struct nvkm_mmu *mmu) { - nvkm_subdev_ctor(&nvkm_mmu, device, index, 0, &mmu->subdev); + nvkm_subdev_ctor(&nvkm_mmu, device, index, &mmu->subdev); mmu->func = func; mmu->limit = func->limit; mmu->dma_bits = func->dma_bits; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c index 9700a7625012..21b65ee254e4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c @@ -241,7 +241,7 @@ nvkm_mxm_new_(struct nvkm_device *device, int index, struct nvkm_mxm **pmxm) if (!(mxm = *pmxm = kzalloc(sizeof(*mxm), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_mxm, device, index, 0, &mxm->subdev); + nvkm_subdev_ctor(&nvkm_mxm, device, index, &mxm->subdev); data = mxm_table(bios, &ver, &len); if (!data || !(ver = nvbios_rd08(bios, data))) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index 65057c8310a2..6b0328bd7eed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -168,7 +168,7 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device, if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_pci_func, device, index, 0, &pci->subdev); + nvkm_subdev_ctor(&nvkm_pci_func, device, index, &pci->subdev); pci->func = func; pci->pdev = device->func->pci(device)->pdev; pci->irq = -1; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c index d95eb8659d1b..8dd164d13043 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c @@ -40,21 +40,23 @@ nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2], struct nvkm_device *device = subdev->device; u32 addr; + mutex_lock(&subdev->mutex); /* wait for a free slot in the fifo */ addr = nvkm_rd32(device, 0x10a4a0); if (nvkm_msec(device, 2000, u32 tmp = nvkm_rd32(device, 0x10a4b0); if (tmp != (addr ^ 8)) break; - ) < 0) + ) < 0) { + mutex_unlock(&subdev->mutex); return -EBUSY; + } /* we currently only support a single process at a time waiting * on a synchronous reply, take the PMU mutex and tell the * receive handler what we're waiting for */ if (reply) { - mutex_lock(&subdev->mutex); pmu->recv.message = message; pmu->recv.process = process; } @@ -81,9 +83,9 @@ nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2], wait_event(pmu->recv.wait, (pmu->recv.process == 0)); reply[0] = pmu->recv.data[0]; reply[1] = pmu->recv.data[1]; - mutex_unlock(&subdev->mutex); } + mutex_unlock(&subdev->mutex); return 0; } @@ -272,7 +274,7 @@ nvkm_pmu_new_(const struct nvkm_pmu_func *func, struct nvkm_device *device, struct nvkm_pmu *pmu; if (!(pmu = *ppmu = kzalloc(sizeof(*pmu), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_pmu, device, index, 0, &pmu->subdev); + nvkm_subdev_ctor(&nvkm_pmu, device, index, &pmu->subdev); pmu->func = func; INIT_WORK(&pmu->recv.work, nvkm_pmu_recv); init_waitqueue_head(&pmu->recv.wait); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c index 6689d0290a7e..f996d90c9f0d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c @@ -220,7 +220,7 @@ gk20a_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu) pmu->base.func = &func; *ppmu = &pmu->base; - nvkm_subdev_ctor(&gk20a_pmu, device, index, 0, &pmu->base.subdev); + nvkm_subdev_ctor(&gk20a_pmu, device, index, &pmu->base.subdev); pmu->data = &gk20a_dvfs_data; nvkm_alarm_init(&pmu->alarm, gk20a_pmu_dvfs_work); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c index 520facf9bc07..213fdba6cfa0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c @@ -264,7 +264,7 @@ nvkm_secboot_ctor(const struct nvkm_secboot_func *func, { unsigned long fid; - nvkm_subdev_ctor(&nvkm_secboot, device, index, 0, &sb->subdev); + nvkm_subdev_ctor(&nvkm_secboot, device, index, &sb->subdev); sb->func = func; /* setup the performing falcon's base address and masks */ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c index 949dc6101a58..8894fee30cbc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c @@ -366,7 +366,7 @@ nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device, if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_therm, device, index, 0, &therm->subdev); + nvkm_subdev_ctor(&nvkm_therm, device, index, &therm->subdev); therm->func = func; nvkm_alarm_init(&therm->alarm, nvkm_therm_alarm); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c index d4dae1f12d62..07dc82bfe346 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c @@ -143,7 +143,7 @@ nvkm_timer_new_(const struct nvkm_timer_func *func, struct nvkm_device *device, if (!(tmr = *ptmr = kzalloc(sizeof(*tmr), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&nvkm_timer, device, index, 0, &tmr->subdev); + nvkm_subdev_ctor(&nvkm_timer, device, index, &tmr->subdev); tmr->func = func; INIT_LIST_HEAD(&tmr->alarms); spin_lock_init(&tmr->lock); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/top/Kbuild new file mode 100644 index 000000000000..1078401cdcea --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/Kbuild @@ -0,0 +1,2 @@ +nvkm-y += nvkm/subdev/top/base.o +nvkm-y += nvkm/subdev/top/gk104.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c new file mode 100644 index 000000000000..a1b264664aad --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c @@ -0,0 +1,148 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ +#include "priv.h" + +struct nvkm_top_device * +nvkm_top_device_new(struct nvkm_top *top) +{ + struct nvkm_top_device *info = kmalloc(sizeof(*info), GFP_KERNEL); + if (info) { + info->index = NVKM_SUBDEV_NR; + info->addr = 0; + info->fault = -1; + info->engine = -1; + info->runlist = -1; + info->reset = -1; + info->intr = -1; + list_add_tail(&info->head, &top->device); + } + return info; +} + +u32 +nvkm_top_reset(struct nvkm_top *top, enum nvkm_devidx index) +{ + struct nvkm_top_device *info; + + if (top) { + list_for_each_entry(info, &top->device, head) { + if (info->index == index && info->reset >= 0) + return BIT(info->reset); + } + } + + return 0; +} + +u32 +nvkm_top_intr(struct nvkm_top *top, u32 intr, u64 *psubdevs) +{ + struct nvkm_top_device *info; + u64 subdevs = 0; + u32 handled = 0; + + if (top) { + list_for_each_entry(info, &top->device, head) { + if (info->index != NVKM_SUBDEV_NR && info->intr >= 0) { + if (intr & BIT(info->intr)) { + subdevs |= BIT_ULL(info->index); + handled |= BIT(info->intr); + } + } + } + } + + *psubdevs = subdevs; + return intr & ~handled; +} + +enum nvkm_devidx +nvkm_top_fault(struct nvkm_top *top, int fault) +{ + struct nvkm_top_device *info; + + list_for_each_entry(info, &top->device, head) { + if (info->fault == fault) + return info->index; + } + + return NVKM_SUBDEV_NR; +} + +enum nvkm_devidx +nvkm_top_engine(struct nvkm_top *top, int index, int *runl, int *engn) +{ + struct nvkm_top_device *info; + int n = 0; + + list_for_each_entry(info, &top->device, head) { + if (info->engine >= 0 && info->runlist >= 0 && n++ == index) { + *runl = info->runlist; + *engn = info->engine; + return info->index; + } + } + + return -ENODEV; +} + +static int +nvkm_top_oneinit(struct nvkm_subdev *subdev) +{ + struct nvkm_top *top = nvkm_top(subdev); + return top->func->oneinit(top); +} + +static void * +nvkm_top_dtor(struct nvkm_subdev *subdev) +{ + struct nvkm_top *top = nvkm_top(subdev); + struct nvkm_top_device *info, *temp; + + list_for_each_entry_safe(info, temp, &top->device, head) { + list_del(&info->head); + kfree(info); + } + + return top; +} + +static const struct nvkm_subdev_func +nvkm_top = { + .dtor = nvkm_top_dtor, + .oneinit = nvkm_top_oneinit, +}; + +int +nvkm_top_new_(const struct nvkm_top_func *func, struct nvkm_device *device, + int index, struct nvkm_top **ptop) +{ + struct nvkm_top *top; + if (!(top = *ptop = kzalloc(sizeof(*top), GFP_KERNEL))) + return -ENOMEM; + nvkm_subdev_ctor(&nvkm_top, device, index, &top->subdev); + top->func = func; + INIT_LIST_HEAD(&top->device); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c new file mode 100644 index 000000000000..e06acc340e99 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c @@ -0,0 +1,110 @@ +/* + * Copyright 2016 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ +#include "priv.h" + +static int +gk104_top_oneinit(struct nvkm_top *top) +{ + struct nvkm_subdev *subdev = &top->subdev; + struct nvkm_device *device = subdev->device; + struct nvkm_top_device *info = NULL; + u32 data, type; + int i; + + for (i = 0; i < 64; i++) { + if (!info) { + if (!(info = nvkm_top_device_new(top))) + return -ENOMEM; + type = ~0; + } + + data = nvkm_rd32(device, 0x022700 + (i * 0x04)); + nvkm_trace(subdev, "%02x: %08x\n", i, data); + switch (data & 0x00000003) { + case 0x00000000: /* NOT_VALID */ + continue; + case 0x00000001: /* DATA */ + info->addr = (data & 0x00fff000); + info->fault = (data & 0x000000f8) >> 3; + break; + case 0x00000002: /* ENUM */ + if (data & 0x00000020) + info->engine = (data & 0x3c000000) >> 26; + if (data & 0x00000010) + info->runlist = (data & 0x01e00000) >> 21; + if (data & 0x00000008) + info->intr = (data & 0x000f8000) >> 15; + if (data & 0x00000004) + info->reset = (data & 0x00003e00) >> 9; + break; + case 0x00000003: /* ENGINE_TYPE */ + type = (data & 0x7ffffffc) >> 2; + break; + } + + if (data & 0x80000000) + continue; + + /* Translate engine type to NVKM engine identifier. */ + switch (type) { + case 0x00000000: info->index = NVKM_ENGINE_GR; break; + case 0x00000001: info->index = NVKM_ENGINE_CE0; break; + case 0x00000002: info->index = NVKM_ENGINE_CE1; break; + case 0x00000003: info->index = NVKM_ENGINE_CE2; break; + case 0x00000008: info->index = NVKM_ENGINE_MSPDEC; break; + case 0x00000009: info->index = NVKM_ENGINE_MSPPP; break; + case 0x0000000a: info->index = NVKM_ENGINE_MSVLD; break; + case 0x0000000b: info->index = NVKM_ENGINE_MSENC; break; + case 0x0000000c: info->index = NVKM_ENGINE_VIC; break; + case 0x0000000d: info->index = NVKM_ENGINE_SEC; break; + case 0x0000000e: info->index = NVKM_ENGINE_NVENC0; break; + case 0x0000000f: info->index = NVKM_ENGINE_NVENC1; break; + case 0x00000010: info->index = NVKM_ENGINE_NVDEC; break; + break; + default: + break; + } + + nvkm_debug(subdev, "%02x (%8s): addr %06x fault %2d engine %2d " + "runlist %2d intr %2d reset %2d\n", type, + info->index == NVKM_SUBDEV_NR ? NULL : + nvkm_subdev_name[info->index], + info->addr, info->fault, info->engine, info->runlist, + info->intr, info->reset); + info = NULL; + } + + return 0; +} + +static const struct nvkm_top_func +gk104_top = { + .oneinit = gk104_top_oneinit, +}; + +int +gk104_top_new(struct nvkm_device *device, int index, struct nvkm_top **ptop) +{ + return nvkm_top_new_(&gk104_top, device, index, ptop); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/top/priv.h new file mode 100644 index 000000000000..adb3ed03d937 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/priv.h @@ -0,0 +1,25 @@ +#ifndef __NVKM_TOP_PRIV_H__ +#define __NVKM_TOP_PRIV_H__ +#define nvkm_top(p) container_of((p), struct nvkm_top, subdev) +#include <subdev/top.h> + +struct nvkm_top_func { + int (*oneinit)(struct nvkm_top *); +}; + +int nvkm_top_new_(const struct nvkm_top_func *, struct nvkm_device *, + int, struct nvkm_top **); + +struct nvkm_top_device { + enum nvkm_devidx index; + u32 addr; + int fault; + int engine; + int runlist; + int reset; + int intr; + struct list_head head; +}; + +struct nvkm_top_device *nvkm_top_device_new(struct nvkm_top *); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c index 50b5649ad1a4..6b2d7531a7ff 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c @@ -177,7 +177,7 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct nvkm_device *device, struct nvkm_bios *bios = device->bios; int i; - nvkm_subdev_ctor(&nvkm_volt, device, index, 0, &volt->subdev); + nvkm_subdev_ctor(&nvkm_volt, device, index, &volt->subdev); volt->func = func; /* Assuming the non-bios device should build the voltage table later */ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c index b735173a18ff..420bd84d8483 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c @@ -56,7 +56,7 @@ gk104_volt_set(struct nvkm_volt *base, u32 uv) /* the blob uses this crystal frequency, let's use it too. */ div = 27648000 / bios->pwm_freq; - duty = (uv - bios->base) * div / bios->pwm_range; + duty = DIV_ROUND_UP((uv - bios->base) * div, bios->pwm_range); nvkm_wr32(device, 0x20340, div); nvkm_wr32(device, 0x20344, 0x80000000 | duty); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index fe794980f1c8..d86f5479345b 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -561,7 +561,7 @@ static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data, VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op); - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = drm_gem_object_lookup(file_priv, args->handle); if (!obj) return -ENOENT; @@ -584,7 +584,7 @@ static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data, VERB("%p:%p: handle=%d", dev, file_priv, args->handle); - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = drm_gem_object_lookup(file_priv, args->handle); if (!obj) return -ENOENT; @@ -608,7 +608,7 @@ static int ioctl_gem_info(struct drm_device *dev, void *data, VERB("%p:%p: handle=%d", dev, file_priv, args->handle); - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = drm_gem_object_lookup(file_priv, args->handle); if (!obj) return -ENOENT; diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 0fbe17d0ec6f..3f823c368912 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -257,14 +257,14 @@ struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder); /* should these be made into common util helpers? */ -static inline int objects_lookup(struct drm_device *dev, +static inline int objects_lookup( struct drm_file *filp, uint32_t pixel_format, struct drm_gem_object **bos, const uint32_t *handles) { int i, n = drm_format_num_planes(pixel_format); for (i = 0; i < n; i++) { - bos[i] = drm_gem_object_lookup(dev, filp, handles[i]); + bos[i] = drm_gem_object_lookup(filp, handles[i]); if (!bos[i]) goto fail; diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index 610962396eb0..94ec06d3d737 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -378,7 +378,7 @@ struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev, struct drm_framebuffer *fb; int ret; - ret = objects_lookup(dev, file, mode_cmd->pixel_format, + ret = objects_lookup(file, mode_cmd->pixel_format, bos, mode_cmd->handles); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 907154f5b67c..b97afc281778 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -687,7 +687,7 @@ int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, int ret = 0; /* GEM does all our handle to object mapping */ - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) { ret = -ENOENT; goto fail; diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 93ee538a99f5..5252ab720e70 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -245,7 +245,7 @@ omap_plane_atomic_duplicate_state(struct drm_plane *plane) static void omap_plane_atomic_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - __drm_atomic_helper_plane_destroy_state(plane, state); + __drm_atomic_helper_plane_destroy_state(state); kfree(to_omap_plane_state(state)); } diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 9a035243faa6..5bc36c4d4232 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -318,7 +318,7 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, if (!handle) return qxl_hide_cursor(qdev); - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("cannot find cursor object\n"); return -ENOENT; @@ -730,7 +730,6 @@ static int qdev_crtc_init(struct drm_device *dev, int crtc_id) drm_crtc_init(dev, &qxl_crtc->base, &qxl_crtc_funcs); qxl_crtc->index = crtc_id; - drm_mode_crtc_set_gamma_size(&qxl_crtc->base, 256); drm_crtc_helper_add(&qxl_crtc->base, &qxl_crtc_helper_funcs); return 0; } @@ -994,7 +993,9 @@ qxl_user_framebuffer_create(struct drm_device *dev, struct qxl_framebuffer *qxl_fb; int ret; - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); + if (!obj) + return NULL; qxl_fb = kzalloc(sizeof(*qxl_fb), GFP_KERNEL); if (qxl_fb == NULL) diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index d34bb4130ff0..5e65d5d2d937 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c @@ -76,7 +76,7 @@ int qxl_mode_dumb_mmap(struct drm_file *file_priv, struct qxl_bo *qobj; BUG_ON(!offset_p); - gobj = drm_gem_object_lookup(dev, file_priv, handle); + gobj = drm_gem_object_lookup(file_priv, handle); if (gobj == NULL) return -ENOENT; qobj = gem_to_qxl_bo(gobj); diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 739a08cddf6d..5ea57f6320b8 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -251,6 +251,9 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); ret = qxlfb_create_pinned_object(qfbdev, &mode_cmd, &gobj); + if (ret < 0) + return ret; + qbo = gem_to_qxl_bo(gobj); QXL_INFO(qdev, "%s: %dx%d %d\n", __func__, mode_cmd.width, mode_cmd.height, mode_cmd.pitches[0]); diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 7c2e78201ead..5a4c8c492683 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -107,15 +107,14 @@ apply_surf_reloc(struct qxl_device *qdev, struct qxl_reloc_info *info) } /* return holding the reference to this object */ -static int qxlhw_handle_to_bo(struct qxl_device *qdev, - struct drm_file *file_priv, uint64_t handle, +static int qxlhw_handle_to_bo(struct drm_file *file_priv, uint64_t handle, struct qxl_release *release, struct qxl_bo **qbo_p) { struct drm_gem_object *gobj; struct qxl_bo *qobj; int ret; - gobj = drm_gem_object_lookup(qdev->ddev, file_priv, handle); + gobj = drm_gem_object_lookup(file_priv, handle); if (!gobj) return -EINVAL; @@ -221,7 +220,7 @@ static int qxl_process_single_command(struct qxl_device *qdev, reloc_info[i].type = reloc.reloc_type; if (reloc.dst_handle) { - ret = qxlhw_handle_to_bo(qdev, file_priv, reloc.dst_handle, release, + ret = qxlhw_handle_to_bo(file_priv, reloc.dst_handle, release, &reloc_info[i].dst_bo); if (ret) goto out_free_bos; @@ -234,7 +233,7 @@ static int qxl_process_single_command(struct qxl_device *qdev, /* reserve and validate the reloc dst bo */ if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle) { - ret = qxlhw_handle_to_bo(qdev, file_priv, reloc.src_handle, release, + ret = qxlhw_handle_to_bo(file_priv, reloc.src_handle, release, &reloc_info[i].src_bo); if (ret) goto out_free_bos; @@ -314,7 +313,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, update_area->top >= update_area->bottom) return -EINVAL; - gobj = drm_gem_object_lookup(dev, file, update_area->handle); + gobj = drm_gem_object_lookup(file, update_area->handle); if (gobj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index bdc7b9ee1930..2e216e2ea78c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1740,6 +1740,7 @@ static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; struct drm_crtc *test_crtc; struct radeon_crtc *test_radeon_crtc; @@ -1749,6 +1750,10 @@ static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) test_radeon_crtc = to_radeon_crtc(test_crtc); if (test_radeon_crtc->encoder && ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { + /* PPLL2 is exclusive to UNIPHYA on DCE61 */ + if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) && + test_radeon_crtc->pll_id == ATOM_PPLL2) + continue; /* for DP use the same PLL for all */ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) return test_radeon_crtc->pll_id; @@ -1770,6 +1775,7 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; struct drm_crtc *test_crtc; struct radeon_crtc *test_radeon_crtc; u32 adjusted_clock, test_adjusted_clock; @@ -1785,6 +1791,10 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc) test_radeon_crtc = to_radeon_crtc(test_crtc); if (test_radeon_crtc->encoder && !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) { + /* PPLL2 is exclusive to UNIPHYA on DCE61 */ + if (ASIC_IS_DCE61(rdev) && !ASIC_IS_DCE8(rdev) && + test_radeon_crtc->pll_id == ATOM_PPLL2) + continue; /* check if we are already driving this connector with another crtc */ if (test_radeon_crtc->connector == radeon_crtc->connector) { /* if we are, return that pll */ diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index afa9db1dc0e3..cead089a9e7d 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -326,8 +326,8 @@ int radeon_dp_get_dp_link_config(struct drm_connector *connector, } } } else { - for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { - for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; if (max_pix_clock >= pix_clock) { *dp_lanes = lane_num; diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index d0240743a17c..a7e978677937 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -2164,7 +2164,7 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, if (pi->caps_stable_p_state) { stable_p_state_sclk = (max_limits->sclk * 75) / 100; - for (i = table->count - 1; i >= 0; i++) { + for (i = table->count - 1; i >= 0; i--) { if (stable_p_state_sclk >= table->entries[i].clk) { stable_p_state_sclk = table->entries[i].clk; break; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index ab39b85e0f76..510ea371dacc 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -74,7 +74,6 @@ static void radeon_cs_buckets_get_list(struct radeon_cs_buckets *b, static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) { - struct drm_device *ddev = p->rdev->ddev; struct radeon_cs_chunk *chunk; struct radeon_cs_buckets buckets; unsigned i; @@ -101,7 +100,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) unsigned priority; r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; - gobj = drm_gem_object_lookup(ddev, p->filp, r->handle); + gobj = drm_gem_object_lookup(p->filp, r->handle); if (gobj == NULL) { DRM_ERROR("gem object lookup failed 0x%x\n", r->handle); diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index afaf346bd50e..2a10e24b34b1 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -274,7 +274,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, return -EINVAL; } - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); return -ENOENT; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 628eb878a069..6a41b4982647 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1368,7 +1368,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, struct radeon_framebuffer *radeon_fb; int ret; - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); if (obj == NULL) { dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " "can't create framebuffer\n", mode_cmd->handles[0]); diff --git a/drivers/gpu/drm/radeon/radeon_dp_auxch.c b/drivers/gpu/drm/radeon/radeon_dp_auxch.c index 3b0c229d7dcd..db64e0062689 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_auxch.c +++ b/drivers/gpu/drm/radeon/radeon_dp_auxch.c @@ -105,7 +105,7 @@ radeon_dp_aux_transfer_native(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg tmp &= AUX_HPD_SEL(0x7); tmp |= AUX_HPD_SEL(chan->rec.hpd); - tmp |= AUX_EN | AUX_LS_READ_EN; + tmp |= AUX_EN | AUX_LS_READ_EN | AUX_HPD_DISCON(0x1); WREG32(AUX_CONTROL + aux_offset[instance], tmp); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index b55aa740171f..a455dc7d4aa1 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -34,11 +34,9 @@ #include "radeon_drv.h" #include <drm/drm_pciids.h> -#include <linux/apple-gmux.h> #include <linux/console.h> #include <linux/module.h> #include <linux/pm_runtime.h> -#include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include <drm/drm_gem.h> @@ -340,13 +338,7 @@ static int radeon_pci_probe(struct pci_dev *pdev, if (ret == -EPROBE_DEFER) return ret; - /* - * apple-gmux is needed on dual GPU MacBook Pro - * to probe the panel if we're the inactive GPU. - */ - if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) && - apple_gmux_present() && pdev != vga_default_device() && - !vga_switcheroo_handler_flags()) + if (vga_switcheroo_client_probe_defer(pdev)) return -EPROBE_DEFER; /* Get rid of things like offb */ diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index e26c963f2e93..deb9511725c9 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -382,7 +382,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, down_read(&rdev->exclusive_lock); /* just do a BO wait for now */ - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { up_read(&rdev->exclusive_lock); return -ENOENT; @@ -404,7 +404,7 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, struct drm_gem_object *gobj; struct radeon_bo *robj; - gobj = drm_gem_object_lookup(dev, filp, handle); + gobj = drm_gem_object_lookup(filp, handle); if (gobj == NULL) { return -ENOENT; } @@ -435,7 +435,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, int r; uint32_t cur_placement = 0; - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { return -ENOENT; } @@ -464,7 +464,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, uint32_t cur_placement = 0; long ret; - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { return -ENOENT; } @@ -495,7 +495,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, int r = 0; DRM_DEBUG("%d \n", args->handle); - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) return -ENOENT; robj = gem_to_radeon_bo(gobj); @@ -513,7 +513,7 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, int r = 0; DRM_DEBUG("\n"); - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) return -ENOENT; rbo = gem_to_radeon_bo(gobj); @@ -648,7 +648,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { args->operation = RADEON_VA_RESULT_ERROR; return -ENOENT; @@ -703,7 +703,7 @@ int radeon_gem_op_ioctl(struct drm_device *dev, void *data, struct radeon_bo *robj; int r; - gobj = drm_gem_object_lookup(dev, filp, args->handle); + gobj = drm_gem_object_lookup(filp, args->handle); if (gobj == NULL) { return -ENOENT; } diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 1e9304d1c88f..c084cadcbf21 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -291,7 +291,6 @@ int radeon_irq_kms_init(struct radeon_device *rdev) if (r) { return r; } - rdev->ddev->vblank_disable_allowed = true; /* enable msi */ rdev->msi_enabled = 0; diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c index eef006c48584..896f2cf51e4e 100644 --- a/drivers/gpu/drm/radeon/radeon_mn.c +++ b/drivers/gpu/drm/radeon/radeon_mn.c @@ -186,7 +186,9 @@ static struct radeon_mn *radeon_mn_get(struct radeon_device *rdev) struct radeon_mn *rmn; int r; - down_write(&mm->mmap_sem); + if (down_write_killable(&mm->mmap_sem)) + return ERR_PTR(-EINTR); + mutex_lock(&rdev->mn_lock); hash_for_each_possible(rdev->mn_hash, rmn, node, (unsigned long)mm) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 8460ae1ffa4b..d445e67f78e1 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -635,7 +635,7 @@ rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane) static void rcar_du_plane_atomic_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - __drm_atomic_helper_plane_destroy_state(plane, state); + __drm_atomic_helper_plane_destroy_state(state); kfree(to_rcar_plane_state(state)); } diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index de7ef041182b..e671a7cd3463 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -251,7 +251,7 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane) static void rcar_du_vsp_plane_atomic_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - __drm_atomic_helper_plane_destroy_state(plane, state); + __drm_atomic_helper_plane_destroy_state(state); kfree(to_rcar_vsp_plane_state(state)); } diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 399adf3c4224..a409d1f703cb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -216,13 +216,6 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags) if (ret) goto err_kms_helper_poll_fini; - /* - * with vblank_disable_allowed = true, vblank interrupt will be disabled - * by drm timer once a current process gives up ownership of - * vblank event.(after drm_vblank_put function is called) - */ - drm_dev->vblank_disable_allowed = true; - drm_mode_config_reset(drm_dev); ret = rockchip_drm_fbdev_init(drm_dev); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index 8c10163a95bc..755cfdba61cd 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -123,8 +123,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, unsigned int height = mode_cmd->height / (i ? vsub : 1); unsigned int min_size; - obj = drm_gem_object_lookup(dev, file_priv, - mode_cmd->handles[i]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); if (!obj) { dev_err(dev->dev, "Failed to lookup GEM object\n"); ret = -ENXIO; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 18e07338c6e5..9c2d8a894093 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -198,7 +198,7 @@ int rockchip_gem_dumb_map_offset(struct drm_file *file_priv, struct drm_gem_object *obj; int ret; - obj = drm_gem_object_lookup(dev, file_priv, handle); + obj = drm_gem_object_lookup(file_priv, handle); if (!obj) { DRM_ERROR("failed to lookup gem object.\n"); return -EINVAL; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index bf55cda356ba..1c4d5b5a70a2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -822,7 +822,7 @@ static void vop_atomic_plane_destroy_state(struct drm_plane *plane, { struct vop_plane_state *vop_state = to_vop_plane_state(state); - __drm_atomic_helper_plane_destroy_state(plane, state); + __drm_atomic_helper_plane_destroy_state(state); kfree(vop_state); } @@ -1065,7 +1065,7 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc, { struct rockchip_crtc_state *s = to_rockchip_crtc_state(state); - __drm_atomic_helper_crtc_destroy_state(crtc, &s->base); + __drm_atomic_helper_crtc_destroy_state(&s->base); kfree(s); } diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c index 32c7986b63ab..6bf4ce466d20 100644 --- a/drivers/gpu/drm/sti/sti_vtg.c +++ b/drivers/gpu/drm/sti/sti_vtg.c @@ -437,7 +437,7 @@ static int vtg_probe(struct platform_device *pdev) return -EPROBE_DEFER; } else { vtg->irq = platform_get_irq(pdev, 0); - if (IS_ERR_VALUE(vtg->irq)) { + if (vtg->irq < 0) { DRM_ERROR("Failed to get VTG interrupt\n"); return vtg->irq; } @@ -447,7 +447,7 @@ static int vtg_probe(struct platform_device *pdev) ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq, vtg_irq_thread, IRQF_ONESHOT, dev_name(dev), vtg); - if (IS_ERR_VALUE(ret)) { + if (ret < 0) { DRM_ERROR("Failed to register VTG interrupt\n"); return ret; } diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 3b85a31b625d..39940f5b7c91 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -434,7 +434,7 @@ static void tegra_plane_reset(struct drm_plane *plane) struct tegra_plane_state *state; if (plane->state) - __drm_atomic_helper_plane_destroy_state(plane, plane->state); + __drm_atomic_helper_plane_destroy_state(plane->state); kfree(plane->state); plane->state = NULL; @@ -466,7 +466,7 @@ static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_pla static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - __drm_atomic_helper_plane_destroy_state(plane, state); + __drm_atomic_helper_plane_destroy_state(state); kfree(state); } @@ -998,7 +998,7 @@ static void tegra_crtc_reset(struct drm_crtc *crtc) struct tegra_dc_state *state; if (crtc->state) - __drm_atomic_helper_crtc_destroy_state(crtc, crtc->state); + __drm_atomic_helper_crtc_destroy_state(crtc->state); kfree(crtc->state); crtc->state = NULL; @@ -1034,7 +1034,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc) static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state) { - __drm_atomic_helper_crtc_destroy_state(crtc, state); + __drm_atomic_helper_crtc_destroy_state(state); kfree(state); } diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 45deb8fd8e7c..b59c3bf0df44 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -180,7 +180,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) /* syncpoints are used for full 32-bit hardware VBLANK counters */ drm->max_vblank_count = 0xffffffff; - drm->vblank_disable_allowed = true; err = drm_vblank_init(drm, drm->mode_config.num_crtc); if (err < 0) @@ -268,12 +267,12 @@ static void tegra_drm_lastclose(struct drm_device *drm) } static struct host1x_bo * -host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle) +host1x_bo_lookup(struct drm_file *file, u32 handle) { struct drm_gem_object *gem; struct tegra_bo *bo; - gem = drm_gem_object_lookup(drm, file, handle); + gem = drm_gem_object_lookup(file, handle); if (!gem) return NULL; @@ -311,11 +310,11 @@ static int host1x_reloc_copy_from_user(struct host1x_reloc *dest, if (err < 0) return err; - dest->cmdbuf.bo = host1x_bo_lookup(drm, file, cmdbuf); + dest->cmdbuf.bo = host1x_bo_lookup(file, cmdbuf); if (!dest->cmdbuf.bo) return -ENOENT; - dest->target.bo = host1x_bo_lookup(drm, file, target); + dest->target.bo = host1x_bo_lookup(file, target); if (!dest->target.bo) return -ENOENT; @@ -363,7 +362,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, goto fail; } - bo = host1x_bo_lookup(drm, file, cmdbuf.handle); + bo = host1x_bo_lookup(file, cmdbuf.handle); if (!bo) { err = -ENOENT; goto fail; @@ -463,7 +462,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data, struct drm_gem_object *gem; struct tegra_bo *bo; - gem = drm_gem_object_lookup(drm, file, args->handle); + gem = drm_gem_object_lookup(file, args->handle); if (!gem) return -EINVAL; @@ -672,7 +671,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data, return -EINVAL; } - gem = drm_gem_object_lookup(drm, file, args->handle); + gem = drm_gem_object_lookup(file, args->handle); if (!gem) return -ENOENT; @@ -694,7 +693,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data, struct tegra_bo *bo; int err = 0; - gem = drm_gem_object_lookup(drm, file, args->handle); + gem = drm_gem_object_lookup(file, args->handle); if (!gem) return -ENOENT; @@ -736,7 +735,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data, if (args->flags & ~DRM_TEGRA_GEM_FLAGS) return -EINVAL; - gem = drm_gem_object_lookup(drm, file, args->handle); + gem = drm_gem_object_lookup(file, args->handle); if (!gem) return -ENOENT; @@ -758,7 +757,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data, struct drm_gem_object *gem; struct tegra_bo *bo; - gem = drm_gem_object_lookup(drm, file, args->handle); + gem = drm_gem_object_lookup(file, args->handle); if (!gem) return -ENOENT; diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 8a10f5b7d9dc..f52d6cb24ff5 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -121,7 +121,7 @@ struct tegra_dc { spinlock_t lock; struct drm_crtc base; - int powergate; + unsigned int powergate; int pipe; struct clk *clk; diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 44e102799195..d1239ebc190f 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -745,13 +745,17 @@ static void tegra_dsi_soft_reset(struct tegra_dsi *dsi) static void tegra_dsi_connector_reset(struct drm_connector *connector) { - struct tegra_dsi_state *state = - kzalloc(sizeof(*state), GFP_KERNEL); + struct tegra_dsi_state *state = kzalloc(sizeof(*state), GFP_KERNEL); - if (state) { + if (!state) + return; + + if (connector->state) { + __drm_atomic_helper_connector_destroy_state(connector->state); kfree(connector->state); - __drm_atomic_helper_connector_reset(connector, &state->base); } + + __drm_atomic_helper_connector_reset(connector, &state->base); } static struct drm_connector_state * @@ -764,6 +768,9 @@ tegra_dsi_connector_duplicate_state(struct drm_connector *connector) if (!copy) return NULL; + __drm_atomic_helper_connector_duplicate_state(connector, + ©->base); + return ©->base; } diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index ca84de9ccb51..1b12aa7a715e 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -149,7 +149,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, unsigned int height = cmd->height / (i ? vsub : 1); unsigned int size, bpp; - gem = drm_gem_object_lookup(drm, file, cmd->handles[i]); + gem = drm_gem_object_lookup(file, cmd->handles[i]); if (!gem) { err = -ENXIO; goto unreference; diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 3b0d8c392b70..aa60d9909ea2 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -401,7 +401,7 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, struct drm_gem_object *gem; struct tegra_bo *bo; - gem = drm_gem_object_lookup(drm, file, handle); + gem = drm_gem_object_lookup(file, handle); if (!gem) { dev_err(drm->dev, "failed to lookup GEM object\n"); return -EINVAL; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c index 106679bca6cb..f9c79dabce20 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c @@ -157,7 +157,7 @@ struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft) if (!overlay_data || kfree_table_add(kft, overlay_data)) return NULL; - of_fdt_unflatten_tree(overlay_data, &overlay); + of_fdt_unflatten_tree(overlay_data, NULL, &overlay); if (!overlay) { pr_warn("%s: Unfattening overlay tree failed\n", __func__); return NULL; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c index 7716f42f8aab..6b8c5b3bf588 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c @@ -342,7 +342,7 @@ static int tfp410_probe(struct platform_device *pdev) tfp410_mod->gpio = of_get_named_gpio_flags(node, "powerdn-gpio", 0, NULL); - if (IS_ERR_VALUE(tfp410_mod->gpio)) { + if (tfp410_mod->gpio < 0) { dev_warn(&pdev->dev, "No power down GPIO\n"); } else { ret = gpio_request(tfp410_mod->gpio, "DVI_PDn"); diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 4a9b43217900..d5df555aeba0 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -500,7 +500,7 @@ udl_fb_user_fb_create(struct drm_device *dev, int ret; uint32_t size; - obj = drm_gem_object_lookup(dev, file, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(file, mode_cmd->handles[0]); if (obj == NULL) return ERR_PTR(-ENOENT); diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index d7528e0d8442..818e70712b18 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -217,7 +217,7 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, int ret = 0; mutex_lock(&dev->struct_mutex); - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (obj == NULL) { ret = -ENOENT; goto unlock; diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 9807bc9d296e..59adcf8532dd 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -291,8 +291,6 @@ static void vc4_bo_cache_free_old(struct drm_device *dev) /* Called on the last userspace/kernel unreference of the BO. Returns * it to the BO cache if possible, otherwise frees it. - * - * Note that this is called with the struct_mutex held. */ void vc4_free_object(struct drm_gem_object *gem_bo) { @@ -457,7 +455,7 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, struct drm_vc4_mmap_bo *args = data; struct drm_gem_object *gem_obj; - gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); + gem_obj = drm_gem_object_lookup(file_priv, args->handle); if (!gem_obj) { DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); return -EINVAL; diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 231356f42a04..904d0754ad78 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -650,7 +650,7 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc, } - __drm_atomic_helper_crtc_destroy_state(crtc, state); + __drm_atomic_helper_crtc_destroy_state(state); } static const struct drm_crtc_funcs vc4_crtc_funcs = { diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 143dd98aa079..58b8fc036332 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -99,7 +99,7 @@ static struct drm_driver vc4_drm_driver = { #endif .gem_create_object = vc4_create_object, - .gem_free_object = vc4_free_object, + .gem_free_object_unlocked = vc4_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, @@ -154,6 +154,24 @@ static void vc4_match_add_drivers(struct device *dev, } } +static void vc4_kick_out_firmware_fb(void) +{ + struct apertures_struct *ap; + + ap = alloc_apertures(1); + if (!ap) + return; + + /* Since VC4 is a UMA device, the simplefb node may have been + * located anywhere in memory. + */ + ap->ranges[0].base = 0; + ap->ranges[0].size = ~0; + + remove_conflicting_framebuffers(ap, "vc4drmfb", false); + kfree(ap); +} + static int vc4_drm_bind(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -187,6 +205,8 @@ static int vc4_drm_bind(struct device *dev) if (ret) goto gem_destroy; + vc4_kick_out_firmware_fb(); + ret = drm_dev_register(drm, 0); if (ret < 0) goto unbind_all; diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 8d4384f8b78d..6155e8aca1c6 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -53,10 +53,8 @@ vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state) { unsigned int i; - mutex_lock(&dev->struct_mutex); for (i = 0; i < state->user_state.bo_count; i++) - drm_gem_object_unreference(state->bo[i]); - mutex_unlock(&dev->struct_mutex); + drm_gem_object_unreference_unlocked(state->bo[i]); kfree(state); } @@ -687,11 +685,9 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) struct vc4_dev *vc4 = to_vc4_dev(dev); unsigned i; - /* Need the struct lock for drm_gem_object_unreference(). */ - mutex_lock(&dev->struct_mutex); if (exec->bo) { for (i = 0; i < exec->bo_count; i++) - drm_gem_object_unreference(&exec->bo[i]->base); + drm_gem_object_unreference_unlocked(&exec->bo[i]->base); kfree(exec->bo); } @@ -699,9 +695,8 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) struct vc4_bo *bo = list_first_entry(&exec->unref_list, struct vc4_bo, unref_head); list_del(&bo->unref_head); - drm_gem_object_unreference(&bo->base.base); + drm_gem_object_unreference_unlocked(&bo->base.base); } - mutex_unlock(&dev->struct_mutex); mutex_lock(&vc4->power_lock); if (--vc4->power_refcount == 0) @@ -822,7 +817,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data, if (args->pad != 0) return -EINVAL; - gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle); + gem_obj = drm_gem_object_lookup(file_priv, args->handle); if (!gem_obj) { DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); return -EINVAL; diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index d423ba10239a..cb37751bc99f 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -207,8 +207,6 @@ int vc4_kms_load(struct drm_device *dev) dev->mode_config.preferred_depth = 24; dev->mode_config.async_page_flip = true; - dev->vblank_disable_allowed = true; - drm_mode_config_reset(dev); vc4->fbdev = drm_fbdev_cma_init(dev, 32, diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 7b0c72ae02a0..4037b52fde31 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -208,7 +208,7 @@ static void vc4_plane_destroy_state(struct drm_plane *plane, } kfree(vc4_state->dlist); - __drm_atomic_helper_plane_destroy_state(plane, &vc4_state->base); + __drm_atomic_helper_plane_destroy_state(&vc4_state->base); kfree(state); } diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index ae4de36d1d83..1b4cc8b27080 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -200,7 +200,7 @@ int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev, int ret = 0; struct drm_gem_object *obj; - obj = drm_gem_object_lookup(dev, file, handle); + obj = drm_gem_object_lookup(file, handle); if (!obj) return -ENOENT; @@ -235,7 +235,7 @@ static const struct file_operations vgem_driver_fops = { static struct drm_driver vgem_driver = { .driver_features = DRIVER_GEM, - .gem_free_object = vgem_gem_free_object, + .gem_free_object_unlocked = vgem_gem_free_object, .gem_vm_ops = &vgem_gem_vm_ops, .ioctls = vgem_ioctls, .fops = &vgem_driver_fops, diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index d37ecad0c243..d4305da88f44 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -68,7 +68,7 @@ static int virtio_gpu_crtc_cursor_set(struct drm_crtc *crtc, } /* lookup the cursor */ - gobj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + gobj = drm_gem_object_lookup(file_priv, handle); if (gobj == NULL) return -ENOENT; @@ -447,7 +447,7 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev, int ret; /* lookup object associated with res handle */ - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); + obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); if (!obj) return ERR_PTR(-EINVAL); diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index 1feb7cee3f0d..336a57fd6d5d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -130,7 +130,7 @@ int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, struct drm_gem_object *gobj; struct virtio_gpu_object *obj; BUG_ON(!offset_p); - gobj = drm_gem_object_lookup(dev, file_priv, handle); + gobj = drm_gem_object_lookup(file_priv, handle); if (gobj == NULL) return -ENOENT; obj = gem_to_virtio_gpu_obj(gobj); diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index b4de18e65db8..c046903cb47b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -133,8 +133,7 @@ static int virtio_gpu_execbuffer(struct drm_device *dev, } for (i = 0; i < exbuf->num_bo_handles; i++) { - gobj = drm_gem_object_lookup(dev, - drm_file, bo_handles[i]); + gobj = drm_gem_object_lookup(drm_file, bo_handles[i]); if (!gobj) { drm_free_large(bo_handles); drm_free_large(buflist); @@ -345,7 +344,7 @@ static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *gobj = NULL; struct virtio_gpu_object *qobj = NULL; - gobj = drm_gem_object_lookup(dev, file_priv, ri->bo_handle); + gobj = drm_gem_object_lookup(file_priv, ri->bo_handle); if (gobj == NULL) return -ENOENT; @@ -374,7 +373,7 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, if (vgdev->has_virgl_3d == false) return -ENOSYS; - gobj = drm_gem_object_lookup(dev, file, args->bo_handle); + gobj = drm_gem_object_lookup(file, args->bo_handle); if (gobj == NULL) return -ENOENT; @@ -418,7 +417,7 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, int ret; u32 offset = args->offset; - gobj = drm_gem_object_lookup(dev, file, args->bo_handle); + gobj = drm_gem_object_lookup(file, args->bo_handle); if (gobj == NULL) return -ENOENT; @@ -464,7 +463,7 @@ static int virtio_gpu_wait_ioctl(struct drm_device *dev, void *data, int ret; bool nowait = false; - gobj = drm_gem_object_lookup(dev, file, args->handle); + gobj = drm_gem_object_lookup(file, args->handle); if (gobj == NULL) return -ENOENT; diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 70b44a2345ab..e50674bccb09 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -63,11 +63,17 @@ static void virtio_gpu_plane_atomic_update(struct drm_plane *plane, { struct drm_device *dev = plane->dev; struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(plane->crtc); + struct virtio_gpu_output *output = NULL; struct virtio_gpu_framebuffer *vgfb; struct virtio_gpu_object *bo; uint32_t handle; + if (plane->state->crtc) + output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); + if (old_state->crtc) + output = drm_crtc_to_virtio_gpu_output(old_state->crtc); + WARN_ON(!output); + if (plane->state->fb) { vgfb = to_virtio_gpu_framebuffer(plane->state->fb); bo = gem_to_virtio_gpu_obj(vgfb->obj); diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile index d281575bbe11..473d00451b0f 100644 --- a/drivers/gpu/drm/vmwgfx/Makefile +++ b/drivers/gpu/drm/vmwgfx/Makefile @@ -8,6 +8,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.o \ vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \ vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \ - vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o + vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9555e204814a..9fcd8200d485 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright © 2009-2015 VMware, Inc., Palo Alto, CA., USA + * Copyright © 2009-2016 VMware, Inc., Palo Alto, CA., USA * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -44,6 +44,12 @@ #define VMW_MIN_INITIAL_WIDTH 800 #define VMW_MIN_INITIAL_HEIGHT 600 +#ifndef VMWGFX_GIT_VERSION +#define VMWGFX_GIT_VERSION "Unknown" +#endif + +#define VMWGFX_REPO "In Tree" + /** * Fully encoded drm commands. Might move to vmw_drm.h @@ -613,6 +619,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) uint32_t svga_id; enum vmw_res_type i; bool refuse_dma = false; + char host_log[100] = {0}; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (unlikely(dev_priv == NULL)) { @@ -628,6 +635,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) mutex_init(&dev_priv->cmdbuf_mutex); mutex_init(&dev_priv->release_mutex); mutex_init(&dev_priv->binding_mutex); + mutex_init(&dev_priv->global_kms_state_mutex); rwlock_init(&dev_priv->resource_lock); ttm_lock_init(&dev_priv->reservation_sem); spin_lock_init(&dev_priv->hw_lock); @@ -873,6 +881,16 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) DRM_INFO("DX: %s\n", dev_priv->has_dx ? "yes." : "no."); + snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", + VMWGFX_REPO, VMWGFX_GIT_VERSION); + vmw_host_log(host_log); + + memset(host_log, 0, sizeof(host_log)); + snprintf(host_log, sizeof(host_log), "vmwgfx: Module Version: %d.%d.%d", + VMWGFX_DRIVER_MAJOR, VMWGFX_DRIVER_MINOR, + VMWGFX_DRIVER_PATCHLEVEL); + vmw_host_log(host_log); + if (dev_priv->enable_fb) { vmw_fifo_resource_inc(dev_priv); vmw_svga_enable(dev_priv); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 019a6ca3e8e9..1980e2a28265 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -412,6 +412,7 @@ struct vmw_private { struct drm_property *implicit_placement_property; unsigned num_implicit; struct vmw_framebuffer *implicit_fb; + struct mutex global_kms_state_mutex; /* * Context and surface management. @@ -1234,4 +1235,10 @@ static inline void vmw_mmio_write(u32 value, u32 *addr) { WRITE_ONCE(*addr, value); } + +/** + * Add vmw_msg module function + */ +extern int vmw_host_log(const char *log); + #endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index fc20d45e3da9..55231cce73a0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2143,13 +2143,13 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, void vmw_kms_del_active(struct vmw_private *dev_priv, struct vmw_display_unit *du) { - lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex); - + mutex_lock(&dev_priv->global_kms_state_mutex); if (du->active_implicit) { if (--(dev_priv->num_implicit) == 0) dev_priv->implicit_fb = NULL; du->active_implicit = false; } + mutex_unlock(&dev_priv->global_kms_state_mutex); } /** @@ -2165,8 +2165,7 @@ void vmw_kms_add_active(struct vmw_private *dev_priv, struct vmw_display_unit *du, struct vmw_framebuffer *vfb) { - lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex); - + mutex_lock(&dev_priv->global_kms_state_mutex); WARN_ON_ONCE(!dev_priv->num_implicit && dev_priv->implicit_fb); if (!du->active_implicit && du->is_implicit) { @@ -2174,6 +2173,7 @@ void vmw_kms_add_active(struct vmw_private *dev_priv, du->active_implicit = true; dev_priv->num_implicit++; } + mutex_unlock(&dev_priv->global_kms_state_mutex); } /** @@ -2190,16 +2190,13 @@ bool vmw_kms_crtc_flippable(struct vmw_private *dev_priv, struct drm_crtc *crtc) { struct vmw_display_unit *du = vmw_crtc_to_du(crtc); + bool ret; - lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex); - - if (!du->is_implicit) - return true; - - if (dev_priv->num_implicit != 1) - return false; + mutex_lock(&dev_priv->global_kms_state_mutex); + ret = !du->is_implicit || dev_priv->num_implicit == 1; + mutex_unlock(&dev_priv->global_kms_state_mutex); - return true; + return ret; } /** @@ -2214,16 +2211,18 @@ void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv, struct vmw_display_unit *du = vmw_crtc_to_du(crtc); struct vmw_framebuffer *vfb; - lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex); + mutex_lock(&dev_priv->global_kms_state_mutex); if (!du->is_implicit) - return; + goto out_unlock; vfb = vmw_framebuffer_to_vfb(crtc->primary->fb); WARN_ON_ONCE(dev_priv->num_implicit != 1 && dev_priv->implicit_fb != vfb); dev_priv->implicit_fb = vfb; +out_unlock: + mutex_unlock(&dev_priv->global_kms_state_mutex); } /** diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c new file mode 100644 index 000000000000..6de283c8fa3e --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -0,0 +1,416 @@ +/* + * Copyright © 2016 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <asm/hypervisor.h> +#include "drmP.h" +#include "vmwgfx_msg.h" + + +#define MESSAGE_STATUS_SUCCESS 0x0001 +#define MESSAGE_STATUS_DORECV 0x0002 +#define MESSAGE_STATUS_CPT 0x0010 +#define MESSAGE_STATUS_HB 0x0080 + +#define RPCI_PROTOCOL_NUM 0x49435052 +#define GUESTMSG_FLAG_COOKIE 0x80000000 + +#define RETRIES 3 + +#define VMW_HYPERVISOR_MAGIC 0x564D5868 +#define VMW_HYPERVISOR_PORT 0x5658 +#define VMW_HYPERVISOR_HB_PORT 0x5659 + +#define VMW_PORT_CMD_MSG 30 +#define VMW_PORT_CMD_HB_MSG 0 +#define VMW_PORT_CMD_OPEN_CHANNEL (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_CLOSE_CHANNEL (MSG_TYPE_CLOSE << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_SENDSIZE (MSG_TYPE_SENDSIZE << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_RECVSIZE (MSG_TYPE_RECVSIZE << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_RECVSTATUS (MSG_TYPE_RECVSTATUS << 16 | VMW_PORT_CMD_MSG) + +#define HIGH_WORD(X) ((X & 0xFFFF0000) >> 16) + +static u32 vmw_msg_enabled = 1; + +enum rpc_msg_type { + MSG_TYPE_OPEN, + MSG_TYPE_SENDSIZE, + MSG_TYPE_SENDPAYLOAD, + MSG_TYPE_RECVSIZE, + MSG_TYPE_RECVPAYLOAD, + MSG_TYPE_RECVSTATUS, + MSG_TYPE_CLOSE, +}; + +struct rpc_channel { + u16 channel_id; + u32 cookie_high; + u32 cookie_low; +}; + + + +/** + * vmw_open_channel + * + * @channel: RPC channel + * @protocol: + * + * Returns: 0 on success + */ +static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol) +{ + unsigned long eax, ebx, ecx, edx, si = 0, di = 0; + + VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL, + (protocol | GUESTMSG_FLAG_COOKIE), si, di, + VMW_HYPERVISOR_PORT, + VMW_HYPERVISOR_MAGIC, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) + return -EINVAL; + + channel->channel_id = HIGH_WORD(edx); + channel->cookie_high = si; + channel->cookie_low = di; + + return 0; +} + + + +/** + * vmw_close_channel + * + * @channel: RPC channel + * + * Returns: 0 on success + */ +static int vmw_close_channel(struct rpc_channel *channel) +{ + unsigned long eax, ebx, ecx, edx, si, di; + + /* Set up additional parameters */ + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL, + 0, si, di, + (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)), + VMW_HYPERVISOR_MAGIC, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) + return -EINVAL; + + return 0; +} + + + +/** + * vmw_send_msg: Sends a message to the host + * + * @channel: RPC channel + * @logmsg: NULL terminated string + * + * Returns: 0 on success + */ +static int vmw_send_msg(struct rpc_channel *channel, const char *msg) +{ + unsigned long eax, ebx, ecx, edx, si, di, bp; + size_t msg_len = strlen(msg); + int retries = 0; + + + while (retries < RETRIES) { + retries++; + + /* Set up additional parameters */ + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_SENDSIZE, + msg_len, si, di, + VMW_HYPERVISOR_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || + (HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) { + /* Expected success + high-bandwidth. Give up. */ + return -EINVAL; + } + + /* Send msg */ + si = (uintptr_t) msg; + di = channel->cookie_low; + bp = channel->cookie_high; + + VMW_PORT_HB_OUT( + (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, + msg_len, si, di, + VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, bp, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) != 0) { + return 0; + } else if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) { + /* A checkpoint occurred. Retry. */ + continue; + } else { + break; + } + } + + return -EINVAL; +} + + + +/** + * vmw_recv_msg: Receives a message from the host + * + * Note: It is the caller's responsibility to call kfree() on msg. + * + * @channel: channel opened by vmw_open_channel + * @msg: [OUT] message received from the host + * @msg_len: message length + */ +static int vmw_recv_msg(struct rpc_channel *channel, void **msg, + size_t *msg_len) +{ + unsigned long eax, ebx, ecx, edx, si, di, bp; + char *reply; + size_t reply_len; + int retries = 0; + + + *msg_len = 0; + *msg = NULL; + + while (retries < RETRIES) { + retries++; + + /* Set up additional parameters */ + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_RECVSIZE, + 0, si, di, + (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)), + VMW_HYPERVISOR_MAGIC, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 || + (HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) { + DRM_ERROR("Failed to get reply size\n"); + return -EINVAL; + } + + /* No reply available. This is okay. */ + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_DORECV) == 0) + return 0; + + reply_len = ebx; + reply = kzalloc(reply_len + 1, GFP_KERNEL); + if (reply == NULL) { + DRM_ERROR("Cannot allocate memory for reply\n"); + return -ENOMEM; + } + + + /* Receive buffer */ + si = channel->cookie_high; + di = (uintptr_t) reply; + bp = channel->cookie_low; + + VMW_PORT_HB_IN( + (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, + reply_len, si, di, + VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, bp, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) { + kfree(reply); + + if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) { + /* A checkpoint occurred. Retry. */ + continue; + } + + return -EINVAL; + } + + reply[reply_len] = '\0'; + + + /* Ack buffer */ + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_RECVSTATUS, + MESSAGE_STATUS_SUCCESS, si, di, + (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)), + VMW_HYPERVISOR_MAGIC, + eax, ebx, ecx, edx, si, di); + + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { + kfree(reply); + + if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) { + /* A checkpoint occurred. Retry. */ + continue; + } + + return -EINVAL; + } + + break; + } + + *msg_len = reply_len; + *msg = reply; + + return 0; +} + + +/** + * vmw_host_get_guestinfo: Gets a GuestInfo parameter + * + * Gets the value of a GuestInfo.* parameter. The value returned will be in + * a string, and it is up to the caller to post-process. + * + * @guest_info_param: Parameter to get, e.g. GuestInfo.svga.gl3 + * @buffer: if NULL, *reply_len will contain reply size. + * @length: size of the reply_buf. Set to size of reply upon return + * + * Returns: 0 on success + */ +int vmw_host_get_guestinfo(const char *guest_info_param, + char *buffer, size_t *length) +{ + struct rpc_channel channel; + char *msg, *reply = NULL; + size_t msg_len, reply_len = 0; + int ret = 0; + + + if (!vmw_msg_enabled) + return -ENODEV; + + if (!guest_info_param || !length) + return -EINVAL; + + msg_len = strlen(guest_info_param) + strlen("info-get ") + 1; + msg = kzalloc(msg_len, GFP_KERNEL); + if (msg == NULL) { + DRM_ERROR("Cannot allocate memory to get %s", guest_info_param); + return -ENOMEM; + } + + sprintf(msg, "info-get %s", guest_info_param); + + if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) || + vmw_send_msg(&channel, msg) || + vmw_recv_msg(&channel, (void *) &reply, &reply_len) || + vmw_close_channel(&channel)) { + DRM_ERROR("Failed to get %s", guest_info_param); + + ret = -EINVAL; + } + + if (buffer && reply && reply_len > 0) { + /* Remove reply code, which are the first 2 characters of + * the reply + */ + reply_len = max(reply_len - 2, (size_t) 0); + reply_len = min(reply_len, *length); + + if (reply_len > 0) + memcpy(buffer, reply + 2, reply_len); + } + + *length = reply_len; + + kfree(reply); + kfree(msg); + + return ret; +} + + + +/** + * vmw_host_log: Sends a log message to the host + * + * @log: NULL terminated string + * + * Returns: 0 on success + */ +int vmw_host_log(const char *log) +{ + struct rpc_channel channel; + char *msg; + int msg_len; + int ret = 0; + + + if (!vmw_msg_enabled) + return -ENODEV; + + if (!log) + return ret; + + msg_len = strlen(log) + strlen("log ") + 1; + msg = kzalloc(msg_len, GFP_KERNEL); + if (msg == NULL) { + DRM_ERROR("Cannot allocate memory for log message\n"); + return -ENOMEM; + } + + sprintf(msg, "log %s", log); + + if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) || + vmw_send_msg(&channel, msg) || + vmw_close_channel(&channel)) { + DRM_ERROR("Failed to send log\n"); + + ret = -EINVAL; + } + + kfree(msg); + + return ret; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.h b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.h new file mode 100644 index 000000000000..557a033fb610 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2016, VMware, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * Based on code from vmware.c and vmmouse.c. + * Author: + * Sinclair Yeh <syeh@vmware.com> + */ +#ifndef _VMWGFX_MSG_H +#define _VMWGFX_MSG_H + + +/** + * Hypervisor-specific bi-directional communication channel. Should never + * execute on bare metal hardware. The caller must make sure to check for + * supported hypervisor before using these macros. + * + * The last two parameters are both input and output and must be initialized. + * + * @cmd: [IN] Message Cmd + * @in_ebx: [IN] Message Len, through EBX + * @in_si: [IN] Input argument through SI, set to 0 if not used + * @in_di: [IN] Input argument through DI, set ot 0 if not used + * @port_num: [IN] port number + [channel id] + * @magic: [IN] hypervisor magic value + * @eax: [OUT] value of EAX register + * @ebx: [OUT] e.g. status from an HB message status command + * @ecx: [OUT] e.g. status from a non-HB message status command + * @edx: [OUT] e.g. channel id + * @si: [OUT] + * @di: [OUT] + */ +#define VMW_PORT(cmd, in_ebx, in_si, in_di, \ + port_num, magic, \ + eax, ebx, ecx, edx, si, di) \ +({ \ + asm volatile ("inl %%dx, %%eax;" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(in_ebx), \ + "c"(cmd), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di) : \ + "memory"); \ +}) + + +/** + * Hypervisor-specific bi-directional communication channel. Should never + * execute on bare metal hardware. The caller must make sure to check for + * supported hypervisor before using these macros. + * + * The last 3 parameters are both input and output and must be initialized. + * + * @cmd: [IN] Message Cmd + * @in_ecx: [IN] Message Len, through ECX + * @in_si: [IN] Input argument through SI, set to 0 if not used + * @in_di: [IN] Input argument through DI, set to 0 if not used + * @port_num: [IN] port number + [channel id] + * @magic: [IN] hypervisor magic value + * @bp: [IN] + * @eax: [OUT] value of EAX register + * @ebx: [OUT] e.g. status from an HB message status command + * @ecx: [OUT] e.g. status from a non-HB message status command + * @edx: [OUT] e.g. channel id + * @si: [OUT] + * @di: [OUT] + */ +#ifdef __x86_64__ + +#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \ + port_num, magic, bp, \ + eax, ebx, ecx, edx, si, di) \ +({ \ + asm volatile ("push %%rbp;" \ + "mov %12, %%rbp;" \ + "rep outsb;" \ + "pop %%rbp;" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_ecx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "r"(bp) : \ + "memory", "cc"); \ +}) + + +#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \ + port_num, magic, bp, \ + eax, ebx, ecx, edx, si, di) \ +({ \ + asm volatile ("push %%rbp;" \ + "mov %12, %%rbp;" \ + "rep insb;" \ + "pop %%rbp" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_ecx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "r"(bp) : \ + "memory", "cc"); \ +}) + +#else + +/* In the 32-bit version of this macro, we use "m" because there is no + * more register left for bp + */ +#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \ + port_num, magic, bp, \ + eax, ebx, ecx, edx, si, di) \ +({ \ + asm volatile ("push %%ebp;" \ + "mov %12, %%ebp;" \ + "rep outsb;" \ + "pop %%ebp;" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_ecx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "m"(bp) : \ + "memory", "cc"); \ +}) + + +#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \ + port_num, magic, bp, \ + eax, ebx, ecx, edx, si, di) \ +({ \ + asm volatile ("push %%ebp;" \ + "mov %12, %%ebp;" \ + "rep insb;" \ + "pop %%ebp" : \ + "=a"(eax), \ + "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_ecx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "m"(bp) : \ + "memory", "cc"); \ +}) +#endif /* #if __x86_64__ */ + +#endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 0ea22fd112c9..b74eae2b8594 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -285,14 +285,17 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) } /* Only one active implicit frame-buffer at a time. */ + mutex_lock(&dev_priv->global_kms_state_mutex); if (sou->base.is_implicit && dev_priv->implicit_fb && vfb && !(dev_priv->num_implicit == 1 && sou->base.active_implicit) && dev_priv->implicit_fb != vfb) { + mutex_unlock(&dev_priv->global_kms_state_mutex); DRM_ERROR("Multiple implicit framebuffers not supported.\n"); return -EINVAL; } + mutex_unlock(&dev_priv->global_kms_state_mutex); /* since they always map one to one these are safe */ connector = &sou->base.connector; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index b949102ad864..9ca818fb034c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -553,12 +553,15 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set) } /* Only one active implicit frame-buffer at a time. */ + mutex_lock(&dev_priv->global_kms_state_mutex); if (!turning_off && stdu->base.is_implicit && dev_priv->implicit_fb && !(dev_priv->num_implicit == 1 && stdu->base.active_implicit) && dev_priv->implicit_fb != vfb) { + mutex_unlock(&dev_priv->global_kms_state_mutex); DRM_ERROR("Multiple implicit framebuffers not supported.\n"); return -EINVAL; } + mutex_unlock(&dev_priv->global_kms_state_mutex); /* Since they always map one to one these are safe */ connector = &stdu->base.connector; diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c index 498b37e39058..e1e31e9e67cd 100644 --- a/drivers/gpu/host1x/hw/intr_hw.c +++ b/drivers/gpu/host1x/hw/intr_hw.c @@ -85,7 +85,7 @@ static int _host1x_intr_init_host_sync(struct host1x *host, u32 cpm, err = devm_request_irq(host->dev, host->intr_syncpt_irq, syncpt_thresh_isr, IRQF_SHARED, "host1x_syncpt", host); - if (IS_ERR_VALUE(err)) { + if (err < 0) { WARN_ON(1); return err; } diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index abb98c77bad2..99dcacf05b99 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -997,7 +997,7 @@ struct ipu_platform_reg { }; /* These must be in the order of the corresponding device tree port nodes */ -static const struct ipu_platform_reg client_reg[] = { +static struct ipu_platform_reg client_reg[] = { { .pdata = { .csi = 0, @@ -1048,7 +1048,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) mutex_unlock(&ipu_client_id_mutex); for (i = 0; i < ARRAY_SIZE(client_reg); i++) { - const struct ipu_platform_reg *reg = &client_reg[i]; + struct ipu_platform_reg *reg = &client_reg[i]; struct platform_device *pdev; struct device_node *of_node; @@ -1070,6 +1070,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) pdev->dev.parent = dev; + reg->pdata.of_node = of_node; ret = platform_device_add_data(pdev, ®->pdata, sizeof(reg->pdata)); if (!ret) diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index cbd7c986d926..2df216b39cc5 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -30,6 +30,7 @@ #define pr_fmt(fmt) "vga_switcheroo: " fmt +#include <linux/apple-gmux.h> #include <linux/console.h> #include <linux/debugfs.h> #include <linux/fb.h> @@ -308,7 +309,8 @@ static int register_client(struct pci_dev *pdev, * * Register vga client (GPU). Enable vga_switcheroo if another GPU and a * handler have already registered. The power state of the client is assumed - * to be ON. + * to be ON. Beforehand, vga_switcheroo_client_probe_defer() shall be called + * to ensure that all prerequisites are met. * * Return: 0 on success, -ENOMEM on memory allocation error. */ @@ -329,7 +331,8 @@ EXPORT_SYMBOL(vga_switcheroo_register_client); * @id: client identifier * * Register audio client (audio device on a GPU). The power state of the - * client is assumed to be ON. + * client is assumed to be ON. Beforehand, vga_switcheroo_client_probe_defer() + * shall be called to ensure that all prerequisites are met. * * Return: 0 on success, -ENOMEM on memory allocation error. */ @@ -376,6 +379,33 @@ find_active_client(struct list_head *head) } /** + * vga_switcheroo_client_probe_defer() - whether to defer probing a given client + * @pdev: client pci device + * + * Determine whether any prerequisites are not fulfilled to probe a given + * client. Drivers shall invoke this early on in their ->probe callback + * and return %-EPROBE_DEFER if it evaluates to %true. Thou shalt not + * register the client ere thou hast called this. + * + * Return: %true if probing should be deferred, otherwise %false. + */ +bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) +{ + if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { + /* + * apple-gmux is needed on pre-retina MacBook Pro + * to probe the panel if pdev is the inactive GPU. + */ + if (apple_gmux_present() && pdev != vga_default_device() && + !vgasr_priv.handler_flags) + return true; + } + + return false; +} +EXPORT_SYMBOL(vga_switcheroo_client_probe_defer); + +/** * vga_switcheroo_get_client_state() - obtain power state of a given client * @pdev: client pci device * |