diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-10 12:58:46 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-10 12:58:46 -0800 |
commit | 8d0749b4f83bf4768ceae45ee6a79e6e7eddfc2a (patch) | |
tree | 069cc92e93982e0b921c09e71df6f7b68b4cbfa2 /drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | |
parent | bf4eebf8cfa2cd50e20b7321dfb3effdcdc6e909 (diff) | |
parent | cb6846fbb83b574c85c2a80211b402a6347b60b1 (diff) |
Merge tag 'drm-next-2022-01-07' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"Highlights are support for privacy screens found in new laptops, a
bunch of nomodeset refactoring, and i915 enables ADL-P systems by
default, while starting to add RPL-S support.
vmwgfx adds GEM and support for OpenGL 4.3 features in userspace.
Lots of internal refactorings around dma reservations, and lots of
driver refactoring as well.
Summary:
core:
- add privacy screen support
- move nomodeset option into drm subsystem
- clean up nomodeset handling in drivers
- make drm_irq.c legacy
- fix stack_depot name conflicts
- remove DMA_BUF_SET_NAME ioctl restrictions
- sysfs: send hotplug event
- replace several DRM_* logging macros with drm_*
- move hashtable to legacy code
- add error return from gem_create_object
- cma-helper: improve interfaces, drop CONFIG_DRM_KMS_CMA_HELPER
- kernel.h related include cleanups
- support XRGB2101010 source buffers
ttm:
- don't include drm hashtable
- stop pruning fences after wait
- documentation updates
dma-buf:
- add dma_resv selftest
- add debugfs helpers
- remove dma_resv_get_excl_unlocked
- documentation
- make fences mandatory in dma_resv_add_excl_fence
dp:
- add link training delay helpers
gem:
- link shmem/cma helpers into separate modules
- use dma_resv iteratior
- import dma-buf namespace into gem helper modules
scheduler:
- fence grab fix
- lockdep fixes
bridge:
- switch to managed MIPI DSI helpers
- register and attach during probe fixes
- convert to YAML in several places.
panel:
- add bunch of new panesl
simpledrm:
- support FB_DAMAGE_CLIPS
- support virtual screen sizes
- add Apple M1 support
amdgpu:
- enable seamless boot for DCN 3.01
- runtime PM fixes
- use drm_kms_helper_connector_hotplug_event
- get all fences at once
- use generic drm fb helpers
- PSR/DPCD/LTTPR/DSC/PM/RAS/OLED/SRIOV fixes
- add smart trace buffer (STB) for supported GPUs
- display debugfs entries
- new SMU debug option
- Documentation update
amdkfd:
- IP discovery enumeration refactor
- interface between driver fixes
- SVM fixes
- kfd uapi header to define some sysfs bitfields.
i915:
- support VESA panel backlights
- enable ADL-P by default
- add eDP privacy screen support
- add Raptor Lake S (RPL-S) support
- DG2 page table support
- lots of GuC/HuC fw refactoring
- refactored i915->gt interfaces
- CD clock squashing support
- enable 10-bit gamma support
- update ADL-P DMC fw to v2.14
- enable runtime PM autosuspend by default
- ADL-P DSI support
- per-lane DP drive settings for ICL+
- add support for pipe C/D DMC firmware
- Atomic gamma LUT updates
- remove CCS FB stride restrictions on ADL-P
- VRR platform support for display 11
- add support for display audio codec keepalive
- lots of display refactoring
- fix runtime PM handling during PXP suspend
- improved eviction performance with async TTM moves
- async VMA unbinding improvements
- VMA locking refactoring
- improved error capture robustness
- use per device iommu checks
- drop bits stealing from i915_sw_fence function ptr
- remove dma_resv_prune
- add IC cache invalidation on DG2
nouveau:
- crc fixes
- validate LUTs in atomic check
- set HDMI AVI RGB quant to full
tegra:
- buffer objects reworks for dma-buf compat
- NVDEC driver uAPI support
- power management improvements
etnaviv:
- IOMMU enabled system support
- fix > 4GB command buffer mapping
- close a DoS vector
- fix spurious GPU resets
ast:
- fix i2c initialization
rcar-du:
- DSI output support
exynos:
- replace legacy gpio interface
- implement generic GEM object mmap
msm:
- dpu plane state cleanup in prep for multirect
- dpu debugfs cleanups
- dp support for sc7280
- a506 support
- removal of struct_mutex
- remove old eDP sub-driver
anx7625:
- support MIPI DSI input
- support HDMI audio
- fix reading EDID
lvds:
- fix bridge DT bindings
megachips:
- probe both bridges before registering
dw-hdmi:
- allow interlace on bridge
ps8640:
- enable runtime PM
- support aux-bus
tx358768:
- enable reference clock
- add pulse mode support
ti-sn65dsi86:
- use regmap bulk write
- add PWM support
etnaviv:
- get all fences at once
gma500:
- gem object cleanups
kmb:
- enable fb console
radeon:
- use dma_resv_wait_timeout
rockchip:
- add DSP hold timeout
- suspend/resume fixes
- PLL clock fixes
- implement mmap in GEM object functions
- use generic fbdev emulation
sun4i:
- use CMA helpers without vmap support
vc4:
- fix HDMI-CEC hang with display is off
- power on HDMI controller while disabling
- support 4K@60Hz modes
- support 10-bit YUV 4:2:0 output
vmwgfx:
- fix leak on probe errors
- fail probing on broken hosts
- new placement for MOB page tables
- hide internal BOs from userspace
- implement GEM support
- implement GL 4.3 support
virtio:
- overflow fixes
xen:
- implement mmap as GEM object function
omapdrm:
- fix scatterlist export
- support virtual planes
mediatek:
- MT8192 support
- CMDQ refinement"
* tag 'drm-next-2022-01-07' of git://anongit.freedesktop.org/drm/drm: (1241 commits)
drm/amdgpu: no DC support for headless chips
drm/amd/display: fix dereference before NULL check
drm/amdgpu: always reset the asic in suspend (v2)
drm/amdgpu: put SMU into proper state on runpm suspending for BOCO capable platform
drm/amd/display: Fix the uninitialized variable in enable_stream_features()
drm/amdgpu: fix runpm documentation
amdgpu/pm: Make sysfs pm attributes as read-only for VFs
drm/amdgpu: save error count in RAS poison handler
drm/amdgpu: drop redundant semicolon
drm/amd/display: get and restore link res map
drm/amd/display: support dynamic HPO DP link encoder allocation
drm/amd/display: access hpo dp link encoder only through link resource
drm/amd/display: populate link res in both detection and validation
drm/amd/display: define link res and make it accessible to all link interfaces
drm/amd/display: 3.2.167
drm/amd/display: [FW Promotion] Release 0.0.98
drm/amd/display: Undo ODM combine
drm/amd/display: Add reg defs for DCN303
drm/amd/display: Changed pipe split policy to allow for multi-display pipe split
drm/amd/display: Set optimize_pwr_state for DCN31
...
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_gem.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c new file mode 100644 index 000000000000..ce609e7d758f --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c @@ -0,0 +1,294 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* + * Copyright 2021 VMware, 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 AUTHORS OR COPYRIGHT HOLDERS + * 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 "vmwgfx_drv.h" + +#include "drm/drm_prime.h" +#include "drm/drm_gem_ttm_helper.h" + +/** + * vmw_buffer_object - Convert a struct ttm_buffer_object to a struct + * vmw_buffer_object. + * + * @bo: Pointer to the TTM buffer object. + * Return: Pointer to the struct vmw_buffer_object embedding the + * TTM buffer object. + */ +static struct vmw_buffer_object * +vmw_buffer_object(struct ttm_buffer_object *bo) +{ + return container_of(bo, struct vmw_buffer_object, base); +} + +static void vmw_gem_object_free(struct drm_gem_object *gobj) +{ + struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gobj); + if (bo) { + ttm_bo_put(bo); + } +} + +static int vmw_gem_object_open(struct drm_gem_object *obj, + struct drm_file *file_priv) +{ + return 0; +} + +static void vmw_gem_object_close(struct drm_gem_object *obj, + struct drm_file *file_priv) +{ +} + +static int vmw_gem_pin_private(struct drm_gem_object *obj, bool do_pin) +{ + struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(obj); + struct vmw_buffer_object *vbo = vmw_buffer_object(bo); + int ret; + + ret = ttm_bo_reserve(bo, false, false, NULL); + if (unlikely(ret != 0)) + goto err; + + vmw_bo_pin_reserved(vbo, do_pin); + + ttm_bo_unreserve(bo); + +err: + return ret; +} + + +static int vmw_gem_object_pin(struct drm_gem_object *obj) +{ + return vmw_gem_pin_private(obj, true); +} + +static void vmw_gem_object_unpin(struct drm_gem_object *obj) +{ + vmw_gem_pin_private(obj, false); +} + +static struct sg_table *vmw_gem_object_get_sg_table(struct drm_gem_object *obj) +{ + struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(obj); + struct vmw_ttm_tt *vmw_tt = + container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm); + + if (vmw_tt->vsgt.sgt) + return vmw_tt->vsgt.sgt; + + return drm_prime_pages_to_sg(obj->dev, vmw_tt->dma_ttm.pages, vmw_tt->dma_ttm.num_pages); +} + + +static const struct drm_gem_object_funcs vmw_gem_object_funcs = { + .free = vmw_gem_object_free, + .open = vmw_gem_object_open, + .close = vmw_gem_object_close, + .print_info = drm_gem_ttm_print_info, + .pin = vmw_gem_object_pin, + .unpin = vmw_gem_object_unpin, + .get_sg_table = vmw_gem_object_get_sg_table, + .vmap = drm_gem_ttm_vmap, + .vunmap = drm_gem_ttm_vunmap, + .mmap = drm_gem_ttm_mmap, +}; + +/** + * vmw_gem_destroy - vmw buffer object destructor + * + * @bo: Pointer to the embedded struct ttm_buffer_object + */ +void vmw_gem_destroy(struct ttm_buffer_object *bo) +{ + struct vmw_buffer_object *vbo = vmw_buffer_object(bo); + + WARN_ON(vbo->dirty); + WARN_ON(!RB_EMPTY_ROOT(&vbo->res_tree)); + vmw_bo_unmap(vbo); + drm_gem_object_release(&vbo->base.base); + kfree(vbo); +} + +int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, + struct drm_file *filp, + uint32_t size, + uint32_t *handle, + struct vmw_buffer_object **p_vbo) +{ + int ret; + + ret = vmw_bo_create(dev_priv, size, + (dev_priv->has_mob) ? + &vmw_sys_placement : + &vmw_vram_sys_placement, + true, false, &vmw_gem_destroy, p_vbo); + + (*p_vbo)->base.base.funcs = &vmw_gem_object_funcs; + if (ret != 0) + goto out_no_bo; + + ret = drm_gem_handle_create(filp, &(*p_vbo)->base.base, handle); + /* drop reference from allocate - handle holds it now */ + drm_gem_object_put(&(*p_vbo)->base.base); +out_no_bo: + return ret; +} + + +int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + union drm_vmw_alloc_dmabuf_arg *arg = + (union drm_vmw_alloc_dmabuf_arg *)data; + struct drm_vmw_alloc_dmabuf_req *req = &arg->req; + struct drm_vmw_dmabuf_rep *rep = &arg->rep; + struct vmw_buffer_object *vbo; + uint32_t handle; + int ret; + + ret = vmw_gem_object_create_with_handle(dev_priv, filp, + req->size, &handle, &vbo); + if (ret) + goto out_no_bo; + + rep->handle = handle; + rep->map_handle = drm_vma_node_offset_addr(&vbo->base.base.vma_node); + rep->cur_gmr_id = handle; + rep->cur_gmr_offset = 0; +out_no_bo: + return ret; +} + +#if defined(CONFIG_DEBUG_FS) + +static void vmw_bo_print_info(int id, struct vmw_buffer_object *bo, struct seq_file *m) +{ + const char *placement; + const char *type; + + switch (bo->base.resource->mem_type) { + case TTM_PL_SYSTEM: + placement = " CPU"; + break; + case VMW_PL_GMR: + placement = " GMR"; + break; + case VMW_PL_MOB: + placement = " MOB"; + break; + case VMW_PL_SYSTEM: + placement = "VCPU"; + break; + case TTM_PL_VRAM: + placement = "VRAM"; + break; + default: + placement = "None"; + break; + } + + switch (bo->base.type) { + case ttm_bo_type_device: + type = "device"; + break; + case ttm_bo_type_kernel: + type = "kernel"; + break; + case ttm_bo_type_sg: + type = "sg "; + break; + default: + type = "none "; + break; + } + + seq_printf(m, "\t\t0x%08x: %12zu bytes %s, type = %s", + id, bo->base.base.size, placement, type); + seq_printf(m, ", priority = %u, pin_count = %u, GEM refs = %d, TTM refs = %d", + bo->base.priority, + bo->base.pin_count, + kref_read(&bo->base.base.refcount), + kref_read(&bo->base.kref)); + seq_puts(m, "\n"); +} + +static int vmw_debugfs_gem_info_show(struct seq_file *m, void *unused) +{ + struct vmw_private *vdev = (struct vmw_private *)m->private; + struct drm_device *dev = &vdev->drm; + struct drm_file *file; + int r; + + r = mutex_lock_interruptible(&dev->filelist_mutex); + if (r) + return r; + + list_for_each_entry(file, &dev->filelist, lhead) { + struct task_struct *task; + struct drm_gem_object *gobj; + int id; + + /* + * Although we have a valid reference on file->pid, that does + * not guarantee that the task_struct who called get_pid() is + * still alive (e.g. get_pid(current) => fork() => exit()). + * Therefore, we need to protect this ->comm access using RCU. + */ + rcu_read_lock(); + task = pid_task(file->pid, PIDTYPE_PID); + seq_printf(m, "pid %8d command %s:\n", pid_nr(file->pid), + task ? task->comm : "<unknown>"); + rcu_read_unlock(); + + spin_lock(&file->table_lock); + idr_for_each_entry(&file->object_idr, gobj, id) { + struct vmw_buffer_object *bo = gem_to_vmw_bo(gobj); + + vmw_bo_print_info(id, bo, m); + } + spin_unlock(&file->table_lock); + } + + mutex_unlock(&dev->filelist_mutex); + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(vmw_debugfs_gem_info); + +#endif + +void vmw_debugfs_gem_init(struct vmw_private *vdev) +{ +#if defined(CONFIG_DEBUG_FS) + struct drm_minor *minor = vdev->drm.primary; + struct dentry *root = minor->debugfs_root; + + debugfs_create_file("vmwgfx_gem_info", 0444, root, vdev, + &vmw_debugfs_gem_info_fops); +#endif +} |