diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-30 13:00:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-30 13:00:37 -0500 |
commit | 4a490b78cb7e0e5efa44425df72a9fedc1c36366 (patch) | |
tree | 8a867e39c4e555e4ba10772748b0bde8fe789e20 | |
parent | 8d91a42e54eebc43f4d8f6064751ccba73528275 (diff) | |
parent | d5757dbe79870d825d0dec30074d48683e1d7e9a (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull DRM update from Dave Airlie:
"This is a bit larger due to me not bothering to do anything since
before Xmas, and other people working too hard after I had clearly
given up.
It's got the 3 main x86 driver fixes pulls, and a bunch of tegra
fixes, doesn't fix the Ironlake bug yet, but that does seem to be
getting closer.
- radeon: gpu reset fixes and userspace packet support
- i915: watermark fixes, workarounds, i830/845 fix,
- nouveau: nvd9/kepler microcode fixes, accel is now enabled and
working, gk106 support
- tegra: misc fixes."
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (34 commits)
Revert "drm: tegra: protect DC register access with mutex"
drm: tegra: program only one window during modeset
drm: tegra: clean out old gem prototypes
drm: tegra: remove redundant tegra2_tmds_config entry
drm: tegra: protect DC register access with mutex
drm: tegra: don't leave clients host1x member uninitialized
drm: tegra: fix front_porch <-> back_porch mixup
drm/nve0/graph: fix fuc, and enable acceleration on all known chipsets
drm/nvc0/graph: fix fuc, and enable acceleration on GF119
drm/nouveau/bios: cache ramcfg strap on later chipsets
drm/nouveau/mxm: silence output if no bios data
drm/nouveau/bios: parse/display extra version component
drm/nouveau/bios: implement opcode 0xa9
drm/nouveau/bios: update gpio parsing apis to match current design
drm/nouveau: initial support for GK106
drm/radeon: add WAIT_UNTIL to evergreen VM safe reg list
drm/i915: disable shrinker lock stealing for create_mmap_offset
drm/i915: optionally disable shrinker lock stealing
drm/i915: fix flags in dma buf exporting
drm/radeon: add support for MEM_WRITE packet
...
46 files changed, 880 insertions, 397 deletions
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 0761a03cdbb2..2bf9670ba29b 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -184,19 +184,27 @@ EXPORT_SYMBOL(drm_mm_get_block_generic); | |||
184 | * -ENOSPC if no suitable free area is available. The preallocated memory node | 184 | * -ENOSPC if no suitable free area is available. The preallocated memory node |
185 | * must be cleared. | 185 | * must be cleared. |
186 | */ | 186 | */ |
187 | int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, | 187 | int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, |
188 | unsigned long size, unsigned alignment) | 188 | unsigned long size, unsigned alignment, |
189 | unsigned long color) | ||
189 | { | 190 | { |
190 | struct drm_mm_node *hole_node; | 191 | struct drm_mm_node *hole_node; |
191 | 192 | ||
192 | hole_node = drm_mm_search_free(mm, size, alignment, false); | 193 | hole_node = drm_mm_search_free_generic(mm, size, alignment, |
194 | color, 0); | ||
193 | if (!hole_node) | 195 | if (!hole_node) |
194 | return -ENOSPC; | 196 | return -ENOSPC; |
195 | 197 | ||
196 | drm_mm_insert_helper(hole_node, node, size, alignment, 0); | 198 | drm_mm_insert_helper(hole_node, node, size, alignment, color); |
197 | |||
198 | return 0; | 199 | return 0; |
199 | } | 200 | } |
201 | EXPORT_SYMBOL(drm_mm_insert_node_generic); | ||
202 | |||
203 | int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, | ||
204 | unsigned long size, unsigned alignment) | ||
205 | { | ||
206 | return drm_mm_insert_node_generic(mm, node, size, alignment, 0); | ||
207 | } | ||
200 | EXPORT_SYMBOL(drm_mm_insert_node); | 208 | EXPORT_SYMBOL(drm_mm_insert_node); |
201 | 209 | ||
202 | static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, | 210 | static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, |
@@ -275,22 +283,31 @@ EXPORT_SYMBOL(drm_mm_get_block_range_generic); | |||
275 | * -ENOSPC if no suitable free area is available. This is for range | 283 | * -ENOSPC if no suitable free area is available. This is for range |
276 | * restricted allocations. The preallocated memory node must be cleared. | 284 | * restricted allocations. The preallocated memory node must be cleared. |
277 | */ | 285 | */ |
278 | int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, | 286 | int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node, |
279 | unsigned long size, unsigned alignment, | 287 | unsigned long size, unsigned alignment, unsigned long color, |
280 | unsigned long start, unsigned long end) | 288 | unsigned long start, unsigned long end) |
281 | { | 289 | { |
282 | struct drm_mm_node *hole_node; | 290 | struct drm_mm_node *hole_node; |
283 | 291 | ||
284 | hole_node = drm_mm_search_free_in_range(mm, size, alignment, | 292 | hole_node = drm_mm_search_free_in_range_generic(mm, |
285 | start, end, false); | 293 | size, alignment, color, |
294 | start, end, 0); | ||
286 | if (!hole_node) | 295 | if (!hole_node) |
287 | return -ENOSPC; | 296 | return -ENOSPC; |
288 | 297 | ||
289 | drm_mm_insert_helper_range(hole_node, node, size, alignment, 0, | 298 | drm_mm_insert_helper_range(hole_node, node, |
299 | size, alignment, color, | ||
290 | start, end); | 300 | start, end); |
291 | |||
292 | return 0; | 301 | return 0; |
293 | } | 302 | } |
303 | EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic); | ||
304 | |||
305 | int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, | ||
306 | unsigned long size, unsigned alignment, | ||
307 | unsigned long start, unsigned long end) | ||
308 | { | ||
309 | return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, 0, start, end); | ||
310 | } | ||
294 | EXPORT_SYMBOL(drm_mm_insert_node_in_range); | 311 | EXPORT_SYMBOL(drm_mm_insert_node_in_range); |
295 | 312 | ||
296 | /** | 313 | /** |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8f63cd5de4b4..99daa896105d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -989,6 +989,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
989 | case I915_PARAM_HAS_SECURE_BATCHES: | 989 | case I915_PARAM_HAS_SECURE_BATCHES: |
990 | value = capable(CAP_SYS_ADMIN); | 990 | value = capable(CAP_SYS_ADMIN); |
991 | break; | 991 | break; |
992 | case I915_PARAM_HAS_PINNED_BATCHES: | ||
993 | value = 1; | ||
994 | break; | ||
992 | default: | 995 | default: |
993 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 996 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
994 | param->param); | 997 | param->param); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 557843dd4b2e..ed3059575576 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -780,6 +780,7 @@ typedef struct drm_i915_private { | |||
780 | struct i915_hw_ppgtt *aliasing_ppgtt; | 780 | struct i915_hw_ppgtt *aliasing_ppgtt; |
781 | 781 | ||
782 | struct shrinker inactive_shrinker; | 782 | struct shrinker inactive_shrinker; |
783 | bool shrinker_no_lock_stealing; | ||
783 | 784 | ||
784 | /** | 785 | /** |
785 | * List of objects currently involved in rendering. | 786 | * List of objects currently involved in rendering. |
@@ -1100,6 +1101,7 @@ struct drm_i915_gem_object { | |||
1100 | */ | 1101 | */ |
1101 | atomic_t pending_flip; | 1102 | atomic_t pending_flip; |
1102 | }; | 1103 | }; |
1104 | #define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base) | ||
1103 | 1105 | ||
1104 | #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) | 1106 | #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) |
1105 | 1107 | ||
@@ -1166,6 +1168,9 @@ struct drm_i915_file_private { | |||
1166 | #define IS_IVB_GT1(dev) ((dev)->pci_device == 0x0156 || \ | 1168 | #define IS_IVB_GT1(dev) ((dev)->pci_device == 0x0156 || \ |
1167 | (dev)->pci_device == 0x0152 || \ | 1169 | (dev)->pci_device == 0x0152 || \ |
1168 | (dev)->pci_device == 0x015a) | 1170 | (dev)->pci_device == 0x015a) |
1171 | #define IS_SNB_GT1(dev) ((dev)->pci_device == 0x0102 || \ | ||
1172 | (dev)->pci_device == 0x0106 || \ | ||
1173 | (dev)->pci_device == 0x010A) | ||
1169 | #define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview) | 1174 | #define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview) |
1170 | #define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell) | 1175 | #define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell) |
1171 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | 1176 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) |
@@ -1196,6 +1201,9 @@ struct drm_i915_file_private { | |||
1196 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) | 1201 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) |
1197 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) | 1202 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) |
1198 | 1203 | ||
1204 | /* Early gen2 have a totally busted CS tlb and require pinned batches. */ | ||
1205 | #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) | ||
1206 | |||
1199 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | 1207 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte |
1200 | * rows, which changed the alignment requirements and fence programming. | 1208 | * rows, which changed the alignment requirements and fence programming. |
1201 | */ | 1209 | */ |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 742206e45103..da3c82e301b1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1517,9 +1517,11 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) | |||
1517 | if (obj->base.map_list.map) | 1517 | if (obj->base.map_list.map) |
1518 | return 0; | 1518 | return 0; |
1519 | 1519 | ||
1520 | dev_priv->mm.shrinker_no_lock_stealing = true; | ||
1521 | |||
1520 | ret = drm_gem_create_mmap_offset(&obj->base); | 1522 | ret = drm_gem_create_mmap_offset(&obj->base); |
1521 | if (ret != -ENOSPC) | 1523 | if (ret != -ENOSPC) |
1522 | return ret; | 1524 | goto out; |
1523 | 1525 | ||
1524 | /* Badly fragmented mmap space? The only way we can recover | 1526 | /* Badly fragmented mmap space? The only way we can recover |
1525 | * space is by destroying unwanted objects. We can't randomly release | 1527 | * space is by destroying unwanted objects. We can't randomly release |
@@ -1531,10 +1533,14 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) | |||
1531 | i915_gem_purge(dev_priv, obj->base.size >> PAGE_SHIFT); | 1533 | i915_gem_purge(dev_priv, obj->base.size >> PAGE_SHIFT); |
1532 | ret = drm_gem_create_mmap_offset(&obj->base); | 1534 | ret = drm_gem_create_mmap_offset(&obj->base); |
1533 | if (ret != -ENOSPC) | 1535 | if (ret != -ENOSPC) |
1534 | return ret; | 1536 | goto out; |
1535 | 1537 | ||
1536 | i915_gem_shrink_all(dev_priv); | 1538 | i915_gem_shrink_all(dev_priv); |
1537 | return drm_gem_create_mmap_offset(&obj->base); | 1539 | ret = drm_gem_create_mmap_offset(&obj->base); |
1540 | out: | ||
1541 | dev_priv->mm.shrinker_no_lock_stealing = false; | ||
1542 | |||
1543 | return ret; | ||
1538 | } | 1544 | } |
1539 | 1545 | ||
1540 | static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) | 1546 | static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) |
@@ -2890,7 +2896,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2890 | { | 2896 | { |
2891 | struct drm_device *dev = obj->base.dev; | 2897 | struct drm_device *dev = obj->base.dev; |
2892 | drm_i915_private_t *dev_priv = dev->dev_private; | 2898 | drm_i915_private_t *dev_priv = dev->dev_private; |
2893 | struct drm_mm_node *free_space; | 2899 | struct drm_mm_node *node; |
2894 | u32 size, fence_size, fence_alignment, unfenced_alignment; | 2900 | u32 size, fence_size, fence_alignment, unfenced_alignment; |
2895 | bool mappable, fenceable; | 2901 | bool mappable, fenceable; |
2896 | int ret; | 2902 | int ret; |
@@ -2936,66 +2942,54 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2936 | 2942 | ||
2937 | i915_gem_object_pin_pages(obj); | 2943 | i915_gem_object_pin_pages(obj); |
2938 | 2944 | ||
2945 | node = kzalloc(sizeof(*node), GFP_KERNEL); | ||
2946 | if (node == NULL) { | ||
2947 | i915_gem_object_unpin_pages(obj); | ||
2948 | return -ENOMEM; | ||
2949 | } | ||
2950 | |||
2939 | search_free: | 2951 | search_free: |
2940 | if (map_and_fenceable) | 2952 | if (map_and_fenceable) |
2941 | free_space = drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space, | 2953 | ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node, |
2942 | size, alignment, obj->cache_level, | 2954 | size, alignment, obj->cache_level, |
2943 | 0, dev_priv->mm.gtt_mappable_end, | 2955 | 0, dev_priv->mm.gtt_mappable_end); |
2944 | false); | ||
2945 | else | 2956 | else |
2946 | free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space, | 2957 | ret = drm_mm_insert_node_generic(&dev_priv->mm.gtt_space, node, |
2947 | size, alignment, obj->cache_level, | 2958 | size, alignment, obj->cache_level); |
2948 | false); | 2959 | if (ret) { |
2949 | |||
2950 | if (free_space != NULL) { | ||
2951 | if (map_and_fenceable) | ||
2952 | free_space = | ||
2953 | drm_mm_get_block_range_generic(free_space, | ||
2954 | size, alignment, obj->cache_level, | ||
2955 | 0, dev_priv->mm.gtt_mappable_end, | ||
2956 | false); | ||
2957 | else | ||
2958 | free_space = | ||
2959 | drm_mm_get_block_generic(free_space, | ||
2960 | size, alignment, obj->cache_level, | ||
2961 | false); | ||
2962 | } | ||
2963 | if (free_space == NULL) { | ||
2964 | ret = i915_gem_evict_something(dev, size, alignment, | 2960 | ret = i915_gem_evict_something(dev, size, alignment, |
2965 | obj->cache_level, | 2961 | obj->cache_level, |
2966 | map_and_fenceable, | 2962 | map_and_fenceable, |
2967 | nonblocking); | 2963 | nonblocking); |
2968 | if (ret) { | 2964 | if (ret == 0) |
2969 | i915_gem_object_unpin_pages(obj); | 2965 | goto search_free; |
2970 | return ret; | ||
2971 | } | ||
2972 | 2966 | ||
2973 | goto search_free; | 2967 | i915_gem_object_unpin_pages(obj); |
2968 | kfree(node); | ||
2969 | return ret; | ||
2974 | } | 2970 | } |
2975 | if (WARN_ON(!i915_gem_valid_gtt_space(dev, | 2971 | if (WARN_ON(!i915_gem_valid_gtt_space(dev, node, obj->cache_level))) { |
2976 | free_space, | ||
2977 | obj->cache_level))) { | ||
2978 | i915_gem_object_unpin_pages(obj); | 2972 | i915_gem_object_unpin_pages(obj); |
2979 | drm_mm_put_block(free_space); | 2973 | drm_mm_put_block(node); |
2980 | return -EINVAL; | 2974 | return -EINVAL; |
2981 | } | 2975 | } |
2982 | 2976 | ||
2983 | ret = i915_gem_gtt_prepare_object(obj); | 2977 | ret = i915_gem_gtt_prepare_object(obj); |
2984 | if (ret) { | 2978 | if (ret) { |
2985 | i915_gem_object_unpin_pages(obj); | 2979 | i915_gem_object_unpin_pages(obj); |
2986 | drm_mm_put_block(free_space); | 2980 | drm_mm_put_block(node); |
2987 | return ret; | 2981 | return ret; |
2988 | } | 2982 | } |
2989 | 2983 | ||
2990 | list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list); | 2984 | list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list); |
2991 | list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); | 2985 | list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); |
2992 | 2986 | ||
2993 | obj->gtt_space = free_space; | 2987 | obj->gtt_space = node; |
2994 | obj->gtt_offset = free_space->start; | 2988 | obj->gtt_offset = node->start; |
2995 | 2989 | ||
2996 | fenceable = | 2990 | fenceable = |
2997 | free_space->size == fence_size && | 2991 | node->size == fence_size && |
2998 | (free_space->start & (fence_alignment - 1)) == 0; | 2992 | (node->start & (fence_alignment - 1)) == 0; |
2999 | 2993 | ||
3000 | mappable = | 2994 | mappable = |
3001 | obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; | 2995 | obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; |
@@ -4392,6 +4386,9 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) | |||
4392 | if (!mutex_is_locked_by(&dev->struct_mutex, current)) | 4386 | if (!mutex_is_locked_by(&dev->struct_mutex, current)) |
4393 | return 0; | 4387 | return 0; |
4394 | 4388 | ||
4389 | if (dev_priv->mm.shrinker_no_lock_stealing) | ||
4390 | return 0; | ||
4391 | |||
4395 | unlock = false; | 4392 | unlock = false; |
4396 | } | 4393 | } |
4397 | 4394 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 773ef77b6c22..7be4241e8242 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c | |||
@@ -226,7 +226,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev, | |||
226 | { | 226 | { |
227 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); | 227 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); |
228 | 228 | ||
229 | return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, 0600); | 229 | return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, flags); |
230 | } | 230 | } |
231 | 231 | ||
232 | static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) | 232 | static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index ee8f97f0539e..d6a994a07393 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -808,6 +808,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
808 | 808 | ||
809 | flags |= I915_DISPATCH_SECURE; | 809 | flags |= I915_DISPATCH_SECURE; |
810 | } | 810 | } |
811 | if (args->flags & I915_EXEC_IS_PINNED) | ||
812 | flags |= I915_DISPATCH_PINNED; | ||
811 | 813 | ||
812 | switch (args->flags & I915_EXEC_RING_MASK) { | 814 | switch (args->flags & I915_EXEC_RING_MASK) { |
813 | case I915_EXEC_DEFAULT: | 815 | case I915_EXEC_DEFAULT: |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a4dc97f8b9f0..2220dec3e5d9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1087,6 +1087,18 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, | |||
1087 | if (!ring->get_seqno) | 1087 | if (!ring->get_seqno) |
1088 | return NULL; | 1088 | return NULL; |
1089 | 1089 | ||
1090 | if (HAS_BROKEN_CS_TLB(dev_priv->dev)) { | ||
1091 | u32 acthd = I915_READ(ACTHD); | ||
1092 | |||
1093 | if (WARN_ON(ring->id != RCS)) | ||
1094 | return NULL; | ||
1095 | |||
1096 | obj = ring->private; | ||
1097 | if (acthd >= obj->gtt_offset && | ||
1098 | acthd < obj->gtt_offset + obj->base.size) | ||
1099 | return i915_error_object_create(dev_priv, obj); | ||
1100 | } | ||
1101 | |||
1090 | seqno = ring->get_seqno(ring, false); | 1102 | seqno = ring->get_seqno(ring, false); |
1091 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { | 1103 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { |
1092 | if (obj->ring != ring) | 1104 | if (obj->ring != ring) |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3f75cfaf1c3f..186ee5c85b51 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -517,6 +517,7 @@ | |||
517 | * the enables for writing to the corresponding low bit. | 517 | * the enables for writing to the corresponding low bit. |
518 | */ | 518 | */ |
519 | #define _3D_CHICKEN 0x02084 | 519 | #define _3D_CHICKEN 0x02084 |
520 | #define _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB (1 << 10) | ||
520 | #define _3D_CHICKEN2 0x0208c | 521 | #define _3D_CHICKEN2 0x0208c |
521 | /* Disables pipelining of read flushes past the SF-WIZ interface. | 522 | /* Disables pipelining of read flushes past the SF-WIZ interface. |
522 | * Required on all Ironlake steppings according to the B-Spec, but the | 523 | * Required on all Ironlake steppings according to the B-Spec, but the |
@@ -532,7 +533,8 @@ | |||
532 | # define MI_FLUSH_ENABLE (1 << 12) | 533 | # define MI_FLUSH_ENABLE (1 << 12) |
533 | 534 | ||
534 | #define GEN6_GT_MODE 0x20d0 | 535 | #define GEN6_GT_MODE 0x20d0 |
535 | #define GEN6_GT_MODE_HI (1 << 9) | 536 | #define GEN6_GT_MODE_HI (1 << 9) |
537 | #define GEN6_TD_FOUR_ROW_DISPATCH_DISABLE (1 << 5) | ||
536 | 538 | ||
537 | #define GFX_MODE 0x02520 | 539 | #define GFX_MODE 0x02520 |
538 | #define GFX_MODE_GEN7 0x0229c | 540 | #define GFX_MODE_GEN7 0x0229c |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5d127e068950..a9fb046b94a1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -8144,10 +8144,6 @@ intel_modeset_stage_output_state(struct drm_device *dev, | |||
8144 | DRM_DEBUG_KMS("encoder changed, full mode switch\n"); | 8144 | DRM_DEBUG_KMS("encoder changed, full mode switch\n"); |
8145 | config->mode_changed = true; | 8145 | config->mode_changed = true; |
8146 | } | 8146 | } |
8147 | |||
8148 | /* Disable all disconnected encoders. */ | ||
8149 | if (connector->base.status == connector_status_disconnected) | ||
8150 | connector->new_encoder = NULL; | ||
8151 | } | 8147 | } |
8152 | /* connector->new_encoder is now updated for all connectors. */ | 8148 | /* connector->new_encoder is now updated for all connectors. */ |
8153 | 8149 | ||
@@ -9167,6 +9163,23 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
9167 | * the crtc fixup. */ | 9163 | * the crtc fixup. */ |
9168 | } | 9164 | } |
9169 | 9165 | ||
9166 | static void i915_redisable_vga(struct drm_device *dev) | ||
9167 | { | ||
9168 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9169 | u32 vga_reg; | ||
9170 | |||
9171 | if (HAS_PCH_SPLIT(dev)) | ||
9172 | vga_reg = CPU_VGACNTRL; | ||
9173 | else | ||
9174 | vga_reg = VGACNTRL; | ||
9175 | |||
9176 | if (I915_READ(vga_reg) != VGA_DISP_DISABLE) { | ||
9177 | DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); | ||
9178 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
9179 | POSTING_READ(vga_reg); | ||
9180 | } | ||
9181 | } | ||
9182 | |||
9170 | /* Scan out the current hw modeset state, sanitizes it and maps it into the drm | 9183 | /* Scan out the current hw modeset state, sanitizes it and maps it into the drm |
9171 | * and i915 state tracking structures. */ | 9184 | * and i915 state tracking structures. */ |
9172 | void intel_modeset_setup_hw_state(struct drm_device *dev, | 9185 | void intel_modeset_setup_hw_state(struct drm_device *dev, |
@@ -9275,6 +9288,8 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
9275 | intel_set_mode(&crtc->base, &crtc->base.mode, | 9288 | intel_set_mode(&crtc->base, &crtc->base.mode, |
9276 | crtc->base.x, crtc->base.y, crtc->base.fb); | 9289 | crtc->base.x, crtc->base.y, crtc->base.fb); |
9277 | } | 9290 | } |
9291 | |||
9292 | i915_redisable_vga(dev); | ||
9278 | } else { | 9293 | } else { |
9279 | intel_modeset_update_staged_output_state(dev); | 9294 | intel_modeset_update_staged_output_state(dev); |
9280 | } | 9295 | } |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 496caa73eb70..e6f54ffab3ba 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -405,7 +405,7 @@ void intel_update_fbc(struct drm_device *dev) | |||
405 | * - going to an unsupported config (interlace, pixel multiply, etc.) | 405 | * - going to an unsupported config (interlace, pixel multiply, etc.) |
406 | */ | 406 | */ |
407 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { | 407 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { |
408 | if (tmp_crtc->enabled && | 408 | if (to_intel_crtc(tmp_crtc)->active && |
409 | !to_intel_crtc(tmp_crtc)->primary_disabled && | 409 | !to_intel_crtc(tmp_crtc)->primary_disabled && |
410 | tmp_crtc->fb) { | 410 | tmp_crtc->fb) { |
411 | if (crtc) { | 411 | if (crtc) { |
@@ -992,7 +992,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) | |||
992 | struct drm_crtc *crtc, *enabled = NULL; | 992 | struct drm_crtc *crtc, *enabled = NULL; |
993 | 993 | ||
994 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 994 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
995 | if (crtc->enabled && crtc->fb) { | 995 | if (to_intel_crtc(crtc)->active && crtc->fb) { |
996 | if (enabled) | 996 | if (enabled) |
997 | return NULL; | 997 | return NULL; |
998 | enabled = crtc; | 998 | enabled = crtc; |
@@ -1086,7 +1086,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
1086 | int entries, tlb_miss; | 1086 | int entries, tlb_miss; |
1087 | 1087 | ||
1088 | crtc = intel_get_crtc_for_plane(dev, plane); | 1088 | crtc = intel_get_crtc_for_plane(dev, plane); |
1089 | if (crtc->fb == NULL || !crtc->enabled) { | 1089 | if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { |
1090 | *cursor_wm = cursor->guard_size; | 1090 | *cursor_wm = cursor->guard_size; |
1091 | *plane_wm = display->guard_size; | 1091 | *plane_wm = display->guard_size; |
1092 | return false; | 1092 | return false; |
@@ -1215,7 +1215,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, | |||
1215 | int entries; | 1215 | int entries; |
1216 | 1216 | ||
1217 | crtc = intel_get_crtc_for_plane(dev, plane); | 1217 | crtc = intel_get_crtc_for_plane(dev, plane); |
1218 | if (crtc->fb == NULL || !crtc->enabled) | 1218 | if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) |
1219 | return false; | 1219 | return false; |
1220 | 1220 | ||
1221 | clock = crtc->mode.clock; /* VESA DOT Clock */ | 1221 | clock = crtc->mode.clock; /* VESA DOT Clock */ |
@@ -1286,6 +1286,7 @@ static void valleyview_update_wm(struct drm_device *dev) | |||
1286 | struct drm_i915_private *dev_priv = dev->dev_private; | 1286 | struct drm_i915_private *dev_priv = dev->dev_private; |
1287 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | 1287 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
1288 | int plane_sr, cursor_sr; | 1288 | int plane_sr, cursor_sr; |
1289 | int ignore_plane_sr, ignore_cursor_sr; | ||
1289 | unsigned int enabled = 0; | 1290 | unsigned int enabled = 0; |
1290 | 1291 | ||
1291 | vlv_update_drain_latency(dev); | 1292 | vlv_update_drain_latency(dev); |
@@ -1302,17 +1303,23 @@ static void valleyview_update_wm(struct drm_device *dev) | |||
1302 | &planeb_wm, &cursorb_wm)) | 1303 | &planeb_wm, &cursorb_wm)) |
1303 | enabled |= 2; | 1304 | enabled |= 2; |
1304 | 1305 | ||
1305 | plane_sr = cursor_sr = 0; | ||
1306 | if (single_plane_enabled(enabled) && | 1306 | if (single_plane_enabled(enabled) && |
1307 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1307 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
1308 | sr_latency_ns, | 1308 | sr_latency_ns, |
1309 | &valleyview_wm_info, | 1309 | &valleyview_wm_info, |
1310 | &valleyview_cursor_wm_info, | 1310 | &valleyview_cursor_wm_info, |
1311 | &plane_sr, &cursor_sr)) | 1311 | &plane_sr, &ignore_cursor_sr) && |
1312 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
1313 | 2*sr_latency_ns, | ||
1314 | &valleyview_wm_info, | ||
1315 | &valleyview_cursor_wm_info, | ||
1316 | &ignore_plane_sr, &cursor_sr)) { | ||
1312 | I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN); | 1317 | I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN); |
1313 | else | 1318 | } else { |
1314 | I915_WRITE(FW_BLC_SELF_VLV, | 1319 | I915_WRITE(FW_BLC_SELF_VLV, |
1315 | I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN); | 1320 | I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN); |
1321 | plane_sr = cursor_sr = 0; | ||
1322 | } | ||
1316 | 1323 | ||
1317 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | 1324 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", |
1318 | planea_wm, cursora_wm, | 1325 | planea_wm, cursora_wm, |
@@ -1352,17 +1359,18 @@ static void g4x_update_wm(struct drm_device *dev) | |||
1352 | &planeb_wm, &cursorb_wm)) | 1359 | &planeb_wm, &cursorb_wm)) |
1353 | enabled |= 2; | 1360 | enabled |= 2; |
1354 | 1361 | ||
1355 | plane_sr = cursor_sr = 0; | ||
1356 | if (single_plane_enabled(enabled) && | 1362 | if (single_plane_enabled(enabled) && |
1357 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1363 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
1358 | sr_latency_ns, | 1364 | sr_latency_ns, |
1359 | &g4x_wm_info, | 1365 | &g4x_wm_info, |
1360 | &g4x_cursor_wm_info, | 1366 | &g4x_cursor_wm_info, |
1361 | &plane_sr, &cursor_sr)) | 1367 | &plane_sr, &cursor_sr)) { |
1362 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | 1368 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
1363 | else | 1369 | } else { |
1364 | I915_WRITE(FW_BLC_SELF, | 1370 | I915_WRITE(FW_BLC_SELF, |
1365 | I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); | 1371 | I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); |
1372 | plane_sr = cursor_sr = 0; | ||
1373 | } | ||
1366 | 1374 | ||
1367 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | 1375 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", |
1368 | planea_wm, cursora_wm, | 1376 | planea_wm, cursora_wm, |
@@ -1468,7 +1476,7 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
1468 | 1476 | ||
1469 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); | 1477 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
1470 | crtc = intel_get_crtc_for_plane(dev, 0); | 1478 | crtc = intel_get_crtc_for_plane(dev, 0); |
1471 | if (crtc->enabled && crtc->fb) { | 1479 | if (to_intel_crtc(crtc)->active && crtc->fb) { |
1472 | int cpp = crtc->fb->bits_per_pixel / 8; | 1480 | int cpp = crtc->fb->bits_per_pixel / 8; |
1473 | if (IS_GEN2(dev)) | 1481 | if (IS_GEN2(dev)) |
1474 | cpp = 4; | 1482 | cpp = 4; |
@@ -1482,7 +1490,7 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
1482 | 1490 | ||
1483 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); | 1491 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); |
1484 | crtc = intel_get_crtc_for_plane(dev, 1); | 1492 | crtc = intel_get_crtc_for_plane(dev, 1); |
1485 | if (crtc->enabled && crtc->fb) { | 1493 | if (to_intel_crtc(crtc)->active && crtc->fb) { |
1486 | int cpp = crtc->fb->bits_per_pixel / 8; | 1494 | int cpp = crtc->fb->bits_per_pixel / 8; |
1487 | if (IS_GEN2(dev)) | 1495 | if (IS_GEN2(dev)) |
1488 | cpp = 4; | 1496 | cpp = 4; |
@@ -1811,8 +1819,110 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
1811 | enabled |= 2; | 1819 | enabled |= 2; |
1812 | } | 1820 | } |
1813 | 1821 | ||
1814 | if ((dev_priv->num_pipe == 3) && | 1822 | /* |
1815 | g4x_compute_wm0(dev, 2, | 1823 | * Calculate and update the self-refresh watermark only when one |
1824 | * display plane is used. | ||
1825 | * | ||
1826 | * SNB support 3 levels of watermark. | ||
1827 | * | ||
1828 | * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, | ||
1829 | * and disabled in the descending order | ||
1830 | * | ||
1831 | */ | ||
1832 | I915_WRITE(WM3_LP_ILK, 0); | ||
1833 | I915_WRITE(WM2_LP_ILK, 0); | ||
1834 | I915_WRITE(WM1_LP_ILK, 0); | ||
1835 | |||
1836 | if (!single_plane_enabled(enabled) || | ||
1837 | dev_priv->sprite_scaling_enabled) | ||
1838 | return; | ||
1839 | enabled = ffs(enabled) - 1; | ||
1840 | |||
1841 | /* WM1 */ | ||
1842 | if (!ironlake_compute_srwm(dev, 1, enabled, | ||
1843 | SNB_READ_WM1_LATENCY() * 500, | ||
1844 | &sandybridge_display_srwm_info, | ||
1845 | &sandybridge_cursor_srwm_info, | ||
1846 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1847 | return; | ||
1848 | |||
1849 | I915_WRITE(WM1_LP_ILK, | ||
1850 | WM1_LP_SR_EN | | ||
1851 | (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1852 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1853 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1854 | cursor_wm); | ||
1855 | |||
1856 | /* WM2 */ | ||
1857 | if (!ironlake_compute_srwm(dev, 2, enabled, | ||
1858 | SNB_READ_WM2_LATENCY() * 500, | ||
1859 | &sandybridge_display_srwm_info, | ||
1860 | &sandybridge_cursor_srwm_info, | ||
1861 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1862 | return; | ||
1863 | |||
1864 | I915_WRITE(WM2_LP_ILK, | ||
1865 | WM2_LP_EN | | ||
1866 | (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1867 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1868 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1869 | cursor_wm); | ||
1870 | |||
1871 | /* WM3 */ | ||
1872 | if (!ironlake_compute_srwm(dev, 3, enabled, | ||
1873 | SNB_READ_WM3_LATENCY() * 500, | ||
1874 | &sandybridge_display_srwm_info, | ||
1875 | &sandybridge_cursor_srwm_info, | ||
1876 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1877 | return; | ||
1878 | |||
1879 | I915_WRITE(WM3_LP_ILK, | ||
1880 | WM3_LP_EN | | ||
1881 | (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1882 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1883 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1884 | cursor_wm); | ||
1885 | } | ||
1886 | |||
1887 | static void ivybridge_update_wm(struct drm_device *dev) | ||
1888 | { | ||
1889 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1890 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | ||
1891 | u32 val; | ||
1892 | int fbc_wm, plane_wm, cursor_wm; | ||
1893 | int ignore_fbc_wm, ignore_plane_wm, ignore_cursor_wm; | ||
1894 | unsigned int enabled; | ||
1895 | |||
1896 | enabled = 0; | ||
1897 | if (g4x_compute_wm0(dev, 0, | ||
1898 | &sandybridge_display_wm_info, latency, | ||
1899 | &sandybridge_cursor_wm_info, latency, | ||
1900 | &plane_wm, &cursor_wm)) { | ||
1901 | val = I915_READ(WM0_PIPEA_ILK); | ||
1902 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
1903 | I915_WRITE(WM0_PIPEA_ILK, val | | ||
1904 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
1905 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
1906 | " plane %d, " "cursor: %d\n", | ||
1907 | plane_wm, cursor_wm); | ||
1908 | enabled |= 1; | ||
1909 | } | ||
1910 | |||
1911 | if (g4x_compute_wm0(dev, 1, | ||
1912 | &sandybridge_display_wm_info, latency, | ||
1913 | &sandybridge_cursor_wm_info, latency, | ||
1914 | &plane_wm, &cursor_wm)) { | ||
1915 | val = I915_READ(WM0_PIPEB_ILK); | ||
1916 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
1917 | I915_WRITE(WM0_PIPEB_ILK, val | | ||
1918 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
1919 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
1920 | " plane %d, cursor: %d\n", | ||
1921 | plane_wm, cursor_wm); | ||
1922 | enabled |= 2; | ||
1923 | } | ||
1924 | |||
1925 | if (g4x_compute_wm0(dev, 2, | ||
1816 | &sandybridge_display_wm_info, latency, | 1926 | &sandybridge_display_wm_info, latency, |
1817 | &sandybridge_cursor_wm_info, latency, | 1927 | &sandybridge_cursor_wm_info, latency, |
1818 | &plane_wm, &cursor_wm)) { | 1928 | &plane_wm, &cursor_wm)) { |
@@ -1875,12 +1985,17 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
1875 | (plane_wm << WM1_LP_SR_SHIFT) | | 1985 | (plane_wm << WM1_LP_SR_SHIFT) | |
1876 | cursor_wm); | 1986 | cursor_wm); |
1877 | 1987 | ||
1878 | /* WM3 */ | 1988 | /* WM3, note we have to correct the cursor latency */ |
1879 | if (!ironlake_compute_srwm(dev, 3, enabled, | 1989 | if (!ironlake_compute_srwm(dev, 3, enabled, |
1880 | SNB_READ_WM3_LATENCY() * 500, | 1990 | SNB_READ_WM3_LATENCY() * 500, |
1881 | &sandybridge_display_srwm_info, | 1991 | &sandybridge_display_srwm_info, |
1882 | &sandybridge_cursor_srwm_info, | 1992 | &sandybridge_cursor_srwm_info, |
1883 | &fbc_wm, &plane_wm, &cursor_wm)) | 1993 | &fbc_wm, &plane_wm, &ignore_cursor_wm) || |
1994 | !ironlake_compute_srwm(dev, 3, enabled, | ||
1995 | 2 * SNB_READ_WM3_LATENCY() * 500, | ||
1996 | &sandybridge_display_srwm_info, | ||
1997 | &sandybridge_cursor_srwm_info, | ||
1998 | &ignore_fbc_wm, &ignore_plane_wm, &cursor_wm)) | ||
1884 | return; | 1999 | return; |
1885 | 2000 | ||
1886 | I915_WRITE(WM3_LP_ILK, | 2001 | I915_WRITE(WM3_LP_ILK, |
@@ -1929,7 +2044,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, | |||
1929 | int entries, tlb_miss; | 2044 | int entries, tlb_miss; |
1930 | 2045 | ||
1931 | crtc = intel_get_crtc_for_plane(dev, plane); | 2046 | crtc = intel_get_crtc_for_plane(dev, plane); |
1932 | if (crtc->fb == NULL || !crtc->enabled) { | 2047 | if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { |
1933 | *sprite_wm = display->guard_size; | 2048 | *sprite_wm = display->guard_size; |
1934 | return false; | 2049 | return false; |
1935 | } | 2050 | } |
@@ -3471,6 +3586,15 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
3471 | I915_READ(ILK_DISPLAY_CHICKEN2) | | 3586 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
3472 | ILK_ELPIN_409_SELECT); | 3587 | ILK_ELPIN_409_SELECT); |
3473 | 3588 | ||
3589 | /* WaDisableHiZPlanesWhenMSAAEnabled */ | ||
3590 | I915_WRITE(_3D_CHICKEN, | ||
3591 | _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); | ||
3592 | |||
3593 | /* WaSetupGtModeTdRowDispatch */ | ||
3594 | if (IS_SNB_GT1(dev)) | ||
3595 | I915_WRITE(GEN6_GT_MODE, | ||
3596 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); | ||
3597 | |||
3474 | I915_WRITE(WM3_LP_ILK, 0); | 3598 | I915_WRITE(WM3_LP_ILK, 0); |
3475 | I915_WRITE(WM2_LP_ILK, 0); | 3599 | I915_WRITE(WM2_LP_ILK, 0); |
3476 | I915_WRITE(WM1_LP_ILK, 0); | 3600 | I915_WRITE(WM1_LP_ILK, 0); |
@@ -3999,7 +4123,7 @@ void intel_init_pm(struct drm_device *dev) | |||
3999 | } else if (IS_IVYBRIDGE(dev)) { | 4123 | } else if (IS_IVYBRIDGE(dev)) { |
4000 | /* FIXME: detect B0+ stepping and use auto training */ | 4124 | /* FIXME: detect B0+ stepping and use auto training */ |
4001 | if (SNB_READ_WM0_LATENCY()) { | 4125 | if (SNB_READ_WM0_LATENCY()) { |
4002 | dev_priv->display.update_wm = sandybridge_update_wm; | 4126 | dev_priv->display.update_wm = ivybridge_update_wm; |
4003 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; | 4127 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; |
4004 | } else { | 4128 | } else { |
4005 | DRM_DEBUG_KMS("Failed to read display plane latency. " | 4129 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2346b920bd86..ae253e04c391 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -547,9 +547,14 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
547 | 547 | ||
548 | static void render_ring_cleanup(struct intel_ring_buffer *ring) | 548 | static void render_ring_cleanup(struct intel_ring_buffer *ring) |
549 | { | 549 | { |
550 | struct drm_device *dev = ring->dev; | ||
551 | |||
550 | if (!ring->private) | 552 | if (!ring->private) |
551 | return; | 553 | return; |
552 | 554 | ||
555 | if (HAS_BROKEN_CS_TLB(dev)) | ||
556 | drm_gem_object_unreference(to_gem_object(ring->private)); | ||
557 | |||
553 | cleanup_pipe_control(ring); | 558 | cleanup_pipe_control(ring); |
554 | } | 559 | } |
555 | 560 | ||
@@ -969,6 +974,8 @@ i965_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
969 | return 0; | 974 | return 0; |
970 | } | 975 | } |
971 | 976 | ||
977 | /* Just userspace ABI convention to limit the wa batch bo to a resonable size */ | ||
978 | #define I830_BATCH_LIMIT (256*1024) | ||
972 | static int | 979 | static int |
973 | i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | 980 | i830_dispatch_execbuffer(struct intel_ring_buffer *ring, |
974 | u32 offset, u32 len, | 981 | u32 offset, u32 len, |
@@ -976,15 +983,47 @@ i830_dispatch_execbuffer(struct intel_ring_buffer *ring, | |||
976 | { | 983 | { |
977 | int ret; | 984 | int ret; |
978 | 985 | ||
979 | ret = intel_ring_begin(ring, 4); | 986 | if (flags & I915_DISPATCH_PINNED) { |
980 | if (ret) | 987 | ret = intel_ring_begin(ring, 4); |
981 | return ret; | 988 | if (ret) |
989 | return ret; | ||
982 | 990 | ||
983 | intel_ring_emit(ring, MI_BATCH_BUFFER); | 991 | intel_ring_emit(ring, MI_BATCH_BUFFER); |
984 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); | 992 | intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
985 | intel_ring_emit(ring, offset + len - 8); | 993 | intel_ring_emit(ring, offset + len - 8); |
986 | intel_ring_emit(ring, 0); | 994 | intel_ring_emit(ring, MI_NOOP); |
987 | intel_ring_advance(ring); | 995 | intel_ring_advance(ring); |
996 | } else { | ||
997 | struct drm_i915_gem_object *obj = ring->private; | ||
998 | u32 cs_offset = obj->gtt_offset; | ||
999 | |||
1000 | if (len > I830_BATCH_LIMIT) | ||
1001 | return -ENOSPC; | ||
1002 | |||
1003 | ret = intel_ring_begin(ring, 9+3); | ||
1004 | if (ret) | ||
1005 | return ret; | ||
1006 | /* Blit the batch (which has now all relocs applied) to the stable batch | ||
1007 | * scratch bo area (so that the CS never stumbles over its tlb | ||
1008 | * invalidation bug) ... */ | ||
1009 | intel_ring_emit(ring, XY_SRC_COPY_BLT_CMD | | ||
1010 | XY_SRC_COPY_BLT_WRITE_ALPHA | | ||
1011 | XY_SRC_COPY_BLT_WRITE_RGB); | ||
1012 | intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_GXCOPY | 4096); | ||
1013 | intel_ring_emit(ring, 0); | ||
1014 | intel_ring_emit(ring, (DIV_ROUND_UP(len, 4096) << 16) | 1024); | ||
1015 | intel_ring_emit(ring, cs_offset); | ||
1016 | intel_ring_emit(ring, 0); | ||
1017 | intel_ring_emit(ring, 4096); | ||
1018 | intel_ring_emit(ring, offset); | ||
1019 | intel_ring_emit(ring, MI_FLUSH); | ||
1020 | |||
1021 | /* ... and execute it. */ | ||
1022 | intel_ring_emit(ring, MI_BATCH_BUFFER); | ||
1023 | intel_ring_emit(ring, cs_offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); | ||
1024 | intel_ring_emit(ring, cs_offset + len - 8); | ||
1025 | intel_ring_advance(ring); | ||
1026 | } | ||
988 | 1027 | ||
989 | return 0; | 1028 | return 0; |
990 | } | 1029 | } |
@@ -1596,6 +1635,27 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1596 | ring->init = init_render_ring; | 1635 | ring->init = init_render_ring; |
1597 | ring->cleanup = render_ring_cleanup; | 1636 | ring->cleanup = render_ring_cleanup; |
1598 | 1637 | ||
1638 | /* Workaround batchbuffer to combat CS tlb bug. */ | ||
1639 | if (HAS_BROKEN_CS_TLB(dev)) { | ||
1640 | struct drm_i915_gem_object *obj; | ||
1641 | int ret; | ||
1642 | |||
1643 | obj = i915_gem_alloc_object(dev, I830_BATCH_LIMIT); | ||
1644 | if (obj == NULL) { | ||
1645 | DRM_ERROR("Failed to allocate batch bo\n"); | ||
1646 | return -ENOMEM; | ||
1647 | } | ||
1648 | |||
1649 | ret = i915_gem_object_pin(obj, 0, true, false); | ||
1650 | if (ret != 0) { | ||
1651 | drm_gem_object_unreference(&obj->base); | ||
1652 | DRM_ERROR("Failed to ping batch bo\n"); | ||
1653 | return ret; | ||
1654 | } | ||
1655 | |||
1656 | ring->private = obj; | ||
1657 | } | ||
1658 | |||
1599 | return intel_init_ring_buffer(dev, ring); | 1659 | return intel_init_ring_buffer(dev, ring); |
1600 | } | 1660 | } |
1601 | 1661 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 526182ed0c6d..6af87cd05725 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -94,6 +94,7 @@ struct intel_ring_buffer { | |||
94 | u32 offset, u32 length, | 94 | u32 offset, u32 length, |
95 | unsigned flags); | 95 | unsigned flags); |
96 | #define I915_DISPATCH_SECURE 0x1 | 96 | #define I915_DISPATCH_SECURE 0x1 |
97 | #define I915_DISPATCH_PINNED 0x2 | ||
97 | void (*cleanup)(struct intel_ring_buffer *ring); | 98 | void (*cleanup)(struct intel_ring_buffer *ring); |
98 | int (*sync_to)(struct intel_ring_buffer *ring, | 99 | int (*sync_to)(struct intel_ring_buffer *ring, |
99 | struct intel_ring_buffer *to, | 100 | struct intel_ring_buffer *to, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc index 7b715fda2763..62ab231cd6b6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc | |||
@@ -57,6 +57,11 @@ chipsets: | |||
57 | .b16 #nve4_gpc_mmio_tail | 57 | .b16 #nve4_gpc_mmio_tail |
58 | .b16 #nve4_tpc_mmio_head | 58 | .b16 #nve4_tpc_mmio_head |
59 | .b16 #nve4_tpc_mmio_tail | 59 | .b16 #nve4_tpc_mmio_tail |
60 | .b8 0xe6 0 0 0 | ||
61 | .b16 #nve4_gpc_mmio_head | ||
62 | .b16 #nve4_gpc_mmio_tail | ||
63 | .b16 #nve4_tpc_mmio_head | ||
64 | .b16 #nve4_tpc_mmio_tail | ||
60 | .b8 0 0 0 0 | 65 | .b8 0 0 0 0 |
61 | 66 | ||
62 | // GPC mmio lists | 67 | // GPC mmio lists |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h index 26c2165bad0f..09ee4702c8b2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h | |||
@@ -34,13 +34,16 @@ uint32_t nve0_grgpc_data[] = { | |||
34 | 0x00000000, | 34 | 0x00000000, |
35 | /* 0x0064: chipsets */ | 35 | /* 0x0064: chipsets */ |
36 | 0x000000e4, | 36 | 0x000000e4, |
37 | 0x01040080, | 37 | 0x0110008c, |
38 | 0x014c0104, | 38 | 0x01580110, |
39 | 0x000000e7, | 39 | 0x000000e7, |
40 | 0x01040080, | 40 | 0x0110008c, |
41 | 0x014c0104, | 41 | 0x01580110, |
42 | 0x000000e6, | ||
43 | 0x0110008c, | ||
44 | 0x01580110, | ||
42 | 0x00000000, | 45 | 0x00000000, |
43 | /* 0x0080: nve4_gpc_mmio_head */ | 46 | /* 0x008c: nve4_gpc_mmio_head */ |
44 | 0x00000380, | 47 | 0x00000380, |
45 | 0x04000400, | 48 | 0x04000400, |
46 | 0x0800040c, | 49 | 0x0800040c, |
@@ -74,8 +77,8 @@ uint32_t nve0_grgpc_data[] = { | |||
74 | 0x14003100, | 77 | 0x14003100, |
75 | 0x000031d0, | 78 | 0x000031d0, |
76 | 0x040031e0, | 79 | 0x040031e0, |
77 | /* 0x0104: nve4_gpc_mmio_tail */ | 80 | /* 0x0110: nve4_gpc_mmio_tail */ |
78 | /* 0x0104: nve4_tpc_mmio_head */ | 81 | /* 0x0110: nve4_tpc_mmio_head */ |
79 | 0x00000048, | 82 | 0x00000048, |
80 | 0x00000064, | 83 | 0x00000064, |
81 | 0x00000088, | 84 | 0x00000088, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc index acfc457654bd..0bcfa4d447e5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc | |||
@@ -754,6 +754,16 @@ ctx_mmio_exec: | |||
754 | // on load it means: "a save preceeded this load" | 754 | // on load it means: "a save preceeded this load" |
755 | // | 755 | // |
756 | ctx_xfer: | 756 | ctx_xfer: |
757 | // according to mwk, some kind of wait for idle | ||
758 | mov $r15 0xc00 | ||
759 | shl b32 $r15 6 | ||
760 | mov $r14 4 | ||
761 | iowr I[$r15 + 0x200] $r14 | ||
762 | ctx_xfer_idle: | ||
763 | iord $r14 I[$r15 + 0x000] | ||
764 | and $r14 0x2000 | ||
765 | bra ne #ctx_xfer_idle | ||
766 | |||
757 | bra not $p1 #ctx_xfer_pre | 767 | bra not $p1 #ctx_xfer_pre |
758 | bra $p2 #ctx_xfer_pre_load | 768 | bra $p2 #ctx_xfer_pre_load |
759 | ctx_xfer_pre: | 769 | ctx_xfer_pre: |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h index 85a8d556f484..bb03d2a1d57b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h | |||
@@ -799,79 +799,80 @@ uint32_t nvc0_grhub_code[] = { | |||
799 | 0x01fa0613, | 799 | 0x01fa0613, |
800 | 0xf803f806, | 800 | 0xf803f806, |
801 | /* 0x0829: ctx_xfer */ | 801 | /* 0x0829: ctx_xfer */ |
802 | 0x0611f400, | 802 | 0x00f7f100, |
803 | /* 0x082f: ctx_xfer_pre */ | 803 | 0x06f4b60c, |
804 | 0xf01102f4, | 804 | 0xd004e7f0, |
805 | 0x21f510f7, | 805 | /* 0x0836: ctx_xfer_idle */ |
806 | 0x21f50698, | 806 | 0xfecf80fe, |
807 | 0x11f40631, | 807 | 0x00e4f100, |
808 | /* 0x083d: ctx_xfer_pre_load */ | 808 | 0xf91bf420, |
809 | 0x02f7f01c, | 809 | 0xf40611f4, |
810 | 0x065721f5, | 810 | /* 0x0846: ctx_xfer_pre */ |
811 | 0x066621f5, | 811 | 0xf7f01102, |
812 | 0x067821f5, | 812 | 0x9821f510, |
813 | 0x21f5f4bd, | 813 | 0x3121f506, |
814 | 0x21f50657, | 814 | 0x1c11f406, |
815 | /* 0x0856: ctx_xfer_exec */ | 815 | /* 0x0854: ctx_xfer_pre_load */ |
816 | 0x019806b8, | 816 | 0xf502f7f0, |
817 | 0x1427f116, | 817 | 0xf5065721, |
818 | 0x0624b604, | 818 | 0xf5066621, |
819 | 0xf10020d0, | 819 | 0xbd067821, |
820 | 0xf0a500e7, | 820 | 0x5721f5f4, |
821 | 0x1fb941e3, | 821 | 0xb821f506, |
822 | 0x8d21f402, | 822 | /* 0x086d: ctx_xfer_exec */ |
823 | 0xf004e0b6, | 823 | 0x16019806, |
824 | 0x2cf001fc, | 824 | 0x041427f1, |
825 | 0x0124b602, | 825 | 0xd00624b6, |
826 | 0xf405f2fd, | 826 | 0xe7f10020, |
827 | 0x17f18d21, | 827 | 0xe3f0a500, |
828 | 0x13f04afc, | 828 | 0x021fb941, |
829 | 0x0c27f002, | 829 | 0xb68d21f4, |
830 | 0xf50012d0, | 830 | 0xfcf004e0, |
831 | 0xf1020721, | 831 | 0x022cf001, |
832 | 0xf047fc27, | 832 | 0xfd0124b6, |
833 | 0x20d00223, | 833 | 0x21f405f2, |
834 | 0x012cf000, | 834 | 0xfc17f18d, |
835 | 0xd00320b6, | 835 | 0x0213f04a, |
836 | 0xacf00012, | 836 | 0xd00c27f0, |
837 | 0x06a5f001, | 837 | 0x21f50012, |
838 | 0x9800b7f0, | 838 | 0x27f10207, |
839 | 0x0d98140c, | 839 | 0x23f047fc, |
840 | 0x00e7f015, | 840 | 0x0020d002, |
841 | 0x015c21f5, | 841 | 0xb6012cf0, |
842 | 0xf508a7f0, | 842 | 0x12d00320, |
843 | 0xf5010321, | 843 | 0x01acf000, |
844 | 0xf4020721, | 844 | 0xf006a5f0, |
845 | 0xa7f02201, | 845 | 0x0c9800b7, |
846 | 0xc921f40c, | 846 | 0x150d9814, |
847 | 0x0a1017f1, | 847 | 0xf500e7f0, |
848 | 0xf00614b6, | 848 | 0xf0015c21, |
849 | 0x12d00527, | 849 | 0x21f508a7, |
850 | /* 0x08dd: ctx_xfer_post_save_wait */ | 850 | 0x21f50103, |
851 | 0x0012cf00, | 851 | 0x01f40207, |
852 | 0xf40522fd, | 852 | 0x0ca7f022, |
853 | 0x02f4fa1b, | 853 | 0xf1c921f4, |
854 | /* 0x08e9: ctx_xfer_post */ | 854 | 0xb60a1017, |
855 | 0x02f7f032, | 855 | 0x27f00614, |
856 | 0x065721f5, | 856 | 0x0012d005, |
857 | 0x21f5f4bd, | 857 | /* 0x08f4: ctx_xfer_post_save_wait */ |
858 | 0x21f50698, | 858 | 0xfd0012cf, |
859 | 0x21f50226, | 859 | 0x1bf40522, |
860 | 0xf4bd0666, | 860 | 0x3202f4fa, |
861 | 0x065721f5, | 861 | /* 0x0900: ctx_xfer_post */ |
862 | 0x981011f4, | 862 | 0xf502f7f0, |
863 | 0x11fd8001, | 863 | 0xbd065721, |
864 | 0x070bf405, | 864 | 0x9821f5f4, |
865 | 0x07df21f5, | 865 | 0x2621f506, |
866 | /* 0x0914: ctx_xfer_no_post_mmio */ | 866 | 0x6621f502, |
867 | 0x064921f5, | 867 | 0xf5f4bd06, |
868 | /* 0x0918: ctx_xfer_done */ | 868 | 0xf4065721, |
869 | 0x000000f8, | 869 | 0x01981011, |
870 | 0x00000000, | 870 | 0x0511fd80, |
871 | 0x00000000, | 871 | 0xf5070bf4, |
872 | 0x00000000, | 872 | /* 0x092b: ctx_xfer_no_post_mmio */ |
873 | 0x00000000, | 873 | 0xf507df21, |
874 | 0x00000000, | 874 | /* 0x092f: ctx_xfer_done */ |
875 | 0xf8064921, | ||
875 | 0x00000000, | 876 | 0x00000000, |
876 | 0x00000000, | 877 | 0x00000000, |
877 | 0x00000000, | 878 | 0x00000000, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc index 138eeaa28665..7fe9d7cf486b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc | |||
@@ -44,6 +44,9 @@ chipsets: | |||
44 | .b8 0xe7 0 0 0 | 44 | .b8 0xe7 0 0 0 |
45 | .b16 #nve4_hub_mmio_head | 45 | .b16 #nve4_hub_mmio_head |
46 | .b16 #nve4_hub_mmio_tail | 46 | .b16 #nve4_hub_mmio_tail |
47 | .b8 0xe6 0 0 0 | ||
48 | .b16 #nve4_hub_mmio_head | ||
49 | .b16 #nve4_hub_mmio_tail | ||
47 | .b8 0 0 0 0 | 50 | .b8 0 0 0 0 |
48 | 51 | ||
49 | nve4_hub_mmio_head: | 52 | nve4_hub_mmio_head: |
@@ -680,6 +683,16 @@ ctx_mmio_exec: | |||
680 | // on load it means: "a save preceeded this load" | 683 | // on load it means: "a save preceeded this load" |
681 | // | 684 | // |
682 | ctx_xfer: | 685 | ctx_xfer: |
686 | // according to mwk, some kind of wait for idle | ||
687 | mov $r15 0xc00 | ||
688 | shl b32 $r15 6 | ||
689 | mov $r14 4 | ||
690 | iowr I[$r15 + 0x200] $r14 | ||
691 | ctx_xfer_idle: | ||
692 | iord $r14 I[$r15 + 0x000] | ||
693 | and $r14 0x2000 | ||
694 | bra ne #ctx_xfer_idle | ||
695 | |||
683 | bra not $p1 #ctx_xfer_pre | 696 | bra not $p1 #ctx_xfer_pre |
684 | bra $p2 #ctx_xfer_pre_load | 697 | bra $p2 #ctx_xfer_pre_load |
685 | ctx_xfer_pre: | 698 | ctx_xfer_pre: |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h index decf0c60ca3b..e3421af68ab9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h | |||
@@ -30,11 +30,13 @@ uint32_t nve0_grhub_data[] = { | |||
30 | 0x00000000, | 30 | 0x00000000, |
31 | /* 0x005c: chipsets */ | 31 | /* 0x005c: chipsets */ |
32 | 0x000000e4, | 32 | 0x000000e4, |
33 | 0x013c0070, | 33 | 0x01440078, |
34 | 0x000000e7, | 34 | 0x000000e7, |
35 | 0x013c0070, | 35 | 0x01440078, |
36 | 0x000000e6, | ||
37 | 0x01440078, | ||
36 | 0x00000000, | 38 | 0x00000000, |
37 | /* 0x0070: nve4_hub_mmio_head */ | 39 | /* 0x0078: nve4_hub_mmio_head */ |
38 | 0x0417e91c, | 40 | 0x0417e91c, |
39 | 0x04400204, | 41 | 0x04400204, |
40 | 0x18404010, | 42 | 0x18404010, |
@@ -86,9 +88,7 @@ uint32_t nve0_grhub_data[] = { | |||
86 | 0x00408840, | 88 | 0x00408840, |
87 | 0x08408900, | 89 | 0x08408900, |
88 | 0x00408980, | 90 | 0x00408980, |
89 | /* 0x013c: nve4_hub_mmio_tail */ | 91 | /* 0x0144: nve4_hub_mmio_tail */ |
90 | 0x00000000, | ||
91 | 0x00000000, | ||
92 | 0x00000000, | 92 | 0x00000000, |
93 | 0x00000000, | 93 | 0x00000000, |
94 | 0x00000000, | 94 | 0x00000000, |
@@ -781,77 +781,78 @@ uint32_t nve0_grhub_code[] = { | |||
781 | 0x0613f002, | 781 | 0x0613f002, |
782 | 0xf80601fa, | 782 | 0xf80601fa, |
783 | /* 0x07fb: ctx_xfer */ | 783 | /* 0x07fb: ctx_xfer */ |
784 | 0xf400f803, | 784 | 0xf100f803, |
785 | 0x02f40611, | 785 | 0xb60c00f7, |
786 | /* 0x0801: ctx_xfer_pre */ | 786 | 0xe7f006f4, |
787 | 0x10f7f00d, | 787 | 0x80fed004, |
788 | 0x067221f5, | 788 | /* 0x0808: ctx_xfer_idle */ |
789 | /* 0x080b: ctx_xfer_pre_load */ | 789 | 0xf100fecf, |
790 | 0xf01c11f4, | 790 | 0xf42000e4, |
791 | 0x21f502f7, | 791 | 0x11f4f91b, |
792 | 0x21f50631, | 792 | 0x0d02f406, |
793 | 0x21f50640, | 793 | /* 0x0818: ctx_xfer_pre */ |
794 | 0xf4bd0652, | 794 | 0xf510f7f0, |
795 | 0x063121f5, | 795 | 0xf4067221, |
796 | 0x069221f5, | 796 | /* 0x0822: ctx_xfer_pre_load */ |
797 | /* 0x0824: ctx_xfer_exec */ | 797 | 0xf7f01c11, |
798 | 0xf1160198, | 798 | 0x3121f502, |
799 | 0xb6041427, | 799 | 0x4021f506, |
800 | 0x20d00624, | 800 | 0x5221f506, |
801 | 0x00e7f100, | 801 | 0xf5f4bd06, |
802 | 0x41e3f0a5, | 802 | 0xf5063121, |
803 | 0xf4021fb9, | 803 | /* 0x083b: ctx_xfer_exec */ |
804 | 0xe0b68d21, | 804 | 0x98069221, |
805 | 0x01fcf004, | 805 | 0x27f11601, |
806 | 0xb6022cf0, | 806 | 0x24b60414, |
807 | 0xf2fd0124, | 807 | 0x0020d006, |
808 | 0x8d21f405, | 808 | 0xa500e7f1, |
809 | 0x4afc17f1, | 809 | 0xb941e3f0, |
810 | 0xf00213f0, | 810 | 0x21f4021f, |
811 | 0x12d00c27, | 811 | 0x04e0b68d, |
812 | 0x0721f500, | 812 | 0xf001fcf0, |
813 | 0xfc27f102, | 813 | 0x24b6022c, |
814 | 0x0223f047, | 814 | 0x05f2fd01, |
815 | 0xf00020d0, | 815 | 0xf18d21f4, |
816 | 0x20b6012c, | 816 | 0xf04afc17, |
817 | 0x0012d003, | 817 | 0x27f00213, |
818 | 0xf001acf0, | 818 | 0x0012d00c, |
819 | 0xb7f006a5, | 819 | 0x020721f5, |
820 | 0x140c9800, | 820 | 0x47fc27f1, |
821 | 0xf0150d98, | 821 | 0xd00223f0, |
822 | 0x21f500e7, | 822 | 0x2cf00020, |
823 | 0xa7f0015c, | 823 | 0x0320b601, |
824 | 0x0321f508, | 824 | 0xf00012d0, |
825 | 0x0721f501, | 825 | 0xa5f001ac, |
826 | 0x2201f402, | 826 | 0x00b7f006, |
827 | 0xf40ca7f0, | 827 | 0x98140c98, |
828 | 0x17f1c921, | 828 | 0xe7f0150d, |
829 | 0x14b60a10, | 829 | 0x5c21f500, |
830 | 0x0527f006, | 830 | 0x08a7f001, |
831 | /* 0x08ab: ctx_xfer_post_save_wait */ | 831 | 0x010321f5, |
832 | 0xcf0012d0, | 832 | 0x020721f5, |
833 | 0x22fd0012, | 833 | 0xf02201f4, |
834 | 0xfa1bf405, | 834 | 0x21f40ca7, |
835 | /* 0x08b7: ctx_xfer_post */ | 835 | 0x1017f1c9, |
836 | 0xf02e02f4, | 836 | 0x0614b60a, |
837 | 0x21f502f7, | 837 | 0xd00527f0, |
838 | 0xf4bd0631, | 838 | /* 0x08c2: ctx_xfer_post_save_wait */ |
839 | 0x067221f5, | 839 | 0x12cf0012, |
840 | 0x022621f5, | 840 | 0x0522fd00, |
841 | 0x064021f5, | 841 | 0xf4fa1bf4, |
842 | 0x21f5f4bd, | 842 | /* 0x08ce: ctx_xfer_post */ |
843 | 0x11f40631, | 843 | 0xf7f02e02, |
844 | 0x80019810, | 844 | 0x3121f502, |
845 | 0xf40511fd, | 845 | 0xf5f4bd06, |
846 | 0x21f5070b, | 846 | 0xf5067221, |
847 | /* 0x08e2: ctx_xfer_no_post_mmio */ | 847 | 0xf5022621, |
848 | /* 0x08e2: ctx_xfer_done */ | 848 | 0xbd064021, |
849 | 0x00f807b1, | 849 | 0x3121f5f4, |
850 | 0x00000000, | 850 | 0x1011f406, |
851 | 0x00000000, | 851 | 0xfd800198, |
852 | 0x00000000, | 852 | 0x0bf40511, |
853 | 0x00000000, | 853 | 0xb121f507, |
854 | 0x00000000, | 854 | /* 0x08f9: ctx_xfer_no_post_mmio */ |
855 | 0x00000000, | 855 | /* 0x08f9: ctx_xfer_done */ |
856 | 0x0000f807, | ||
856 | 0x00000000, | 857 | 0x00000000, |
857 | }; | 858 | }; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index 47a02081d708..45aff5f5085a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | |||
@@ -516,18 +516,9 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
516 | { | 516 | { |
517 | struct nouveau_device *device = nv_device(parent); | 517 | struct nouveau_device *device = nv_device(parent); |
518 | struct nvc0_graph_priv *priv; | 518 | struct nvc0_graph_priv *priv; |
519 | bool enable = true; | ||
520 | int ret, i; | 519 | int ret, i; |
521 | 520 | ||
522 | switch (device->chipset) { | 521 | ret = nouveau_graph_create(parent, engine, oclass, true, &priv); |
523 | case 0xd9: /* known broken without binary driver firmware */ | ||
524 | enable = false; | ||
525 | break; | ||
526 | default: | ||
527 | break; | ||
528 | } | ||
529 | |||
530 | ret = nouveau_graph_create(parent, engine, oclass, enable, &priv); | ||
531 | *pobject = nv_object(priv); | 522 | *pobject = nv_object(priv); |
532 | if (ret) | 523 | if (ret) |
533 | return ret; | 524 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h index 18d2210e12eb..a1e78de46456 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h | |||
@@ -121,6 +121,7 @@ nvc0_graph_class(void *obj) | |||
121 | return 0x9297; | 121 | return 0x9297; |
122 | case 0xe4: | 122 | case 0xe4: |
123 | case 0xe7: | 123 | case 0xe7: |
124 | case 0xe6: | ||
124 | return 0xa097; | 125 | return 0xa097; |
125 | default: | 126 | default: |
126 | return 0; | 127 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c index 539d4c72f192..9f82e9702b46 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c | |||
@@ -203,7 +203,7 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
203 | struct nvc0_graph_priv *priv; | 203 | struct nvc0_graph_priv *priv; |
204 | int ret, i; | 204 | int ret, i; |
205 | 205 | ||
206 | ret = nouveau_graph_create(parent, engine, oclass, false, &priv); | 206 | ret = nouveau_graph_create(parent, engine, oclass, true, &priv); |
207 | *pobject = nv_object(priv); | 207 | *pobject = nv_object(priv); |
208 | if (ret) | 208 | if (ret) |
209 | return ret; | 209 | return ret; |
@@ -252,6 +252,7 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
252 | priv->magic_not_rop_nr = 1; | 252 | priv->magic_not_rop_nr = 1; |
253 | break; | 253 | break; |
254 | case 0xe7: | 254 | case 0xe7: |
255 | case 0xe6: | ||
255 | priv->magic_not_rop_nr = 1; | 256 | priv->magic_not_rop_nr = 1; |
256 | break; | 257 | break; |
257 | default: | 258 | default: |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h index d145b25e6be4..5bd1ca8cd20d 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios.h | |||
@@ -17,6 +17,7 @@ struct nouveau_bios { | |||
17 | u8 chip; | 17 | u8 chip; |
18 | u8 minor; | 18 | u8 minor; |
19 | u8 micro; | 19 | u8 micro; |
20 | u8 patch; | ||
20 | } version; | 21 | } version; |
21 | }; | 22 | }; |
22 | 23 | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h index 2bf178082a36..e6563b5cb08e 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h | |||
@@ -25,9 +25,11 @@ struct dcb_gpio_func { | |||
25 | u8 param; | 25 | u8 param; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | u16 dcb_gpio_table(struct nouveau_bios *); | 28 | u16 dcb_gpio_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); |
29 | u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver); | 29 | u16 dcb_gpio_entry(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len); |
30 | int dcb_gpio_parse(struct nouveau_bios *, int idx, u8 func, u8 line, | 30 | u16 dcb_gpio_parse(struct nouveau_bios *, int idx, int ent, u8 *ver, u8 *len, |
31 | struct dcb_gpio_func *); | 31 | struct dcb_gpio_func *); |
32 | u16 dcb_gpio_match(struct nouveau_bios *, int idx, u8 func, u8 line, | ||
33 | u8 *ver, u8 *len, struct dcb_gpio_func *); | ||
32 | 34 | ||
33 | #endif | 35 | #endif |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h index e69a8bdc6e97..ca2f6bf37f46 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/init.h | |||
@@ -13,6 +13,7 @@ struct nvbios_init { | |||
13 | u32 nested; | 13 | u32 nested; |
14 | u16 repeat; | 14 | u16 repeat; |
15 | u16 repend; | 15 | u16 repend; |
16 | u32 ramcfg; | ||
16 | }; | 17 | }; |
17 | 18 | ||
18 | int nvbios_exec(struct nvbios_init *); | 19 | int nvbios_exec(struct nvbios_init *); |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h index 9ea2b12cc15d..b75e8f18e52c 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h | |||
@@ -11,7 +11,7 @@ struct nouveau_gpio { | |||
11 | struct nouveau_subdev base; | 11 | struct nouveau_subdev base; |
12 | 12 | ||
13 | /* hardware interfaces */ | 13 | /* hardware interfaces */ |
14 | void (*reset)(struct nouveau_gpio *); | 14 | void (*reset)(struct nouveau_gpio *, u8 func); |
15 | int (*drive)(struct nouveau_gpio *, int line, int dir, int out); | 15 | int (*drive)(struct nouveau_gpio *, int line, int dir, int out); |
16 | int (*sense)(struct nouveau_gpio *, int line); | 16 | int (*sense)(struct nouveau_gpio *, int line); |
17 | void (*irq_enable)(struct nouveau_gpio *, int line, bool); | 17 | void (*irq_enable)(struct nouveau_gpio *, int line, bool); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index dd111947eb86..f621f69fa1a2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c | |||
@@ -447,6 +447,7 @@ nouveau_bios_ctor(struct nouveau_object *parent, | |||
447 | bios->version.chip = nv_ro08(bios, bit_i.offset + 2); | 447 | bios->version.chip = nv_ro08(bios, bit_i.offset + 2); |
448 | bios->version.minor = nv_ro08(bios, bit_i.offset + 1); | 448 | bios->version.minor = nv_ro08(bios, bit_i.offset + 1); |
449 | bios->version.micro = nv_ro08(bios, bit_i.offset + 0); | 449 | bios->version.micro = nv_ro08(bios, bit_i.offset + 0); |
450 | bios->version.patch = nv_ro08(bios, bit_i.offset + 4); | ||
450 | } else | 451 | } else |
451 | if (bmp_version(bios)) { | 452 | if (bmp_version(bios)) { |
452 | bios->version.major = nv_ro08(bios, bios->bmp_offset + 13); | 453 | bios->version.major = nv_ro08(bios, bios->bmp_offset + 13); |
@@ -455,9 +456,9 @@ nouveau_bios_ctor(struct nouveau_object *parent, | |||
455 | bios->version.micro = nv_ro08(bios, bios->bmp_offset + 10); | 456 | bios->version.micro = nv_ro08(bios, bios->bmp_offset + 10); |
456 | } | 457 | } |
457 | 458 | ||
458 | nv_info(bios, "version %02x.%02x.%02x.%02x\n", | 459 | nv_info(bios, "version %02x.%02x.%02x.%02x.%02x\n", |
459 | bios->version.major, bios->version.chip, | 460 | bios->version.major, bios->version.chip, |
460 | bios->version.minor, bios->version.micro); | 461 | bios->version.minor, bios->version.micro, bios->version.patch); |
461 | 462 | ||
462 | return 0; | 463 | return 0; |
463 | } | 464 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c b/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c index c90d4aa3ae4f..c84e93fa6d95 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/gpio.c | |||
@@ -27,84 +27,105 @@ | |||
27 | #include <subdev/bios/gpio.h> | 27 | #include <subdev/bios/gpio.h> |
28 | 28 | ||
29 | u16 | 29 | u16 |
30 | dcb_gpio_table(struct nouveau_bios *bios) | 30 | dcb_gpio_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) |
31 | { | 31 | { |
32 | u8 ver, hdr, cnt, len; | 32 | u16 data = 0x0000; |
33 | u16 dcb = dcb_table(bios, &ver, &hdr, &cnt, &len); | 33 | u16 dcb = dcb_table(bios, ver, hdr, cnt, len); |
34 | if (dcb) { | 34 | if (dcb) { |
35 | if (ver >= 0x30 && hdr >= 0x0c) | 35 | if (*ver >= 0x30 && *hdr >= 0x0c) |
36 | return nv_ro16(bios, dcb + 0x0a); | 36 | data = nv_ro16(bios, dcb + 0x0a); |
37 | if (ver >= 0x22 && nv_ro08(bios, dcb - 1) >= 0x13) | 37 | else |
38 | return nv_ro16(bios, dcb - 0x0f); | 38 | if (*ver >= 0x22 && nv_ro08(bios, dcb - 1) >= 0x13) |
39 | data = nv_ro16(bios, dcb - 0x0f); | ||
40 | |||
41 | if (data) { | ||
42 | *ver = nv_ro08(bios, data + 0x00); | ||
43 | if (*ver < 0x30) { | ||
44 | *hdr = 3; | ||
45 | *cnt = nv_ro08(bios, data + 0x02); | ||
46 | *len = nv_ro08(bios, data + 0x01); | ||
47 | } else | ||
48 | if (*ver <= 0x41) { | ||
49 | *hdr = nv_ro08(bios, data + 0x01); | ||
50 | *cnt = nv_ro08(bios, data + 0x02); | ||
51 | *len = nv_ro08(bios, data + 0x03); | ||
52 | } else { | ||
53 | data = 0x0000; | ||
54 | } | ||
55 | } | ||
39 | } | 56 | } |
40 | return 0x0000; | 57 | return data; |
41 | } | 58 | } |
42 | 59 | ||
43 | u16 | 60 | u16 |
44 | dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver) | 61 | dcb_gpio_entry(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len) |
45 | { | 62 | { |
46 | u16 gpio = dcb_gpio_table(bios); | 63 | u8 hdr, cnt; |
47 | if (gpio) { | 64 | u16 gpio = !idx ? dcb_gpio_table(bios, ver, &hdr, &cnt, len) : 0x0000; |
48 | *ver = nv_ro08(bios, gpio); | 65 | if (gpio && ent < cnt) |
49 | if (*ver < 0x30 && ent < nv_ro08(bios, gpio + 2)) | 66 | return gpio + hdr + (ent * *len); |
50 | return gpio + 3 + (ent * nv_ro08(bios, gpio + 1)); | ||
51 | else if (ent < nv_ro08(bios, gpio + 2)) | ||
52 | return gpio + nv_ro08(bios, gpio + 1) + | ||
53 | (ent * nv_ro08(bios, gpio + 3)); | ||
54 | } | ||
55 | return 0x0000; | 67 | return 0x0000; |
56 | } | 68 | } |
57 | 69 | ||
58 | int | 70 | u16 |
59 | dcb_gpio_parse(struct nouveau_bios *bios, int idx, u8 func, u8 line, | 71 | dcb_gpio_parse(struct nouveau_bios *bios, int idx, int ent, u8 *ver, u8 *len, |
60 | struct dcb_gpio_func *gpio) | 72 | struct dcb_gpio_func *gpio) |
61 | { | 73 | { |
62 | u8 ver, hdr, cnt, len; | 74 | u16 data = dcb_gpio_entry(bios, idx, ent, ver, len); |
63 | u16 entry; | 75 | if (data) { |
64 | int i = -1; | 76 | if (*ver < 0x40) { |
65 | 77 | u16 info = nv_ro16(bios, data); | |
66 | while ((entry = dcb_gpio_entry(bios, idx, ++i, &ver))) { | ||
67 | if (ver < 0x40) { | ||
68 | u16 data = nv_ro16(bios, entry); | ||
69 | *gpio = (struct dcb_gpio_func) { | 78 | *gpio = (struct dcb_gpio_func) { |
70 | .line = (data & 0x001f) >> 0, | 79 | .line = (info & 0x001f) >> 0, |
71 | .func = (data & 0x07e0) >> 5, | 80 | .func = (info & 0x07e0) >> 5, |
72 | .log[0] = (data & 0x1800) >> 11, | 81 | .log[0] = (info & 0x1800) >> 11, |
73 | .log[1] = (data & 0x6000) >> 13, | 82 | .log[1] = (info & 0x6000) >> 13, |
74 | .param = !!(data & 0x8000), | 83 | .param = !!(info & 0x8000), |
75 | }; | 84 | }; |
76 | } else | 85 | } else |
77 | if (ver < 0x41) { | 86 | if (*ver < 0x41) { |
78 | u32 data = nv_ro32(bios, entry); | 87 | u32 info = nv_ro32(bios, data); |
79 | *gpio = (struct dcb_gpio_func) { | 88 | *gpio = (struct dcb_gpio_func) { |
80 | .line = (data & 0x0000001f) >> 0, | 89 | .line = (info & 0x0000001f) >> 0, |
81 | .func = (data & 0x0000ff00) >> 8, | 90 | .func = (info & 0x0000ff00) >> 8, |
82 | .log[0] = (data & 0x18000000) >> 27, | 91 | .log[0] = (info & 0x18000000) >> 27, |
83 | .log[1] = (data & 0x60000000) >> 29, | 92 | .log[1] = (info & 0x60000000) >> 29, |
84 | .param = !!(data & 0x80000000), | 93 | .param = !!(info & 0x80000000), |
85 | }; | 94 | }; |
86 | } else { | 95 | } else { |
87 | u32 data = nv_ro32(bios, entry + 0); | 96 | u32 info = nv_ro32(bios, data + 0); |
88 | u8 data1 = nv_ro32(bios, entry + 4); | 97 | u8 info1 = nv_ro32(bios, data + 4); |
89 | *gpio = (struct dcb_gpio_func) { | 98 | *gpio = (struct dcb_gpio_func) { |
90 | .line = (data & 0x0000003f) >> 0, | 99 | .line = (info & 0x0000003f) >> 0, |
91 | .func = (data & 0x0000ff00) >> 8, | 100 | .func = (info & 0x0000ff00) >> 8, |
92 | .log[0] = (data1 & 0x30) >> 4, | 101 | .log[0] = (info1 & 0x30) >> 4, |
93 | .log[1] = (data1 & 0xc0) >> 6, | 102 | .log[1] = (info1 & 0xc0) >> 6, |
94 | .param = !!(data & 0x80000000), | 103 | .param = !!(info & 0x80000000), |
95 | }; | 104 | }; |
96 | } | 105 | } |
106 | } | ||
107 | |||
108 | return data; | ||
109 | } | ||
97 | 110 | ||
111 | u16 | ||
112 | dcb_gpio_match(struct nouveau_bios *bios, int idx, u8 func, u8 line, | ||
113 | u8 *ver, u8 *len, struct dcb_gpio_func *gpio) | ||
114 | { | ||
115 | u8 hdr, cnt, i = 0; | ||
116 | u16 data; | ||
117 | |||
118 | while ((data = dcb_gpio_parse(bios, idx, i++, ver, len, gpio))) { | ||
98 | if ((line == 0xff || line == gpio->line) && | 119 | if ((line == 0xff || line == gpio->line) && |
99 | (func == 0xff || func == gpio->func)) | 120 | (func == 0xff || func == gpio->func)) |
100 | return 0; | 121 | return data; |
101 | } | 122 | } |
102 | 123 | ||
103 | /* DCB 2.2, fixed TVDAC GPIO data */ | 124 | /* DCB 2.2, fixed TVDAC GPIO data */ |
104 | if ((entry = dcb_table(bios, &ver, &hdr, &cnt, &len))) { | 125 | if ((data = dcb_table(bios, ver, &hdr, &cnt, len))) { |
105 | if (ver >= 0x22 && ver < 0x30 && func == DCB_GPIO_TVDAC0) { | 126 | if (*ver >= 0x22 && *ver < 0x30 && func == DCB_GPIO_TVDAC0) { |
106 | u8 conf = nv_ro08(bios, entry - 5); | 127 | u8 conf = nv_ro08(bios, data - 5); |
107 | u8 addr = nv_ro08(bios, entry - 4); | 128 | u8 addr = nv_ro08(bios, data - 4); |
108 | if (conf & 0x01) { | 129 | if (conf & 0x01) { |
109 | *gpio = (struct dcb_gpio_func) { | 130 | *gpio = (struct dcb_gpio_func) { |
110 | .func = DCB_GPIO_TVDAC0, | 131 | .func = DCB_GPIO_TVDAC0, |
@@ -112,10 +133,11 @@ dcb_gpio_parse(struct nouveau_bios *bios, int idx, u8 func, u8 line, | |||
112 | .log[0] = !!(conf & 0x02), | 133 | .log[0] = !!(conf & 0x02), |
113 | .log[1] = !(conf & 0x02), | 134 | .log[1] = !(conf & 0x02), |
114 | }; | 135 | }; |
115 | return 0; | 136 | *ver = 0x00; |
137 | return data; | ||
116 | } | 138 | } |
117 | } | 139 | } |
118 | } | 140 | } |
119 | 141 | ||
120 | return -EINVAL; | 142 | return 0x0000; |
121 | } | 143 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index ae168bbb86d8..2917d552689b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c | |||
@@ -2,11 +2,12 @@ | |||
2 | #include <core/device.h> | 2 | #include <core/device.h> |
3 | 3 | ||
4 | #include <subdev/bios.h> | 4 | #include <subdev/bios.h> |
5 | #include <subdev/bios/conn.h> | ||
6 | #include <subdev/bios/bmp.h> | 5 | #include <subdev/bios/bmp.h> |
7 | #include <subdev/bios/bit.h> | 6 | #include <subdev/bios/bit.h> |
7 | #include <subdev/bios/conn.h> | ||
8 | #include <subdev/bios/dcb.h> | 8 | #include <subdev/bios/dcb.h> |
9 | #include <subdev/bios/dp.h> | 9 | #include <subdev/bios/dp.h> |
10 | #include <subdev/bios/gpio.h> | ||
10 | #include <subdev/bios/init.h> | 11 | #include <subdev/bios/init.h> |
11 | #include <subdev/devinit.h> | 12 | #include <subdev/devinit.h> |
12 | #include <subdev/clock.h> | 13 | #include <subdev/clock.h> |
@@ -410,9 +411,25 @@ init_ram_restrict_group_count(struct nvbios_init *init) | |||
410 | } | 411 | } |
411 | 412 | ||
412 | static u8 | 413 | static u8 |
414 | init_ram_restrict_strap(struct nvbios_init *init) | ||
415 | { | ||
416 | /* This appears to be the behaviour of the VBIOS parser, and *is* | ||
417 | * important to cache the NV_PEXTDEV_BOOT0 on later chipsets to | ||
418 | * avoid fucking up the memory controller (somehow) by reading it | ||
419 | * on every INIT_RAM_RESTRICT_ZM_GROUP opcode. | ||
420 | * | ||
421 | * Preserving the non-caching behaviour on earlier chipsets just | ||
422 | * in case *not* re-reading the strap causes similar breakage. | ||
423 | */ | ||
424 | if (!init->ramcfg || init->bios->version.major < 0x70) | ||
425 | init->ramcfg = init_rd32(init, 0x101000); | ||
426 | return (init->ramcfg & 0x00000003c) >> 2; | ||
427 | } | ||
428 | |||
429 | static u8 | ||
413 | init_ram_restrict(struct nvbios_init *init) | 430 | init_ram_restrict(struct nvbios_init *init) |
414 | { | 431 | { |
415 | u32 strap = (init_rd32(init, 0x101000) & 0x0000003c) >> 2; | 432 | u8 strap = init_ram_restrict_strap(init); |
416 | u16 table = init_ram_restrict_table(init); | 433 | u16 table = init_ram_restrict_table(init); |
417 | if (table) | 434 | if (table) |
418 | return nv_ro08(init->bios, table + strap); | 435 | return nv_ro08(init->bios, table + strap); |
@@ -1781,7 +1798,7 @@ init_gpio(struct nvbios_init *init) | |||
1781 | init->offset += 1; | 1798 | init->offset += 1; |
1782 | 1799 | ||
1783 | if (init_exec(init) && gpio && gpio->reset) | 1800 | if (init_exec(init) && gpio && gpio->reset) |
1784 | gpio->reset(gpio); | 1801 | gpio->reset(gpio, DCB_GPIO_UNUSED); |
1785 | } | 1802 | } |
1786 | 1803 | ||
1787 | /** | 1804 | /** |
@@ -1995,6 +2012,47 @@ init_i2c_long_if(struct nvbios_init *init) | |||
1995 | init_exec_set(init, false); | 2012 | init_exec_set(init, false); |
1996 | } | 2013 | } |
1997 | 2014 | ||
2015 | /** | ||
2016 | * INIT_GPIO_NE - opcode 0xa9 | ||
2017 | * | ||
2018 | */ | ||
2019 | static void | ||
2020 | init_gpio_ne(struct nvbios_init *init) | ||
2021 | { | ||
2022 | struct nouveau_bios *bios = init->bios; | ||
2023 | struct nouveau_gpio *gpio = nouveau_gpio(bios); | ||
2024 | struct dcb_gpio_func func; | ||
2025 | u8 count = nv_ro08(bios, init->offset + 1); | ||
2026 | u8 idx = 0, ver, len; | ||
2027 | u16 data, i; | ||
2028 | |||
2029 | trace("GPIO_NE\t"); | ||
2030 | init->offset += 2; | ||
2031 | |||
2032 | for (i = init->offset; i < init->offset + count; i++) | ||
2033 | cont("0x%02x ", nv_ro08(bios, i)); | ||
2034 | cont("\n"); | ||
2035 | |||
2036 | while ((data = dcb_gpio_parse(bios, 0, idx++, &ver, &len, &func))) { | ||
2037 | if (func.func != DCB_GPIO_UNUSED) { | ||
2038 | for (i = init->offset; i < init->offset + count; i++) { | ||
2039 | if (func.func == nv_ro08(bios, i)) | ||
2040 | break; | ||
2041 | } | ||
2042 | |||
2043 | trace("\tFUNC[0x%02x]", func.func); | ||
2044 | if (i == (init->offset + count)) { | ||
2045 | cont(" *"); | ||
2046 | if (init_exec(init) && gpio && gpio->reset) | ||
2047 | gpio->reset(gpio, func.func); | ||
2048 | } | ||
2049 | cont("\n"); | ||
2050 | } | ||
2051 | } | ||
2052 | |||
2053 | init->offset += count; | ||
2054 | } | ||
2055 | |||
1998 | static struct nvbios_init_opcode { | 2056 | static struct nvbios_init_opcode { |
1999 | void (*exec)(struct nvbios_init *); | 2057 | void (*exec)(struct nvbios_init *); |
2000 | } init_opcode[] = { | 2058 | } init_opcode[] = { |
@@ -2059,6 +2117,7 @@ static struct nvbios_init_opcode { | |||
2059 | [0x98] = { init_auxch }, | 2117 | [0x98] = { init_auxch }, |
2060 | [0x99] = { init_zm_auxch }, | 2118 | [0x99] = { init_zm_auxch }, |
2061 | [0x9a] = { init_i2c_long_if }, | 2119 | [0x9a] = { init_i2c_long_if }, |
2120 | [0xa9] = { init_gpio_ne }, | ||
2062 | }; | 2121 | }; |
2063 | 2122 | ||
2064 | #define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0])) | 2123 | #define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0])) |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c index 9b7881e76634..03a652876e73 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c | |||
@@ -109,6 +109,34 @@ nve0_identify(struct nouveau_device *device) | |||
109 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | 109 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; |
110 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 110 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
111 | break; | 111 | break; |
112 | case 0xe6: | ||
113 | device->cname = "GK106"; | ||
114 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; | ||
115 | device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass; | ||
116 | device->oclass[NVDEV_SUBDEV_I2C ] = &nouveau_i2c_oclass; | ||
117 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; | ||
118 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; | ||
119 | device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; | ||
120 | device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; | ||
121 | device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; | ||
122 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | ||
123 | device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; | ||
124 | device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; | ||
125 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | ||
126 | device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; | ||
127 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | ||
128 | device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; | ||
129 | device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; | ||
130 | device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass; | ||
131 | device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; | ||
132 | device->oclass[NVDEV_ENGINE_GR ] = &nve0_graph_oclass; | ||
133 | device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; | ||
134 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; | ||
135 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; | ||
136 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; | ||
137 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | ||
138 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | ||
139 | break; | ||
112 | default: | 140 | default: |
113 | nv_fatal(device, "unknown Kepler chipset\n"); | 141 | nv_fatal(device, "unknown Kepler chipset\n"); |
114 | return -EINVAL; | 142 | return -EINVAL; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c index acf818c58bf0..9fb0f9b92d49 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c | |||
@@ -43,10 +43,15 @@ static int | |||
43 | nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, | 43 | nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, |
44 | struct dcb_gpio_func *func) | 44 | struct dcb_gpio_func *func) |
45 | { | 45 | { |
46 | struct nouveau_bios *bios = nouveau_bios(gpio); | ||
47 | u8 ver, len; | ||
48 | u16 data; | ||
49 | |||
46 | if (line == 0xff && tag == 0xff) | 50 | if (line == 0xff && tag == 0xff) |
47 | return -EINVAL; | 51 | return -EINVAL; |
48 | 52 | ||
49 | if (!dcb_gpio_parse(nouveau_bios(gpio), idx, tag, line, func)) | 53 | data = dcb_gpio_match(bios, idx, tag, line, &ver, &len, func); |
54 | if (data) | ||
50 | return 0; | 55 | return 0; |
51 | 56 | ||
52 | /* Apple iMac G4 NV18 */ | 57 | /* Apple iMac G4 NV18 */ |
@@ -265,7 +270,7 @@ nouveau_gpio_init(struct nouveau_gpio *gpio) | |||
265 | int ret = nouveau_subdev_init(&gpio->base); | 270 | int ret = nouveau_subdev_init(&gpio->base); |
266 | if (ret == 0 && gpio->reset) { | 271 | if (ret == 0 && gpio->reset) { |
267 | if (dmi_check_system(gpio_reset_ids)) | 272 | if (dmi_check_system(gpio_reset_ids)) |
268 | gpio->reset(gpio); | 273 | gpio->reset(gpio, DCB_GPIO_UNUSED); |
269 | } | 274 | } |
270 | return ret; | 275 | return ret; |
271 | } | 276 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c index f3502c961cd9..bf13a1200f26 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c | |||
@@ -29,15 +29,15 @@ struct nv50_gpio_priv { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | static void | 31 | static void |
32 | nv50_gpio_reset(struct nouveau_gpio *gpio) | 32 | nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match) |
33 | { | 33 | { |
34 | struct nouveau_bios *bios = nouveau_bios(gpio); | 34 | struct nouveau_bios *bios = nouveau_bios(gpio); |
35 | struct nv50_gpio_priv *priv = (void *)gpio; | 35 | struct nv50_gpio_priv *priv = (void *)gpio; |
36 | u8 ver, len; | ||
36 | u16 entry; | 37 | u16 entry; |
37 | u8 ver; | ||
38 | int ent = -1; | 38 | int ent = -1; |
39 | 39 | ||
40 | while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver))) { | 40 | while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) { |
41 | static const u32 regs[] = { 0xe100, 0xe28c }; | 41 | static const u32 regs[] = { 0xe100, 0xe28c }; |
42 | u32 data = nv_ro32(bios, entry); | 42 | u32 data = nv_ro32(bios, entry); |
43 | u8 line = (data & 0x0000001f); | 43 | u8 line = (data & 0x0000001f); |
@@ -48,7 +48,8 @@ nv50_gpio_reset(struct nouveau_gpio *gpio) | |||
48 | u32 val = (unk1 << 16) | unk0; | 48 | u32 val = (unk1 << 16) | unk0; |
49 | u32 reg = regs[line >> 4]; line &= 0x0f; | 49 | u32 reg = regs[line >> 4]; line &= 0x0f; |
50 | 50 | ||
51 | if (func == 0xff) | 51 | if ( func == DCB_GPIO_UNUSED || |
52 | (match != DCB_GPIO_UNUSED && match != func)) | ||
52 | continue; | 53 | continue; |
53 | 54 | ||
54 | gpio->set(gpio, 0, func, line, defs); | 55 | gpio->set(gpio, 0, func, line, defs); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c index 8d18fcad26e0..83e8b8f16e6a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c | |||
@@ -29,15 +29,15 @@ struct nvd0_gpio_priv { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | static void | 31 | static void |
32 | nvd0_gpio_reset(struct nouveau_gpio *gpio) | 32 | nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match) |
33 | { | 33 | { |
34 | struct nouveau_bios *bios = nouveau_bios(gpio); | 34 | struct nouveau_bios *bios = nouveau_bios(gpio); |
35 | struct nvd0_gpio_priv *priv = (void *)gpio; | 35 | struct nvd0_gpio_priv *priv = (void *)gpio; |
36 | u8 ver, len; | ||
36 | u16 entry; | 37 | u16 entry; |
37 | u8 ver; | ||
38 | int ent = -1; | 38 | int ent = -1; |
39 | 39 | ||
40 | while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver))) { | 40 | while ((entry = dcb_gpio_entry(bios, 0, ++ent, &ver, &len))) { |
41 | u32 data = nv_ro32(bios, entry); | 41 | u32 data = nv_ro32(bios, entry); |
42 | u8 line = (data & 0x0000003f); | 42 | u8 line = (data & 0x0000003f); |
43 | u8 defs = !!(data & 0x00000080); | 43 | u8 defs = !!(data & 0x00000080); |
@@ -45,7 +45,8 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio) | |||
45 | u8 unk0 = (data & 0x00ff0000) >> 16; | 45 | u8 unk0 = (data & 0x00ff0000) >> 16; |
46 | u8 unk1 = (data & 0x1f000000) >> 24; | 46 | u8 unk1 = (data & 0x1f000000) >> 24; |
47 | 47 | ||
48 | if (func == 0xff) | 48 | if ( func == DCB_GPIO_UNUSED || |
49 | (match != DCB_GPIO_UNUSED && match != func)) | ||
49 | continue; | 50 | continue; |
50 | 51 | ||
51 | gpio->set(gpio, 0, func, line, defs); | 52 | gpio->set(gpio, 0, func, line, defs); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c index 93e3ddf7303a..e286e132c7e7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c | |||
@@ -260,7 +260,7 @@ nouveau_mxm_create_(struct nouveau_object *parent, | |||
260 | 260 | ||
261 | data = mxm_table(bios, &ver, &len); | 261 | data = mxm_table(bios, &ver, &len); |
262 | if (!data || !(ver = nv_ro08(bios, data))) { | 262 | if (!data || !(ver = nv_ro08(bios, data))) { |
263 | nv_info(mxm, "no VBIOS data, nothing to do\n"); | 263 | nv_debug(mxm, "no VBIOS data, nothing to do\n"); |
264 | return 0; | 264 | return 0; |
265 | } | 265 | } |
266 | 266 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 74c6b42d2597..7a445666e71f 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -2654,6 +2654,35 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2654 | ib[idx+4] = upper_32_bits(offset) & 0xff; | 2654 | ib[idx+4] = upper_32_bits(offset) & 0xff; |
2655 | } | 2655 | } |
2656 | break; | 2656 | break; |
2657 | case PACKET3_MEM_WRITE: | ||
2658 | { | ||
2659 | u64 offset; | ||
2660 | |||
2661 | if (pkt->count != 3) { | ||
2662 | DRM_ERROR("bad MEM_WRITE (invalid count)\n"); | ||
2663 | return -EINVAL; | ||
2664 | } | ||
2665 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2666 | if (r) { | ||
2667 | DRM_ERROR("bad MEM_WRITE (missing reloc)\n"); | ||
2668 | return -EINVAL; | ||
2669 | } | ||
2670 | offset = radeon_get_ib_value(p, idx+0); | ||
2671 | offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL; | ||
2672 | if (offset & 0x7) { | ||
2673 | DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n"); | ||
2674 | return -EINVAL; | ||
2675 | } | ||
2676 | if ((offset + 8) > radeon_bo_size(reloc->robj)) { | ||
2677 | DRM_ERROR("bad MEM_WRITE bo too small: 0x%llx, 0x%lx\n", | ||
2678 | offset + 8, radeon_bo_size(reloc->robj)); | ||
2679 | return -EINVAL; | ||
2680 | } | ||
2681 | offset += reloc->lobj.gpu_offset; | ||
2682 | ib[idx+0] = offset; | ||
2683 | ib[idx+1] = upper_32_bits(offset) & 0xff; | ||
2684 | break; | ||
2685 | } | ||
2657 | case PACKET3_COPY_DW: | 2686 | case PACKET3_COPY_DW: |
2658 | if (pkt->count != 4) { | 2687 | if (pkt->count != 4) { |
2659 | DRM_ERROR("bad COPY_DW (invalid count)\n"); | 2688 | DRM_ERROR("bad COPY_DW (invalid count)\n"); |
@@ -3287,6 +3316,7 @@ static bool evergreen_vm_reg_valid(u32 reg) | |||
3287 | 3316 | ||
3288 | /* check config regs */ | 3317 | /* check config regs */ |
3289 | switch (reg) { | 3318 | switch (reg) { |
3319 | case WAIT_UNTIL: | ||
3290 | case GRBM_GFX_INDEX: | 3320 | case GRBM_GFX_INDEX: |
3291 | case CP_STRMOUT_CNTL: | 3321 | case CP_STRMOUT_CNTL: |
3292 | case CP_COHER_CNTL: | 3322 | case CP_COHER_CNTL: |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0be768be530c..9ea13d07cc55 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -2294,6 +2294,35 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
2294 | ib[idx+4] = upper_32_bits(offset) & 0xff; | 2294 | ib[idx+4] = upper_32_bits(offset) & 0xff; |
2295 | } | 2295 | } |
2296 | break; | 2296 | break; |
2297 | case PACKET3_MEM_WRITE: | ||
2298 | { | ||
2299 | u64 offset; | ||
2300 | |||
2301 | if (pkt->count != 3) { | ||
2302 | DRM_ERROR("bad MEM_WRITE (invalid count)\n"); | ||
2303 | return -EINVAL; | ||
2304 | } | ||
2305 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
2306 | if (r) { | ||
2307 | DRM_ERROR("bad MEM_WRITE (missing reloc)\n"); | ||
2308 | return -EINVAL; | ||
2309 | } | ||
2310 | offset = radeon_get_ib_value(p, idx+0); | ||
2311 | offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL; | ||
2312 | if (offset & 0x7) { | ||
2313 | DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n"); | ||
2314 | return -EINVAL; | ||
2315 | } | ||
2316 | if ((offset + 8) > radeon_bo_size(reloc->robj)) { | ||
2317 | DRM_ERROR("bad MEM_WRITE bo too small: 0x%llx, 0x%lx\n", | ||
2318 | offset + 8, radeon_bo_size(reloc->robj)); | ||
2319 | return -EINVAL; | ||
2320 | } | ||
2321 | offset += reloc->lobj.gpu_offset; | ||
2322 | ib[idx+0] = offset; | ||
2323 | ib[idx+1] = upper_32_bits(offset) & 0xff; | ||
2324 | break; | ||
2325 | } | ||
2297 | case PACKET3_COPY_DW: | 2326 | case PACKET3_COPY_DW: |
2298 | if (pkt->count != 4) { | 2327 | if (pkt->count != 4) { |
2299 | DRM_ERROR("bad COPY_DW (invalid count)\n"); | 2328 | DRM_ERROR("bad COPY_DW (invalid count)\n"); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5dc744d43d12..9b9422c4403a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -225,12 +225,13 @@ struct radeon_fence { | |||
225 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); | 225 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); |
226 | int radeon_fence_driver_init(struct radeon_device *rdev); | 226 | int radeon_fence_driver_init(struct radeon_device *rdev); |
227 | void radeon_fence_driver_fini(struct radeon_device *rdev); | 227 | void radeon_fence_driver_fini(struct radeon_device *rdev); |
228 | void radeon_fence_driver_force_completion(struct radeon_device *rdev); | ||
228 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring); | 229 | int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring); |
229 | void radeon_fence_process(struct radeon_device *rdev, int ring); | 230 | void radeon_fence_process(struct radeon_device *rdev, int ring); |
230 | bool radeon_fence_signaled(struct radeon_fence *fence); | 231 | bool radeon_fence_signaled(struct radeon_fence *fence); |
231 | int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); | 232 | int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); |
232 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); | 233 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); |
233 | void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); | 234 | int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); |
234 | int radeon_fence_wait_any(struct radeon_device *rdev, | 235 | int radeon_fence_wait_any(struct radeon_device *rdev, |
235 | struct radeon_fence **fences, | 236 | struct radeon_fence **fences, |
236 | bool intr); | 237 | bool intr); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 49b06590001e..cd756262924d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -1164,6 +1164,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
1164 | struct drm_crtc *crtc; | 1164 | struct drm_crtc *crtc; |
1165 | struct drm_connector *connector; | 1165 | struct drm_connector *connector; |
1166 | int i, r; | 1166 | int i, r; |
1167 | bool force_completion = false; | ||
1167 | 1168 | ||
1168 | if (dev == NULL || dev->dev_private == NULL) { | 1169 | if (dev == NULL || dev->dev_private == NULL) { |
1169 | return -ENODEV; | 1170 | return -ENODEV; |
@@ -1206,8 +1207,16 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
1206 | 1207 | ||
1207 | mutex_lock(&rdev->ring_lock); | 1208 | mutex_lock(&rdev->ring_lock); |
1208 | /* wait for gpu to finish processing current batch */ | 1209 | /* wait for gpu to finish processing current batch */ |
1209 | for (i = 0; i < RADEON_NUM_RINGS; i++) | 1210 | for (i = 0; i < RADEON_NUM_RINGS; i++) { |
1210 | radeon_fence_wait_empty_locked(rdev, i); | 1211 | r = radeon_fence_wait_empty_locked(rdev, i); |
1212 | if (r) { | ||
1213 | /* delay GPU reset to resume */ | ||
1214 | force_completion = true; | ||
1215 | } | ||
1216 | } | ||
1217 | if (force_completion) { | ||
1218 | radeon_fence_driver_force_completion(rdev); | ||
1219 | } | ||
1211 | mutex_unlock(&rdev->ring_lock); | 1220 | mutex_unlock(&rdev->ring_lock); |
1212 | 1221 | ||
1213 | radeon_save_bios_scratch_regs(rdev); | 1222 | radeon_save_bios_scratch_regs(rdev); |
@@ -1338,7 +1347,6 @@ retry: | |||
1338 | } | 1347 | } |
1339 | 1348 | ||
1340 | radeon_restore_bios_scratch_regs(rdev); | 1349 | radeon_restore_bios_scratch_regs(rdev); |
1341 | drm_helper_resume_force_mode(rdev->ddev); | ||
1342 | 1350 | ||
1343 | if (!r) { | 1351 | if (!r) { |
1344 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1352 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
@@ -1358,11 +1366,14 @@ retry: | |||
1358 | } | 1366 | } |
1359 | } | 1367 | } |
1360 | } else { | 1368 | } else { |
1369 | radeon_fence_driver_force_completion(rdev); | ||
1361 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1370 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
1362 | kfree(ring_data[i]); | 1371 | kfree(ring_data[i]); |
1363 | } | 1372 | } |
1364 | } | 1373 | } |
1365 | 1374 | ||
1375 | drm_helper_resume_force_mode(rdev->ddev); | ||
1376 | |||
1366 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 1377 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
1367 | if (r) { | 1378 | if (r) { |
1368 | /* bad news, how to tell it to userspace ? */ | 1379 | /* bad news, how to tell it to userspace ? */ |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 9b1a727d3c9e..ff7593498a74 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -68,9 +68,10 @@ | |||
68 | * 2.25.0 - eg+: new info request for num SE and num SH | 68 | * 2.25.0 - eg+: new info request for num SE and num SH |
69 | * 2.26.0 - r600-eg: fix htile size computation | 69 | * 2.26.0 - r600-eg: fix htile size computation |
70 | * 2.27.0 - r600-SI: Add CS ioctl support for async DMA | 70 | * 2.27.0 - r600-SI: Add CS ioctl support for async DMA |
71 | * 2.28.0 - r600-eg: Add MEM_WRITE packet support | ||
71 | */ | 72 | */ |
72 | #define KMS_DRIVER_MAJOR 2 | 73 | #define KMS_DRIVER_MAJOR 2 |
73 | #define KMS_DRIVER_MINOR 27 | 74 | #define KMS_DRIVER_MINOR 28 |
74 | #define KMS_DRIVER_PATCHLEVEL 0 | 75 | #define KMS_DRIVER_PATCHLEVEL 0 |
75 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 76 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
76 | int radeon_driver_unload_kms(struct drm_device *dev); | 77 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 410a975a8eec..34356252567a 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -609,26 +609,20 @@ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) | |||
609 | * Returns 0 if the fences have passed, error for all other cases. | 609 | * Returns 0 if the fences have passed, error for all other cases. |
610 | * Caller must hold ring lock. | 610 | * Caller must hold ring lock. |
611 | */ | 611 | */ |
612 | void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) | 612 | int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) |
613 | { | 613 | { |
614 | uint64_t seq = rdev->fence_drv[ring].sync_seq[ring]; | 614 | uint64_t seq = rdev->fence_drv[ring].sync_seq[ring]; |
615 | int r; | ||
615 | 616 | ||
616 | while(1) { | 617 | r = radeon_fence_wait_seq(rdev, seq, ring, false, false); |
617 | int r; | 618 | if (r) { |
618 | r = radeon_fence_wait_seq(rdev, seq, ring, false, false); | ||
619 | if (r == -EDEADLK) { | 619 | if (r == -EDEADLK) { |
620 | mutex_unlock(&rdev->ring_lock); | 620 | return -EDEADLK; |
621 | r = radeon_gpu_reset(rdev); | ||
622 | mutex_lock(&rdev->ring_lock); | ||
623 | if (!r) | ||
624 | continue; | ||
625 | } | ||
626 | if (r) { | ||
627 | dev_err(rdev->dev, "error waiting for ring to become" | ||
628 | " idle (%d)\n", r); | ||
629 | } | 621 | } |
630 | return; | 622 | dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%d)\n", |
623 | ring, r); | ||
631 | } | 624 | } |
625 | return 0; | ||
632 | } | 626 | } |
633 | 627 | ||
634 | /** | 628 | /** |
@@ -854,13 +848,17 @@ int radeon_fence_driver_init(struct radeon_device *rdev) | |||
854 | */ | 848 | */ |
855 | void radeon_fence_driver_fini(struct radeon_device *rdev) | 849 | void radeon_fence_driver_fini(struct radeon_device *rdev) |
856 | { | 850 | { |
857 | int ring; | 851 | int ring, r; |
858 | 852 | ||
859 | mutex_lock(&rdev->ring_lock); | 853 | mutex_lock(&rdev->ring_lock); |
860 | for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { | 854 | for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { |
861 | if (!rdev->fence_drv[ring].initialized) | 855 | if (!rdev->fence_drv[ring].initialized) |
862 | continue; | 856 | continue; |
863 | radeon_fence_wait_empty_locked(rdev, ring); | 857 | r = radeon_fence_wait_empty_locked(rdev, ring); |
858 | if (r) { | ||
859 | /* no need to trigger GPU reset as we are unloading */ | ||
860 | radeon_fence_driver_force_completion(rdev); | ||
861 | } | ||
864 | wake_up_all(&rdev->fence_queue); | 862 | wake_up_all(&rdev->fence_queue); |
865 | radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); | 863 | radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); |
866 | rdev->fence_drv[ring].initialized = false; | 864 | rdev->fence_drv[ring].initialized = false; |
@@ -868,6 +866,25 @@ void radeon_fence_driver_fini(struct radeon_device *rdev) | |||
868 | mutex_unlock(&rdev->ring_lock); | 866 | mutex_unlock(&rdev->ring_lock); |
869 | } | 867 | } |
870 | 868 | ||
869 | /** | ||
870 | * radeon_fence_driver_force_completion - force all fence waiter to complete | ||
871 | * | ||
872 | * @rdev: radeon device pointer | ||
873 | * | ||
874 | * In case of GPU reset failure make sure no process keep waiting on fence | ||
875 | * that will never complete. | ||
876 | */ | ||
877 | void radeon_fence_driver_force_completion(struct radeon_device *rdev) | ||
878 | { | ||
879 | int ring; | ||
880 | |||
881 | for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { | ||
882 | if (!rdev->fence_drv[ring].initialized) | ||
883 | continue; | ||
884 | radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring); | ||
885 | } | ||
886 | } | ||
887 | |||
871 | 888 | ||
872 | /* | 889 | /* |
873 | * Fence debugfs | 890 | * Fence debugfs |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index aa14dbb7e4fb..0bfa656aa87d 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -234,7 +234,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) | |||
234 | 234 | ||
235 | static void radeon_pm_set_clocks(struct radeon_device *rdev) | 235 | static void radeon_pm_set_clocks(struct radeon_device *rdev) |
236 | { | 236 | { |
237 | int i; | 237 | int i, r; |
238 | 238 | ||
239 | /* no need to take locks, etc. if nothing's going to change */ | 239 | /* no need to take locks, etc. if nothing's going to change */ |
240 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && | 240 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && |
@@ -248,8 +248,17 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
248 | /* wait for the rings to drain */ | 248 | /* wait for the rings to drain */ |
249 | for (i = 0; i < RADEON_NUM_RINGS; i++) { | 249 | for (i = 0; i < RADEON_NUM_RINGS; i++) { |
250 | struct radeon_ring *ring = &rdev->ring[i]; | 250 | struct radeon_ring *ring = &rdev->ring[i]; |
251 | if (ring->ready) | 251 | if (!ring->ready) { |
252 | radeon_fence_wait_empty_locked(rdev, i); | 252 | continue; |
253 | } | ||
254 | r = radeon_fence_wait_empty_locked(rdev, i); | ||
255 | if (r) { | ||
256 | /* needs a GPU reset dont reset here */ | ||
257 | mutex_unlock(&rdev->ring_lock); | ||
258 | up_write(&rdev->pm.mclk_lock); | ||
259 | mutex_unlock(&rdev->ddev->struct_mutex); | ||
260 | return; | ||
261 | } | ||
253 | } | 262 | } |
254 | 263 | ||
255 | radeon_unmap_vram_bos(rdev); | 264 | radeon_unmap_vram_bos(rdev); |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 074410371e2a..656b2e3334a6 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
@@ -102,12 +102,12 @@ static int tegra_dc_set_timings(struct tegra_dc *dc, | |||
102 | ((mode->hsync_end - mode->hsync_start) << 0); | 102 | ((mode->hsync_end - mode->hsync_start) << 0); |
103 | tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH); | 103 | tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH); |
104 | 104 | ||
105 | value = ((mode->vsync_start - mode->vdisplay) << 16) | | ||
106 | ((mode->hsync_start - mode->hdisplay) << 0); | ||
107 | tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH); | ||
108 | |||
109 | value = ((mode->vtotal - mode->vsync_end) << 16) | | 105 | value = ((mode->vtotal - mode->vsync_end) << 16) | |
110 | ((mode->htotal - mode->hsync_end) << 0); | 106 | ((mode->htotal - mode->hsync_end) << 0); |
107 | tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH); | ||
108 | |||
109 | value = ((mode->vsync_start - mode->vdisplay) << 16) | | ||
110 | ((mode->hsync_start - mode->hdisplay) << 0); | ||
111 | tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH); | 111 | tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH); |
112 | 112 | ||
113 | value = (mode->vdisplay << 16) | mode->hdisplay; | 113 | value = (mode->vdisplay << 16) | mode->hdisplay; |
@@ -221,8 +221,7 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc, | |||
221 | win.stride = crtc->fb->pitches[0]; | 221 | win.stride = crtc->fb->pitches[0]; |
222 | 222 | ||
223 | /* program window registers */ | 223 | /* program window registers */ |
224 | value = tegra_dc_readl(dc, DC_CMD_DISPLAY_WINDOW_HEADER); | 224 | value = WINDOW_A_SELECT; |
225 | value |= WINDOW_A_SELECT; | ||
226 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); | 225 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); |
227 | 226 | ||
228 | tegra_dc_writel(dc, win.fmt, DC_WIN_COLOR_DEPTH); | 227 | tegra_dc_writel(dc, win.fmt, DC_WIN_COLOR_DEPTH); |
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 3a843a77ddc7..741b5dc2742c 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h | |||
@@ -204,24 +204,6 @@ extern int tegra_output_parse_dt(struct tegra_output *output); | |||
204 | extern int tegra_output_init(struct drm_device *drm, struct tegra_output *output); | 204 | extern int tegra_output_init(struct drm_device *drm, struct tegra_output *output); |
205 | extern int tegra_output_exit(struct tegra_output *output); | 205 | extern int tegra_output_exit(struct tegra_output *output); |
206 | 206 | ||
207 | /* from gem.c */ | ||
208 | extern struct tegra_gem_object *tegra_gem_alloc(struct drm_device *drm, | ||
209 | size_t size); | ||
210 | extern int tegra_gem_handle_create(struct drm_device *drm, | ||
211 | struct drm_file *file, size_t size, | ||
212 | unsigned long flags, uint32_t *handle); | ||
213 | extern int tegra_gem_dumb_create(struct drm_file *file, struct drm_device *drm, | ||
214 | struct drm_mode_create_dumb *args); | ||
215 | extern int tegra_gem_dumb_map_offset(struct drm_file *file, | ||
216 | struct drm_device *drm, uint32_t handle, | ||
217 | uint64_t *offset); | ||
218 | extern int tegra_gem_dumb_destroy(struct drm_file *file, | ||
219 | struct drm_device *drm, uint32_t handle); | ||
220 | extern int tegra_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); | ||
221 | extern int tegra_gem_init_object(struct drm_gem_object *obj); | ||
222 | extern void tegra_gem_free_object(struct drm_gem_object *obj); | ||
223 | extern struct vm_operations_struct tegra_gem_vm_ops; | ||
224 | |||
225 | /* from fb.c */ | 207 | /* from fb.c */ |
226 | extern int tegra_drm_fb_init(struct drm_device *drm); | 208 | extern int tegra_drm_fb_init(struct drm_device *drm); |
227 | extern void tegra_drm_fb_exit(struct drm_device *drm); | 209 | extern void tegra_drm_fb_exit(struct drm_device *drm); |
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index ab4016412bbf..e060c7e6434d 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c | |||
@@ -149,7 +149,7 @@ struct tmds_config { | |||
149 | }; | 149 | }; |
150 | 150 | ||
151 | static const struct tmds_config tegra2_tmds_config[] = { | 151 | static const struct tmds_config tegra2_tmds_config[] = { |
152 | { /* 480p modes */ | 152 | { /* slow pixel clock modes */ |
153 | .pclk = 27000000, | 153 | .pclk = 27000000, |
154 | .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | | 154 | .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | |
155 | SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) | | 155 | SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) | |
@@ -163,21 +163,8 @@ static const struct tmds_config tegra2_tmds_config[] = { | |||
163 | DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) | | 163 | DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) | |
164 | DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) | | 164 | DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) | |
165 | DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA), | 165 | DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA), |
166 | }, { /* 720p modes */ | 166 | }, |
167 | .pclk = 74250000, | 167 | { /* high pixel clock modes */ |
168 | .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | | ||
169 | SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) | | ||
170 | SOR_PLL_TX_REG_LOAD(3), | ||
171 | .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN, | ||
172 | .pe_current = PE_CURRENT0(PE_CURRENT_6_0_mA) | | ||
173 | PE_CURRENT1(PE_CURRENT_6_0_mA) | | ||
174 | PE_CURRENT2(PE_CURRENT_6_0_mA) | | ||
175 | PE_CURRENT3(PE_CURRENT_6_0_mA), | ||
176 | .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) | | ||
177 | DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) | | ||
178 | DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) | | ||
179 | DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA), | ||
180 | }, { /* 1080p modes */ | ||
181 | .pclk = UINT_MAX, | 168 | .pclk = UINT_MAX, |
182 | .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | | 169 | .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | |
183 | SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) | | 170 | SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) | |
@@ -479,7 +466,7 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi, | |||
479 | return; | 466 | return; |
480 | } | 467 | } |
481 | 468 | ||
482 | h_front_porch = mode->htotal - mode->hsync_end; | 469 | h_front_porch = mode->hsync_start - mode->hdisplay; |
483 | memset(&frame, 0, sizeof(frame)); | 470 | memset(&frame, 0, sizeof(frame)); |
484 | frame.r = HDMI_AVI_R_SAME; | 471 | frame.r = HDMI_AVI_R_SAME; |
485 | 472 | ||
@@ -634,8 +621,8 @@ static int tegra_output_hdmi_enable(struct tegra_output *output) | |||
634 | 621 | ||
635 | pclk = mode->clock * 1000; | 622 | pclk = mode->clock * 1000; |
636 | h_sync_width = mode->hsync_end - mode->hsync_start; | 623 | h_sync_width = mode->hsync_end - mode->hsync_start; |
637 | h_front_porch = mode->htotal - mode->hsync_end; | 624 | h_back_porch = mode->htotal - mode->hsync_end; |
638 | h_back_porch = mode->hsync_start - mode->hdisplay; | 625 | h_front_porch = mode->hsync_start - mode->hdisplay; |
639 | 626 | ||
640 | err = regulator_enable(hdmi->vdd); | 627 | err = regulator_enable(hdmi->vdd); |
641 | if (err < 0) { | 628 | if (err < 0) { |
diff --git a/drivers/gpu/drm/tegra/host1x.c b/drivers/gpu/drm/tegra/host1x.c index bdb97a564d82..5d17b113a6fc 100644 --- a/drivers/gpu/drm/tegra/host1x.c +++ b/drivers/gpu/drm/tegra/host1x.c | |||
@@ -239,6 +239,8 @@ int host1x_register_client(struct host1x *host1x, struct host1x_client *client) | |||
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
242 | client->host1x = host1x; | ||
243 | |||
242 | return 0; | 244 | return 0; |
243 | } | 245 | } |
244 | 246 | ||
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 06d7f798a08c..0f4a366f6fa6 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h | |||
@@ -158,12 +158,29 @@ static inline struct drm_mm_node *drm_mm_get_block_atomic_range( | |||
158 | return drm_mm_get_block_range_generic(parent, size, alignment, 0, | 158 | return drm_mm_get_block_range_generic(parent, size, alignment, 0, |
159 | start, end, 1); | 159 | start, end, 1); |
160 | } | 160 | } |
161 | extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, | 161 | |
162 | unsigned long size, unsigned alignment); | 162 | extern int drm_mm_insert_node(struct drm_mm *mm, |
163 | struct drm_mm_node *node, | ||
164 | unsigned long size, | ||
165 | unsigned alignment); | ||
163 | extern int drm_mm_insert_node_in_range(struct drm_mm *mm, | 166 | extern int drm_mm_insert_node_in_range(struct drm_mm *mm, |
164 | struct drm_mm_node *node, | 167 | struct drm_mm_node *node, |
165 | unsigned long size, unsigned alignment, | 168 | unsigned long size, |
166 | unsigned long start, unsigned long end); | 169 | unsigned alignment, |
170 | unsigned long start, | ||
171 | unsigned long end); | ||
172 | extern int drm_mm_insert_node_generic(struct drm_mm *mm, | ||
173 | struct drm_mm_node *node, | ||
174 | unsigned long size, | ||
175 | unsigned alignment, | ||
176 | unsigned long color); | ||
177 | extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, | ||
178 | struct drm_mm_node *node, | ||
179 | unsigned long size, | ||
180 | unsigned alignment, | ||
181 | unsigned long color, | ||
182 | unsigned long start, | ||
183 | unsigned long end); | ||
167 | extern void drm_mm_put_block(struct drm_mm_node *cur); | 184 | extern void drm_mm_put_block(struct drm_mm_node *cur); |
168 | extern void drm_mm_remove_node(struct drm_mm_node *node); | 185 | extern void drm_mm_remove_node(struct drm_mm_node *node); |
169 | extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); | 186 | extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); |
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index b746a3cf5fa9..c4d2e9c74002 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h | |||
@@ -307,6 +307,7 @@ typedef struct drm_i915_irq_wait { | |||
307 | #define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21 | 307 | #define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21 |
308 | #define I915_PARAM_RSVD_FOR_FUTURE_USE 22 | 308 | #define I915_PARAM_RSVD_FOR_FUTURE_USE 22 |
309 | #define I915_PARAM_HAS_SECURE_BATCHES 23 | 309 | #define I915_PARAM_HAS_SECURE_BATCHES 23 |
310 | #define I915_PARAM_HAS_PINNED_BATCHES 24 | ||
310 | 311 | ||
311 | typedef struct drm_i915_getparam { | 312 | typedef struct drm_i915_getparam { |
312 | int param; | 313 | int param; |
@@ -677,6 +678,15 @@ struct drm_i915_gem_execbuffer2 { | |||
677 | */ | 678 | */ |
678 | #define I915_EXEC_SECURE (1<<9) | 679 | #define I915_EXEC_SECURE (1<<9) |
679 | 680 | ||
681 | /** Inform the kernel that the batch is and will always be pinned. This | ||
682 | * negates the requirement for a workaround to be performed to avoid | ||
683 | * an incoherent CS (such as can be found on 830/845). If this flag is | ||
684 | * not passed, the kernel will endeavour to make sure the batch is | ||
685 | * coherent with the CS before execution. If this flag is passed, | ||
686 | * userspace assumes the responsibility for ensuring the same. | ||
687 | */ | ||
688 | #define I915_EXEC_IS_PINNED (1<<10) | ||
689 | |||
680 | #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) | 690 | #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) |
681 | #define i915_execbuffer2_set_context_id(eb2, context) \ | 691 | #define i915_execbuffer2_set_context_id(eb2, context) \ |
682 | (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK | 692 | (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK |