/* * SPDX-License-Identifier: MIT * * Copyright © 2008 Intel Corporation */ #include <linux/string.h> #include <linux/bitops.h> #include "i915_drv.h" #include "i915_gem.h" #include "i915_gem_ioctls.h" #include "i915_gem_mman.h" #include "i915_gem_object.h" #include "i915_gem_tiling.h" #include "i915_reg.h" /** * DOC: buffer object tiling * * i915_gem_set_tiling_ioctl() and i915_gem_get_tiling_ioctl() is the userspace * interface to declare fence register requirements. * * In principle GEM doesn't care at all about the internal data layout of an * object, and hence it also doesn't care about tiling or swizzling. There's two * exceptions: * * - For X and Y tiling the hardware provides detilers for CPU access, so called * fences. Since there's only a limited amount of them the kernel must manage * these, and therefore userspace must tell the kernel the object tiling if it * wants to use fences for detiling. * - On gen3 and gen4 platforms have a swizzling pattern for tiled objects which * depends upon the physical page frame number. When swapping such objects the * page frame number might change and the kernel must be able to fix this up * and hence now the tiling. Note that on a subset of platforms with * asymmetric memory channel population the swizzling pattern changes in an * unknown way, and for those the kernel simply forbids swapping completely. * * Since neither of this applies for new tiling layouts on modern platforms like * W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled. * Anything else can be handled in userspace entirely without the kernel's * invovlement. */ /** * i915_gem_fence_size - required global GTT size for a fence * @i915: i915 device * @size: object size * @tiling: tiling mode * @stride: tiling stride * * Return the required global GTT size for a fence (view of a tiled object), * taking into account potential fence register mapping. */ u32 i915_gem_fence_size(struct drm_i915_private *i915, u32 size, unsigned int tiling, unsigned int stride) { … } /** * i915_gem_fence_alignment - required global GTT alignment for a fence * @i915: i915 device * @size: object size * @tiling: tiling mode * @stride: tiling stride * * Return the required global GTT alignment for a fence (a view of a tiled * object), taking into account potential fence register mapping. */ u32 i915_gem_fence_alignment(struct drm_i915_private *i915, u32 size, unsigned int tiling, unsigned int stride) { … } /* Check pitch constraints for all chips & tiling formats */ static bool i915_tiling_ok(struct drm_i915_gem_object *obj, unsigned int tiling, unsigned int stride) { … } static bool i915_vma_fence_prepare(struct i915_vma *vma, int tiling_mode, unsigned int stride) { … } /* Make the current GTT allocation valid for the change in tiling. */ static int i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj, int tiling_mode, unsigned int stride) { … } bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) { … } int i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, unsigned int tiling, unsigned int stride) { … } /** * i915_gem_set_tiling_ioctl - IOCTL handler to set tiling mode * @dev: DRM device * @data: data pointer for the ioctl * @file: DRM file for the ioctl call * * Sets the tiling mode of an object, returning the required swizzling of * bit 6 of addresses in the object. * * Called by the user via ioctl. * * Returns: * Zero on success, negative errno on failure. */ int i915_gem_set_tiling_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { … } /** * i915_gem_get_tiling_ioctl - IOCTL handler to get tiling mode * @dev: DRM device * @data: data pointer for the ioctl * @file: DRM file for the ioctl call * * Returns the current tiling mode and required bit 6 swizzling for the object. * * Called by the user via ioctl. * * Returns: * Zero on success, negative errno on failure. */ int i915_gem_get_tiling_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { … }