Subversion Repositories Kolibri OS

Rev

Rev 5354 | Go to most recent revision | 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.         mutex_lock(&dev->struct_mutex);
  180.         if (obj->pin_display || obj->framebuffer_references) {
  181.                 ret = -EBUSY;
  182.                 goto err;
  183.         }
  184.  
  185.         if (args->tiling_mode == I915_TILING_NONE) {
  186.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
  187.                 args->stride = 0;
  188.         } else {
  189.                 if (args->tiling_mode == I915_TILING_X)
  190.                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
  191.                 else
  192.                         args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
  193.  
  194.                 /* Hide bit 17 swizzling from the user.  This prevents old Mesa
  195.                  * from aborting the application on sw fallbacks to bit 17,
  196.                  * and we use the pread/pwrite bit17 paths to swizzle for it.
  197.                  * If there was a user that was relying on the swizzle
  198.                  * information for drm_intel_bo_map()ed reads/writes this would
  199.                  * break it, but we don't have any of those.
  200.                  */
  201.                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
  202.                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
  203.                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
  204.                         args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
  205.  
  206.                 /* If we can't handle the swizzling, make it untiled. */
  207.                 if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
  208.                         args->tiling_mode = I915_TILING_NONE;
  209.                         args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
  210.                         args->stride = 0;
  211.                 }
  212.         }
  213.  
  214.         if (args->tiling_mode != obj->tiling_mode ||
  215.             args->stride != obj->stride) {
  216.                 /* We need to rebind the object if its current allocation
  217.                  * no longer meets the alignment restrictions for its new
  218.                  * tiling mode. Otherwise we can just leave it alone, but
  219.                  * need to ensure that any fence register is updated before
  220.                  * the next fenced (either through the GTT or by the BLT unit
  221.                  * on older GPUs) access.
  222.                  *
  223.                  * After updating the tiling parameters, we then flag whether
  224.                  * we need to update an associated fence register. Note this
  225.                  * has to also include the unfenced register the GPU uses
  226.                  * whilst executing a fenced command for an untiled object.
  227.                  */
  228.                 if (obj->map_and_fenceable &&
  229.                     !i915_gem_object_fence_ok(obj, args->tiling_mode))
  230.                         ret = i915_gem_object_ggtt_unbind(obj);
  231.  
  232.                 if (ret == 0) {
  233.                         if (obj->pages &&
  234.                             obj->madv == I915_MADV_WILLNEED &&
  235.                             dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
  236.                                 if (args->tiling_mode == I915_TILING_NONE)
  237.                                         i915_gem_object_unpin_pages(obj);
  238.                                 if (obj->tiling_mode == I915_TILING_NONE)
  239.                                         i915_gem_object_pin_pages(obj);
  240.                         }
  241.  
  242.                         obj->fence_dirty =
  243.                                 obj->last_fenced_req ||
  244.                                 obj->fence_reg != I915_FENCE_REG_NONE;
  245.  
  246.                         obj->tiling_mode = args->tiling_mode;
  247.                         obj->stride = args->stride;
  248.  
  249.                         /* Force the fence to be reacquired for GTT access */
  250.                         i915_gem_release_mmap(obj);
  251.                 }
  252.         }
  253.         /* we have to maintain this existing ABI... */
  254.         args->stride = obj->stride;
  255.         args->tiling_mode = obj->tiling_mode;
  256.  
  257.         /* Try to preallocate memory required to save swizzling on put-pages */
  258.         if (i915_gem_object_needs_bit17_swizzle(obj)) {
  259.                 if (obj->bit_17 == NULL) {
  260.                         obj->bit_17 = kcalloc(BITS_TO_LONGS(obj->base.size >> PAGE_SHIFT),
  261.                                               sizeof(long), GFP_KERNEL);
  262.                 }
  263.         } else {
  264.                 kfree(obj->bit_17);
  265.                 obj->bit_17 = NULL;
  266.         }
  267.  
  268. err:
  269.         drm_gem_object_unreference(&obj->base);
  270.         mutex_unlock(&dev->struct_mutex);
  271.  
  272.         return ret;
  273. }
  274.  
  275. /**
  276.  * i915_gem_get_tiling - IOCTL handler to get tiling mode
  277.  * @dev: DRM device
  278.  * @data: data pointer for the ioctl
  279.  * @file: DRM file for the ioctl call
  280.  *
  281.  * Returns the current tiling mode and required bit 6 swizzling for the object.
  282.  *
  283.  * Called by the user via ioctl.
  284.  *
  285.  * Returns:
  286.  * Zero on success, negative errno on failure.
  287.  */
  288. int
  289. i915_gem_get_tiling(struct drm_device *dev, void *data,
  290.                    struct drm_file *file)
  291. {
  292.         struct drm_i915_gem_get_tiling *args = data;
  293.         struct drm_i915_private *dev_priv = dev->dev_private;
  294.         struct drm_i915_gem_object *obj;
  295.  
  296.         obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
  297.         if (&obj->base == NULL)
  298.                 return -ENOENT;
  299.  
  300.         mutex_lock(&dev->struct_mutex);
  301.  
  302.         args->tiling_mode = obj->tiling_mode;
  303.         switch (obj->tiling_mode) {
  304.         case I915_TILING_X:
  305.                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
  306.                 break;
  307.         case I915_TILING_Y:
  308.                 args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
  309.                 break;
  310.         case I915_TILING_NONE:
  311.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
  312.                 break;
  313.         default:
  314.                 DRM_ERROR("unknown tiling mode\n");
  315.         }
  316.  
  317.         /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */
  318.         if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
  319.                 args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN;
  320.         else
  321.                 args->phys_swizzle_mode = args->swizzle_mode;
  322.         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17)
  323.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9;
  324.         if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17)
  325.                 args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10;
  326.  
  327.         drm_gem_object_unreference(&obj->base);
  328.         mutex_unlock(&dev->struct_mutex);
  329.  
  330.         return 0;
  331. }
  332.