Subversion Repositories Kolibri OS

Rev

Rev 6084 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2008 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Eric Anholt <eric@anholt.net>
  25.  *
  26.  */
  27.  
  28. #include <linux/string.h>
  29. #include <linux/bitops.h>
  30. #include <drm/drmP.h>
  31. #include <drm/i915_drm.h>
  32. #include "i915_drv.h"
  33.  
  34. /**
  35.  * DOC: buffer object tiling
  36.  *
  37.  * i915_gem_set_tiling() and i915_gem_get_tiling() is the userspace interface to
  38.  * declare fence register requirements.
  39.  *
  40.  * In principle GEM doesn't care at all about the internal data layout of an
  41.  * object, and hence it also doesn't care about tiling or swizzling. There's two
  42.  * exceptions:
  43.  *
  44.  * - For X and Y tiling the hardware provides detilers for CPU access, so called
  45.  *   fences. Since there's only a limited amount of them the kernel must manage
  46.  *   these, and therefore userspace must tell the kernel the object tiling if it
  47.  *   wants to use fences for detiling.
  48.  * - On gen3 and gen4 platforms have a swizzling pattern for tiled objects which
  49.  *   depends upon the physical page frame number. When swapping such objects the
  50.  *   page frame number might change and the kernel must be able to fix this up
  51.  *   and hence now the tiling. Note that on a subset of platforms with
  52.  *   asymmetric memory channel population the swizzling pattern changes in an
  53.  *   unknown way, and for those the kernel simply forbids swapping completely.
  54.  *
  55.  * Since neither of this applies for new tiling layouts on modern platforms like
  56.  * W, Ys and Yf tiling GEM only allows object tiling to be set to X or Y tiled.
  57.  * Anything else can be handled in userspace entirely without the kernel's
  58.  * invovlement.
  59.  */
  60.  
  61. /* Check pitch constriants for all chips & tiling formats */
  62. static bool
  63. i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
  64. {
  65.         int tile_width;
  66.  
  67.         /* Linear is always fine */
  68.         if (tiling_mode == I915_TILING_NONE)
  69.                 return true;
  70.  
  71.         if (IS_GEN2(dev) ||
  72.             (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
  73.                 tile_width = 128;
  74.         else
  75.                 tile_width = 512;
  76.  
  77.         /* check maximum stride & object size */
  78.         /* i965+ stores the end address of the gtt mapping in the fence
  79.          * reg, so dont bother to check the size */
  80.         if (INTEL_INFO(dev)->gen >= 7) {
  81.                 if (stride / 128 > GEN7_FENCE_MAX_PITCH_VAL)
  82.                         return false;
  83.         } else if (INTEL_INFO(dev)->gen >= 4) {
  84.                 if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
  85.                         return false;
  86.         } else {
  87.                 if (stride > 8192)
  88.                         return false;
  89.  
  90.                 if (IS_GEN3(dev)) {
  91.                         if (size > I830_FENCE_MAX_SIZE_VAL << 20)
  92.                                 return false;
  93.                 } else {
  94.                         if (size > I830_FENCE_MAX_SIZE_VAL << 19)
  95.                                 return false;
  96.                 }
  97.         }
  98.  
  99.         if (stride < tile_width)
  100.                 return false;
  101.  
  102.         /* 965+ just needs multiples of tile width */
  103.         if (INTEL_INFO(dev)->gen >= 4) {
  104.                 if (stride & (tile_width - 1))
  105.                         return false;
  106.                 return true;
  107.         }
  108.  
  109.         /* Pre-965 needs power of two tile widths */
  110.         if (stride & (stride - 1))
  111.                 return false;
  112.  
  113.         return true;
  114. }
  115.  
  116. /* Is the current GTT allocation valid for the change in tiling? */
  117. static bool
  118. i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
  119. {
  120.         u32 size;
  121.  
  122.         if (tiling_mode == I915_TILING_NONE)
  123.                 return true;
  124.  
  125.         if (INTEL_INFO(obj->base.dev)->gen >= 4)
  126.                 return true;
  127.  
  128.         if (INTEL_INFO(obj->base.dev)->gen == 3) {
  129.                 if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK)
  130.                         return false;
  131.         } else {
  132.                 if (i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK)
  133.                         return false;
  134.         }
  135.  
  136.         size = i915_gem_get_gtt_size(obj->base.dev, obj->base.size, tiling_mode);
  137.         if (i915_gem_obj_ggtt_size(obj) != size)
  138.                 return false;
  139.  
  140.         if (i915_gem_obj_ggtt_offset(obj) & (size - 1))
  141.                 return false;
  142.  
  143.         return true;
  144. }
  145.  
  146. /**
  147.  * i915_gem_set_tiling - IOCTL handler to set tiling mode
  148.  * @dev: DRM device
  149.  * @data: data pointer for the ioctl
  150.  * @file: DRM file for the ioctl call
  151.  *
  152.  * Sets the tiling mode of an object, returning the required swizzling of
  153.  * bit 6 of addresses in the object.
  154.  *
  155.  * Called by the user via ioctl.
  156.  *
  157.  * Returns:
  158.  * Zero on success, negative errno on failure.
  159.  */
  160. int
  161. i915_gem_set_tiling(struct drm_device *dev, void *data,
  162.                    struct drm_file *file)
  163. {
  164.         struct drm_i915_gem_set_tiling *args = data;
  165.         struct drm_i915_private *dev_priv = dev->dev_private;
  166.         struct drm_i915_gem_object *obj;
  167.         int ret = 0;
  168.  
  169.         obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
  170.         if (&obj->base == NULL)
  171.                 return -ENOENT;
  172.  
  173.         if (!i915_tiling_ok(dev,
  174.                             args->stride, obj->base.size, args->tiling_mode)) {
  175.                 drm_gem_object_unreference_unlocked(&obj->base);
  176.                 return -EINVAL;
  177.         }
  178.  
  179.         intel_runtime_pm_get(dev_priv);
  180.  
  181.         mutex_lock(&dev->struct_mutex);
  182.         if (obj->pin_display || obj->framebuffer_references) {
  183.                 ret = -EBUSY;
  184.                 goto err;
  185.         }
  186.  
  187.         if (args->tiling_mode == I915_TILING_NONE) {
  188.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
  189.                 args->stride = 0;
  190.         } else {
  191.                 if (args->tiling_mode == I915_TILING_X)
  192.                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
  193.                 else
  194.                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
  195.  
  196.                 /* Hide bit 17 swizzling from the user.  This prevents old Mesa
  197.                  * from aborting the application on sw fallbacks to bit 17,
  198.                  * and we use the pread/pwrite bit17 paths to swizzle for it.
  199.                  * If there was a user that was relying on the swizzle
  200.                  * information for drm_intel_bo_map()ed reads/writes this would
  201.                  * break it, but we don't have any of those.
  202.                  */
  203.                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
  204.                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
  205.                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
  206.                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
  207.  
  208.                 /* If we can't handle the swizzling, make it untiled. */
  209.                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
  210.                         args->tiling_mode = I915_TILING_NONE;
  211.                         args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
  212.                         args->stride = 0;
  213.                 }
  214.         }
  215.  
  216.         if (args->tiling_mode != obj->tiling_mode ||
  217.             args->stride != obj->stride) {
  218.                 /* We need to rebind the object if its current allocation
  219.                  * no longer meets the alignment restrictions for its new
  220.                  * tiling mode. Otherwise we can just leave it alone, but
  221.                  * need to ensure that any fence register is updated before
  222.                  * the next fenced (either through the GTT or by the BLT unit
  223.                  * on older GPUs) access.
  224.                  *
  225.                  * After updating the tiling parameters, we then flag whether
  226.                  * we need to update an associated fence register. Note this
  227.                  * has to also include the unfenced register the GPU uses
  228.                  * whilst executing a fenced command for an untiled object.
  229.                  */
  230.                 if (obj->map_and_fenceable &&
  231.                     !i915_gem_object_fence_ok(obj, args->tiling_mode))
  232.                         ret = i915_gem_object_ggtt_unbind(obj);
  233.  
  234.                 if (ret == 0) {
  235.                         if (obj->pages &&
  236.                             obj->madv == I915_MADV_WILLNEED &&
  237.                             dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
  238.                                 if (args->tiling_mode == I915_TILING_NONE)
  239.                                         i915_gem_object_unpin_pages(obj);
  240.                                 if (obj->tiling_mode == I915_TILING_NONE)
  241.                                         i915_gem_object_pin_pages(obj);
  242.                         }
  243.  
  244.                         obj->fence_dirty =
  245.                                 obj->last_fenced_req ||
  246.                                 obj->fence_reg != I915_FENCE_REG_NONE;
  247.  
  248.                         obj->tiling_mode = args->tiling_mode;
  249.                         obj->stride = args->stride;
  250.  
  251.                         /* Force the fence to be reacquired for GTT access */
  252.                         i915_gem_release_mmap(obj);
  253.                 }
  254.         }
  255.         /* we have to maintain this existing ABI... */
  256.         args->stride = obj->stride;
  257.         args->tiling_mode = obj->tiling_mode;
  258.  
  259.         /* Try to preallocate memory required to save swizzling on put-pages */
  260.         if (i915_gem_object_needs_bit17_swizzle(obj)) {
  261.                 if (obj->bit_17 == NULL) {
  262.                         obj->bit_17 = kcalloc(BITS_TO_LONGS(obj->base.size >> PAGE_SHIFT),
  263.                                               sizeof(long), GFP_KERNEL);
  264.                 }
  265.         } else {
  266.                 kfree(obj->bit_17);
  267.                 obj->bit_17 = NULL;
  268.         }
  269.  
  270. err:
  271.         drm_gem_object_unreference(&obj->base);
  272.         mutex_unlock(&dev->struct_mutex);
  273.  
  274.         intel_runtime_pm_put(dev_priv);
  275.  
  276.         return ret;
  277. }
  278.  
  279. /**
  280.  * i915_gem_get_tiling - IOCTL handler to get tiling mode
  281.  * @dev: DRM device
  282.  * @data: data pointer for the ioctl
  283.  * @file: DRM file for the ioctl call
  284.  *
  285.  * Returns the current tiling mode and required bit 6 swizzling for the object.
  286.  *
  287.  * Called by the user via ioctl.
  288.  *
  289.  * Returns:
  290.  * Zero on success, negative errno on failure.
  291.  */
  292. int
  293. i915_gem_get_tiling(struct drm_device *dev, void *data,
  294.                    struct drm_file *file)
  295. {
  296.         struct drm_i915_gem_get_tiling *args = data;
  297.         struct drm_i915_private *dev_priv = dev->dev_private;
  298.         struct drm_i915_gem_object *obj;
  299.  
  300.         obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
  301.         if (&obj->base == NULL)
  302.                 return -ENOENT;
  303.  
  304.         mutex_lock(&dev->struct_mutex);
  305.  
  306.         args->tiling_mode = obj->tiling_mode;
  307.         switch (obj->tiling_mode) {
  308.         case I915_TILING_X:
  309.                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
  310.                 break;
  311.         case I915_TILING_Y:
  312.                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
  313.                 break;
  314.         case I915_TILING_NONE:
  315.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
  316.                 break;
  317.         default:
  318.                 DRM_ERROR("unknown tiling mode\n");
  319.         }
  320.  
  321.         /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
  322.         if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
  323.                 args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN;
  324.         else
  325.                 args->phys_swizzle_mode = args->swizzle_mode;
  326.         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
  327.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
  328.         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
  329.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
  330.  
  331.         drm_gem_object_unreference(&obj->base);
  332.         mutex_unlock(&dev->struct_mutex);
  333.  
  334.         return 0;
  335. }
  336.