25,11 → 25,10 |
* |
*/ |
|
#include "linux/string.h" |
#include "linux/bitops.h" |
#include "drmP.h" |
#include "drm.h" |
#include "i915_drm.h" |
#include <linux/string.h> |
#include <linux/bitops.h> |
#include <drm/drmP.h> |
#include <drm/i915_drm.h> |
#include "i915_drv.h" |
|
/** @file i915_gem_tiling.c |
110,9 → 109,27 |
uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; |
uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; |
|
if (INTEL_INFO(dev)->gen >= 6) { |
if (IS_VALLEYVIEW(dev)) { |
swizzle_x = I915_BIT_6_SWIZZLE_NONE; |
swizzle_y = I915_BIT_6_SWIZZLE_NONE; |
} else if (INTEL_INFO(dev)->gen >= 6) { |
uint32_t dimm_c0, dimm_c1; |
dimm_c0 = I915_READ(MAD_DIMM_C0); |
dimm_c1 = I915_READ(MAD_DIMM_C1); |
dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; |
dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; |
/* Enable swizzling when the channels are populated with |
* identically sized dimms. We don't need to check the 3rd |
* channel because no cpu with gpu attached ships in that |
* configuration. Also, swizzling only makes sense for 2 |
* channels anyway. */ |
if (dimm_c0 == dimm_c1) { |
swizzle_x = I915_BIT_6_SWIZZLE_9_10; |
swizzle_y = I915_BIT_6_SWIZZLE_9; |
} else { |
swizzle_x = I915_BIT_6_SWIZZLE_NONE; |
swizzle_y = I915_BIT_6_SWIZZLE_NONE; |
} |
} else if (IS_GEN5(dev)) { |
/* On Ironlake whatever DRAM config, GPU always do |
* same swizzling setup. |
125,10 → 142,10 |
*/ |
swizzle_x = I915_BIT_6_SWIZZLE_NONE; |
swizzle_y = I915_BIT_6_SWIZZLE_NONE; |
} else if (IS_MOBILE(dev)) { |
} else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { |
uint32_t dcc; |
|
/* On mobile 9xx chipsets, channel interleave by the CPU is |
/* On 9xx chipsets, channel interleave by the CPU is |
* determined by DCC. For single-channel, neither the CPU |
* nor the GPU do swizzling. For dual channel interleaved, |
* the GPU's interleave is bit 9 and 10 for X tiled, and bit |
358,9 → 375,15 |
/* We need to rebind the object if its current allocation |
* no longer meets the alignment restrictions for its new |
* tiling mode. Otherwise we can just leave it alone, but |
* need to ensure that any fence register is cleared. |
* need to ensure that any fence register is updated before |
* the next fenced (either through the GTT or by the BLT unit |
* on older GPUs) access. |
* |
* After updating the tiling parameters, we then flag whether |
* we need to update an associated fence register. Note this |
* has to also include the unfenced register the GPU uses |
* whilst executing a fenced command for an untiled object. |
*/ |
i915_gem_release_mmap(obj); |
|
obj->map_and_fenceable = |
obj->gtt_space == NULL || |
378,9 → 401,15 |
} |
|
if (ret == 0) { |
obj->tiling_changed = true; |
obj->fence_dirty = |
obj->fenced_gpu_access || |
obj->fence_reg != I915_FENCE_REG_NONE; |
|
obj->tiling_mode = args->tiling_mode; |
obj->stride = args->stride; |
|
/* Force the fence to be reacquired for GTT access */ |
i915_gem_release_mmap(obj); |
} |
} |
/* we have to maintain this existing ABI... */ |
462,6 → 491,7 |
void |
i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) |
{ |
struct scatterlist *sg; |
int page_count = obj->base.size >> PAGE_SHIFT; |
int i; |
|
468,12 → 498,13 |
if (obj->bit_17 == NULL) |
return; |
|
for (i = 0; i < page_count; i++) { |
char new_bit_17 = page_to_phys(obj->pages[i]) >> 17; |
for_each_sg(obj->pages->sgl, sg, page_count, i) { |
struct page *page = sg_page(sg); |
char new_bit_17 = page_to_phys(page) >> 17; |
if ((new_bit_17 & 0x1) != |
(test_bit(i, obj->bit_17) != 0)) { |
i915_gem_swizzle_page(obj->pages[i]); |
set_page_dirty(obj->pages[i]); |
i915_gem_swizzle_page(page); |
set_page_dirty(page); |
} |
} |
} |
481,6 → 512,7 |
void |
i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) |
{ |
struct scatterlist *sg; |
int page_count = obj->base.size >> PAGE_SHIFT; |
int i; |
|
494,8 → 526,9 |
} |
} |
|
for (i = 0; i < page_count; i++) { |
if (page_to_phys(obj->pages[i]) & (1 << 17)) |
for_each_sg(obj->pages->sgl, sg, page_count, i) { |
struct page *page = sg_page(sg); |
if (page_to_phys(page) & (1 << 17)) |
__set_bit(i, obj->bit_17); |
else |
__clear_bit(i, obj->bit_17); |