diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-28 17:31:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-28 17:31:36 -0400 |
commit | 25d0d91af77089ddf378568fd858b22612c52aff (patch) | |
tree | d994e12764355a5b87945e3e9e932464b86f30d7 | |
parent | 908e373f1c8102505d13cdb61ad56c1686d6a583 (diff) | |
parent | add1fa75101263ab4d74240f93000998d4325624 (diff) |
Merge tag 'drm-fixes-for-4.8-rc4' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie:
"A bunch of fixes covering i915, amdgpu, one tegra and some core DRM
ones. Nothing too strange at this point"
* tag 'drm-fixes-for-4.8-rc4' of git://people.freedesktop.org/~airlied/linux: (21 commits)
drm/atomic: Don't potentially reset color_mgmt_changed on successive property updates.
drm: Protect fb_defio in drivers with CONFIG_KMS_FBDEV_EMULATION
drm/amdgpu: skip TV/CV in display parsing
drm/amdgpu: avoid a possible array overflow
drm/amdgpu: fix lru size grouping v2
drm/tegra: dsi: Enhance runtime power management
drm/i915: Fix botched merge that downgrades CSR versions.
drm/i915/skl: Ensure pipes with changed wms get added to the state
drm/i915/gen9: Only copy WM results for changed pipes to skl_hw
drm/i915/skl: Add support for the SAGV, fix underrun hangs
drm/i915/gen6+: Interpret mailbox error flags
drm/i915: Reattach comment, complete type specification
drm/i915: Unconditionally flush any chipset buffers before execbuf
drm/i915/gen9: Drop invalid WARN() during data rate calculation
drm/i915/gen9: Initialize intel_state->active_crtcs during WM sanitization (v2)
drm: Reject page_flip for !DRIVER_MODESET
drm/amdgpu: fix timeout value check in amd_sched_job_recovery
drm/amdgpu: fix sdma_v2_4_ring_test_ib
drm/amdgpu: fix amdgpu_move_blit on 32bit systems
drm/radeon: fix radeon_move_blit on 32bit systems
...
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_csr.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 270 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ttm.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/dsi.c | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/host1x/mipi.c | 63 | ||||
-rw-r--r-- | include/linux/host1x.h | 2 |
21 files changed, 424 insertions, 71 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 8c704c86597b..700c56baf2de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -426,6 +426,8 @@ struct amdgpu_mman { | |||
426 | 426 | ||
427 | /* custom LRU management */ | 427 | /* custom LRU management */ |
428 | struct amdgpu_mman_lru log2_size[AMDGPU_TTM_LRU_SIZE]; | 428 | struct amdgpu_mman_lru log2_size[AMDGPU_TTM_LRU_SIZE]; |
429 | /* guard for log2_size array, don't add anything in between */ | ||
430 | struct amdgpu_mman_lru guard; | ||
429 | }; | 431 | }; |
430 | 432 | ||
431 | int amdgpu_copy_buffer(struct amdgpu_ring *ring, | 433 | int amdgpu_copy_buffer(struct amdgpu_ring *ring, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 983175363b06..fe872b82e619 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | |||
@@ -321,6 +321,19 @@ bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device * | |||
321 | (le16_to_cpu(path->usConnObjectId) & | 321 | (le16_to_cpu(path->usConnObjectId) & |
322 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 322 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
323 | 323 | ||
324 | /* Skip TV/CV support */ | ||
325 | if ((le16_to_cpu(path->usDeviceTag) == | ||
326 | ATOM_DEVICE_TV1_SUPPORT) || | ||
327 | (le16_to_cpu(path->usDeviceTag) == | ||
328 | ATOM_DEVICE_CV_SUPPORT)) | ||
329 | continue; | ||
330 | |||
331 | if (con_obj_id >= ARRAY_SIZE(object_connector_convert)) { | ||
332 | DRM_ERROR("invalid con_obj_id %d for device tag 0x%04x\n", | ||
333 | con_obj_id, le16_to_cpu(path->usDeviceTag)); | ||
334 | continue; | ||
335 | } | ||
336 | |||
324 | connector_type = | 337 | connector_type = |
325 | object_connector_convert[con_obj_id]; | 338 | object_connector_convert[con_obj_id]; |
326 | connector_object_id = con_obj_id; | 339 | connector_object_id = con_obj_id; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9b61c8ba7aaf..716f2afeb6a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -251,8 +251,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, | |||
251 | 251 | ||
252 | adev = amdgpu_get_adev(bo->bdev); | 252 | adev = amdgpu_get_adev(bo->bdev); |
253 | ring = adev->mman.buffer_funcs_ring; | 253 | ring = adev->mman.buffer_funcs_ring; |
254 | old_start = old_mem->start << PAGE_SHIFT; | 254 | old_start = (u64)old_mem->start << PAGE_SHIFT; |
255 | new_start = new_mem->start << PAGE_SHIFT; | 255 | new_start = (u64)new_mem->start << PAGE_SHIFT; |
256 | 256 | ||
257 | switch (old_mem->mem_type) { | 257 | switch (old_mem->mem_type) { |
258 | case TTM_PL_VRAM: | 258 | case TTM_PL_VRAM: |
@@ -950,6 +950,8 @@ static struct list_head *amdgpu_ttm_lru_tail(struct ttm_buffer_object *tbo) | |||
950 | struct list_head *res = lru->lru[tbo->mem.mem_type]; | 950 | struct list_head *res = lru->lru[tbo->mem.mem_type]; |
951 | 951 | ||
952 | lru->lru[tbo->mem.mem_type] = &tbo->lru; | 952 | lru->lru[tbo->mem.mem_type] = &tbo->lru; |
953 | while ((++lru)->lru[tbo->mem.mem_type] == res) | ||
954 | lru->lru[tbo->mem.mem_type] = &tbo->lru; | ||
953 | 955 | ||
954 | return res; | 956 | return res; |
955 | } | 957 | } |
@@ -960,6 +962,8 @@ static struct list_head *amdgpu_ttm_swap_lru_tail(struct ttm_buffer_object *tbo) | |||
960 | struct list_head *res = lru->swap_lru; | 962 | struct list_head *res = lru->swap_lru; |
961 | 963 | ||
962 | lru->swap_lru = &tbo->swap; | 964 | lru->swap_lru = &tbo->swap; |
965 | while ((++lru)->swap_lru == res) | ||
966 | lru->swap_lru = &tbo->swap; | ||
963 | 967 | ||
964 | return res; | 968 | return res; |
965 | } | 969 | } |
@@ -1011,6 +1015,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1011 | lru->swap_lru = &adev->mman.bdev.glob->swap_lru; | 1015 | lru->swap_lru = &adev->mman.bdev.glob->swap_lru; |
1012 | } | 1016 | } |
1013 | 1017 | ||
1018 | for (j = 0; j < TTM_NUM_MEM_TYPES; ++j) | ||
1019 | adev->mman.guard.lru[j] = NULL; | ||
1020 | adev->mman.guard.swap_lru = NULL; | ||
1021 | |||
1014 | adev->mman.initialized = true; | 1022 | adev->mman.initialized = true; |
1015 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, | 1023 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, |
1016 | adev->mc.real_vram_size >> PAGE_SHIFT); | 1024 | adev->mc.real_vram_size >> PAGE_SHIFT); |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 1351c7e834a2..a64715d90503 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
@@ -714,7 +714,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
714 | DRM_ERROR("amdgpu: IB test timed out\n"); | 714 | DRM_ERROR("amdgpu: IB test timed out\n"); |
715 | r = -ETIMEDOUT; | 715 | r = -ETIMEDOUT; |
716 | goto err1; | 716 | goto err1; |
717 | } else if (r) { | 717 | } else if (r < 0) { |
718 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | 718 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); |
719 | goto err1; | 719 | goto err1; |
720 | } | 720 | } |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index ef312bb75fda..963a24d46a93 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
@@ -405,7 +405,7 @@ void amd_sched_job_recovery(struct amd_gpu_scheduler *sched) | |||
405 | spin_lock(&sched->job_list_lock); | 405 | spin_lock(&sched->job_list_lock); |
406 | s_job = list_first_entry_or_null(&sched->ring_mirror_list, | 406 | s_job = list_first_entry_or_null(&sched->ring_mirror_list, |
407 | struct amd_sched_job, node); | 407 | struct amd_sched_job, node); |
408 | if (s_job) | 408 | if (s_job && sched->timeout != MAX_SCHEDULE_TIMEOUT) |
409 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); | 409 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); |
410 | 410 | ||
411 | list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) { | 411 | list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) { |
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index fa3930757972..2a3ded44cf2a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -475,7 +475,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
475 | val, | 475 | val, |
476 | -1, | 476 | -1, |
477 | &replaced); | 477 | &replaced); |
478 | state->color_mgmt_changed = replaced; | 478 | state->color_mgmt_changed |= replaced; |
479 | return ret; | 479 | return ret; |
480 | } else if (property == config->ctm_property) { | 480 | } else if (property == config->ctm_property) { |
481 | ret = drm_atomic_replace_property_blob_from_id(crtc, | 481 | ret = drm_atomic_replace_property_blob_from_id(crtc, |
@@ -483,7 +483,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
483 | val, | 483 | val, |
484 | sizeof(struct drm_color_ctm), | 484 | sizeof(struct drm_color_ctm), |
485 | &replaced); | 485 | &replaced); |
486 | state->color_mgmt_changed = replaced; | 486 | state->color_mgmt_changed |= replaced; |
487 | return ret; | 487 | return ret; |
488 | } else if (property == config->gamma_lut_property) { | 488 | } else if (property == config->gamma_lut_property) { |
489 | ret = drm_atomic_replace_property_blob_from_id(crtc, | 489 | ret = drm_atomic_replace_property_blob_from_id(crtc, |
@@ -491,7 +491,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, | |||
491 | val, | 491 | val, |
492 | -1, | 492 | -1, |
493 | &replaced); | 493 | &replaced); |
494 | state->color_mgmt_changed = replaced; | 494 | state->color_mgmt_changed |= replaced; |
495 | return ret; | 495 | return ret; |
496 | } else if (crtc->funcs->atomic_set_property) | 496 | } else if (crtc->funcs->atomic_set_property) |
497 | return crtc->funcs->atomic_set_property(crtc, state, property, val); | 497 | return crtc->funcs->atomic_set_property(crtc, state, property, val); |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index b1dbb60af99f..ddebe54cd5ca 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -5404,6 +5404,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, | |||
5404 | struct drm_pending_vblank_event *e = NULL; | 5404 | struct drm_pending_vblank_event *e = NULL; |
5405 | int ret = -EINVAL; | 5405 | int ret = -EINVAL; |
5406 | 5406 | ||
5407 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
5408 | return -EINVAL; | ||
5409 | |||
5407 | if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || | 5410 | if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || |
5408 | page_flip->reserved != 0) | 5411 | page_flip->reserved != 0) |
5409 | return -EINVAL; | 5412 | return -EINVAL; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 20fe9d52e256..f68c78918d63 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -882,11 +882,12 @@ struct i915_gem_context { | |||
882 | 882 | ||
883 | struct i915_ctx_hang_stats hang_stats; | 883 | struct i915_ctx_hang_stats hang_stats; |
884 | 884 | ||
885 | /* Unique identifier for this context, used by the hw for tracking */ | ||
886 | unsigned long flags; | 885 | unsigned long flags; |
887 | #define CONTEXT_NO_ZEROMAP BIT(0) | 886 | #define CONTEXT_NO_ZEROMAP BIT(0) |
888 | #define CONTEXT_NO_ERROR_CAPTURE BIT(1) | 887 | #define CONTEXT_NO_ERROR_CAPTURE BIT(1) |
889 | unsigned hw_id; | 888 | |
889 | /* Unique identifier for this context, used by the hw for tracking */ | ||
890 | unsigned int hw_id; | ||
890 | u32 user_handle; | 891 | u32 user_handle; |
891 | 892 | ||
892 | u32 ggtt_alignment; | 893 | u32 ggtt_alignment; |
@@ -1963,6 +1964,13 @@ struct drm_i915_private { | |||
1963 | struct i915_suspend_saved_registers regfile; | 1964 | struct i915_suspend_saved_registers regfile; |
1964 | struct vlv_s0ix_state vlv_s0ix_state; | 1965 | struct vlv_s0ix_state vlv_s0ix_state; |
1965 | 1966 | ||
1967 | enum { | ||
1968 | I915_SKL_SAGV_UNKNOWN = 0, | ||
1969 | I915_SKL_SAGV_DISABLED, | ||
1970 | I915_SKL_SAGV_ENABLED, | ||
1971 | I915_SKL_SAGV_NOT_CONTROLLED | ||
1972 | } skl_sagv_status; | ||
1973 | |||
1966 | struct { | 1974 | struct { |
1967 | /* | 1975 | /* |
1968 | * Raw watermark latency values: | 1976 | * Raw watermark latency values: |
@@ -3591,6 +3599,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle); | |||
3591 | /* belongs in i915_gem_gtt.h */ | 3599 | /* belongs in i915_gem_gtt.h */ |
3592 | static inline void i915_gem_chipset_flush(struct drm_i915_private *dev_priv) | 3600 | static inline void i915_gem_chipset_flush(struct drm_i915_private *dev_priv) |
3593 | { | 3601 | { |
3602 | wmb(); | ||
3594 | if (INTEL_GEN(dev_priv) < 6) | 3603 | if (INTEL_GEN(dev_priv) < 6) |
3595 | intel_gtt_chipset_flush(); | 3604 | intel_gtt_chipset_flush(); |
3596 | } | 3605 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 1978633e7549..b35e5b6475b2 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -943,8 +943,6 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, | |||
943 | { | 943 | { |
944 | const unsigned other_rings = ~intel_engine_flag(req->engine); | 944 | const unsigned other_rings = ~intel_engine_flag(req->engine); |
945 | struct i915_vma *vma; | 945 | struct i915_vma *vma; |
946 | uint32_t flush_domains = 0; | ||
947 | bool flush_chipset = false; | ||
948 | int ret; | 946 | int ret; |
949 | 947 | ||
950 | list_for_each_entry(vma, vmas, exec_list) { | 948 | list_for_each_entry(vma, vmas, exec_list) { |
@@ -957,16 +955,11 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req, | |||
957 | } | 955 | } |
958 | 956 | ||
959 | if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) | 957 | if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) |
960 | flush_chipset |= i915_gem_clflush_object(obj, false); | 958 | i915_gem_clflush_object(obj, false); |
961 | |||
962 | flush_domains |= obj->base.write_domain; | ||
963 | } | 959 | } |
964 | 960 | ||
965 | if (flush_chipset) | 961 | /* Unconditionally flush any chipset caches (for streaming writes). */ |
966 | i915_gem_chipset_flush(req->engine->i915); | 962 | i915_gem_chipset_flush(req->engine->i915); |
967 | |||
968 | if (flush_domains & I915_GEM_DOMAIN_GTT) | ||
969 | wmb(); | ||
970 | 963 | ||
971 | /* Unconditionally invalidate gpu caches and ensure that we do flush | 964 | /* Unconditionally invalidate gpu caches and ensure that we do flush |
972 | * any residual writes from the previous batch. | 965 | * any residual writes from the previous batch. |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5c06413ae0e6..bf2cad3f9e1f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -7145,6 +7145,15 @@ enum { | |||
7145 | 7145 | ||
7146 | #define GEN6_PCODE_MAILBOX _MMIO(0x138124) | 7146 | #define GEN6_PCODE_MAILBOX _MMIO(0x138124) |
7147 | #define GEN6_PCODE_READY (1<<31) | 7147 | #define GEN6_PCODE_READY (1<<31) |
7148 | #define GEN6_PCODE_ERROR_MASK 0xFF | ||
7149 | #define GEN6_PCODE_SUCCESS 0x0 | ||
7150 | #define GEN6_PCODE_ILLEGAL_CMD 0x1 | ||
7151 | #define GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x2 | ||
7152 | #define GEN6_PCODE_TIMEOUT 0x3 | ||
7153 | #define GEN6_PCODE_UNIMPLEMENTED_CMD 0xFF | ||
7154 | #define GEN7_PCODE_TIMEOUT 0x2 | ||
7155 | #define GEN7_PCODE_ILLEGAL_DATA 0x3 | ||
7156 | #define GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE 0x10 | ||
7148 | #define GEN6_PCODE_WRITE_RC6VIDS 0x4 | 7157 | #define GEN6_PCODE_WRITE_RC6VIDS 0x4 |
7149 | #define GEN6_PCODE_READ_RC6VIDS 0x5 | 7158 | #define GEN6_PCODE_READ_RC6VIDS 0x5 |
7150 | #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) | 7159 | #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) |
@@ -7166,6 +7175,10 @@ enum { | |||
7166 | #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 | 7175 | #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 |
7167 | #define DISPLAY_IPS_CONTROL 0x19 | 7176 | #define DISPLAY_IPS_CONTROL 0x19 |
7168 | #define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A | 7177 | #define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A |
7178 | #define GEN9_PCODE_SAGV_CONTROL 0x21 | ||
7179 | #define GEN9_SAGV_DISABLE 0x0 | ||
7180 | #define GEN9_SAGV_IS_DISABLED 0x1 | ||
7181 | #define GEN9_SAGV_ENABLE 0x3 | ||
7169 | #define GEN6_PCODE_DATA _MMIO(0x138128) | 7182 | #define GEN6_PCODE_DATA _MMIO(0x138128) |
7170 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 | 7183 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 |
7171 | #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 | 7184 | #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 3edb9580928e..c3b33a10c15c 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
@@ -41,15 +41,15 @@ | |||
41 | * be moved to FW_FAILED. | 41 | * be moved to FW_FAILED. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #define I915_CSR_KBL "i915/kbl_dmc_ver1.bin" | 44 | #define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin" |
45 | MODULE_FIRMWARE(I915_CSR_KBL); | 45 | MODULE_FIRMWARE(I915_CSR_KBL); |
46 | #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 1) | 46 | #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 1) |
47 | 47 | ||
48 | #define I915_CSR_SKL "i915/skl_dmc_ver1.bin" | 48 | #define I915_CSR_SKL "i915/skl_dmc_ver1_26.bin" |
49 | MODULE_FIRMWARE(I915_CSR_SKL); | 49 | MODULE_FIRMWARE(I915_CSR_SKL); |
50 | #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 23) | 50 | #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 26) |
51 | 51 | ||
52 | #define I915_CSR_BXT "i915/bxt_dmc_ver1.bin" | 52 | #define I915_CSR_BXT "i915/bxt_dmc_ver1_07.bin" |
53 | MODULE_FIRMWARE(I915_CSR_BXT); | 53 | MODULE_FIRMWARE(I915_CSR_BXT); |
54 | #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) | 54 | #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) |
55 | 55 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2a751b6e0253..175595fc3e45 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -13759,6 +13759,13 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
13759 | intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)) | 13759 | intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)) |
13760 | dev_priv->display.modeset_commit_cdclk(state); | 13760 | dev_priv->display.modeset_commit_cdclk(state); |
13761 | 13761 | ||
13762 | /* | ||
13763 | * SKL workaround: bspec recommends we disable the SAGV when we | ||
13764 | * have more then one pipe enabled | ||
13765 | */ | ||
13766 | if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state)) | ||
13767 | skl_disable_sagv(dev_priv); | ||
13768 | |||
13762 | intel_modeset_verify_disabled(dev); | 13769 | intel_modeset_verify_disabled(dev); |
13763 | } | 13770 | } |
13764 | 13771 | ||
@@ -13832,6 +13839,10 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
13832 | intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); | 13839 | intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); |
13833 | } | 13840 | } |
13834 | 13841 | ||
13842 | if (IS_SKYLAKE(dev_priv) && intel_state->modeset && | ||
13843 | skl_can_enable_sagv(state)) | ||
13844 | skl_enable_sagv(dev_priv); | ||
13845 | |||
13835 | drm_atomic_helper_commit_hw_done(state); | 13846 | drm_atomic_helper_commit_hw_done(state); |
13836 | 13847 | ||
13837 | if (intel_state->modeset) | 13848 | if (intel_state->modeset) |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cc937a19b1ba..ff399b9a5c1f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -1716,6 +1716,9 @@ void ilk_wm_get_hw_state(struct drm_device *dev); | |||
1716 | void skl_wm_get_hw_state(struct drm_device *dev); | 1716 | void skl_wm_get_hw_state(struct drm_device *dev); |
1717 | void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, | 1717 | void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, |
1718 | struct skl_ddb_allocation *ddb /* out */); | 1718 | struct skl_ddb_allocation *ddb /* out */); |
1719 | bool skl_can_enable_sagv(struct drm_atomic_state *state); | ||
1720 | int skl_enable_sagv(struct drm_i915_private *dev_priv); | ||
1721 | int skl_disable_sagv(struct drm_i915_private *dev_priv); | ||
1719 | uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); | 1722 | uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); |
1720 | bool ilk_disable_lp_wm(struct drm_device *dev); | 1723 | bool ilk_disable_lp_wm(struct drm_device *dev); |
1721 | int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); | 1724 | int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6); |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d5deb58a2128..53e13c10e4ea 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2852,6 +2852,7 @@ bool ilk_disable_lp_wm(struct drm_device *dev) | |||
2852 | 2852 | ||
2853 | #define SKL_DDB_SIZE 896 /* in blocks */ | 2853 | #define SKL_DDB_SIZE 896 /* in blocks */ |
2854 | #define BXT_DDB_SIZE 512 | 2854 | #define BXT_DDB_SIZE 512 |
2855 | #define SKL_SAGV_BLOCK_TIME 30 /* µs */ | ||
2855 | 2856 | ||
2856 | /* | 2857 | /* |
2857 | * Return the index of a plane in the SKL DDB and wm result arrays. Primary | 2858 | * Return the index of a plane in the SKL DDB and wm result arrays. Primary |
@@ -2875,6 +2876,153 @@ skl_wm_plane_id(const struct intel_plane *plane) | |||
2875 | } | 2876 | } |
2876 | } | 2877 | } |
2877 | 2878 | ||
2879 | /* | ||
2880 | * SAGV dynamically adjusts the system agent voltage and clock frequencies | ||
2881 | * depending on power and performance requirements. The display engine access | ||
2882 | * to system memory is blocked during the adjustment time. Because of the | ||
2883 | * blocking time, having this enabled can cause full system hangs and/or pipe | ||
2884 | * underruns if we don't meet all of the following requirements: | ||
2885 | * | ||
2886 | * - <= 1 pipe enabled | ||
2887 | * - All planes can enable watermarks for latencies >= SAGV engine block time | ||
2888 | * - We're not using an interlaced display configuration | ||
2889 | */ | ||
2890 | int | ||
2891 | skl_enable_sagv(struct drm_i915_private *dev_priv) | ||
2892 | { | ||
2893 | int ret; | ||
2894 | |||
2895 | if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || | ||
2896 | dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED) | ||
2897 | return 0; | ||
2898 | |||
2899 | DRM_DEBUG_KMS("Enabling the SAGV\n"); | ||
2900 | mutex_lock(&dev_priv->rps.hw_lock); | ||
2901 | |||
2902 | ret = sandybridge_pcode_write(dev_priv, GEN9_PCODE_SAGV_CONTROL, | ||
2903 | GEN9_SAGV_ENABLE); | ||
2904 | |||
2905 | /* We don't need to wait for the SAGV when enabling */ | ||
2906 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
2907 | |||
2908 | /* | ||
2909 | * Some skl systems, pre-release machines in particular, | ||
2910 | * don't actually have an SAGV. | ||
2911 | */ | ||
2912 | if (ret == -ENXIO) { | ||
2913 | DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); | ||
2914 | dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; | ||
2915 | return 0; | ||
2916 | } else if (ret < 0) { | ||
2917 | DRM_ERROR("Failed to enable the SAGV\n"); | ||
2918 | return ret; | ||
2919 | } | ||
2920 | |||
2921 | dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED; | ||
2922 | return 0; | ||
2923 | } | ||
2924 | |||
2925 | static int | ||
2926 | skl_do_sagv_disable(struct drm_i915_private *dev_priv) | ||
2927 | { | ||
2928 | int ret; | ||
2929 | uint32_t temp = GEN9_SAGV_DISABLE; | ||
2930 | |||
2931 | ret = sandybridge_pcode_read(dev_priv, GEN9_PCODE_SAGV_CONTROL, | ||
2932 | &temp); | ||
2933 | if (ret) | ||
2934 | return ret; | ||
2935 | else | ||
2936 | return temp & GEN9_SAGV_IS_DISABLED; | ||
2937 | } | ||
2938 | |||
2939 | int | ||
2940 | skl_disable_sagv(struct drm_i915_private *dev_priv) | ||
2941 | { | ||
2942 | int ret, result; | ||
2943 | |||
2944 | if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED || | ||
2945 | dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED) | ||
2946 | return 0; | ||
2947 | |||
2948 | DRM_DEBUG_KMS("Disabling the SAGV\n"); | ||
2949 | mutex_lock(&dev_priv->rps.hw_lock); | ||
2950 | |||
2951 | /* bspec says to keep retrying for at least 1 ms */ | ||
2952 | ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1); | ||
2953 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
2954 | |||
2955 | if (ret == -ETIMEDOUT) { | ||
2956 | DRM_ERROR("Request to disable SAGV timed out\n"); | ||
2957 | return -ETIMEDOUT; | ||
2958 | } | ||
2959 | |||
2960 | /* | ||
2961 | * Some skl systems, pre-release machines in particular, | ||
2962 | * don't actually have an SAGV. | ||
2963 | */ | ||
2964 | if (result == -ENXIO) { | ||
2965 | DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n"); | ||
2966 | dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED; | ||
2967 | return 0; | ||
2968 | } else if (result < 0) { | ||
2969 | DRM_ERROR("Failed to disable the SAGV\n"); | ||
2970 | return result; | ||
2971 | } | ||
2972 | |||
2973 | dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED; | ||
2974 | return 0; | ||
2975 | } | ||
2976 | |||
2977 | bool skl_can_enable_sagv(struct drm_atomic_state *state) | ||
2978 | { | ||
2979 | struct drm_device *dev = state->dev; | ||
2980 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2981 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); | ||
2982 | struct drm_crtc *crtc; | ||
2983 | enum pipe pipe; | ||
2984 | int level, plane; | ||
2985 | |||
2986 | /* | ||
2987 | * SKL workaround: bspec recommends we disable the SAGV when we have | ||
2988 | * more then one pipe enabled | ||
2989 | * | ||
2990 | * If there are no active CRTCs, no additional checks need be performed | ||
2991 | */ | ||
2992 | if (hweight32(intel_state->active_crtcs) == 0) | ||
2993 | return true; | ||
2994 | else if (hweight32(intel_state->active_crtcs) > 1) | ||
2995 | return false; | ||
2996 | |||
2997 | /* Since we're now guaranteed to only have one active CRTC... */ | ||
2998 | pipe = ffs(intel_state->active_crtcs) - 1; | ||
2999 | crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
3000 | |||
3001 | if (crtc->state->mode.flags & DRM_MODE_FLAG_INTERLACE) | ||
3002 | return false; | ||
3003 | |||
3004 | for_each_plane(dev_priv, pipe, plane) { | ||
3005 | /* Skip this plane if it's not enabled */ | ||
3006 | if (intel_state->wm_results.plane[pipe][plane][0] == 0) | ||
3007 | continue; | ||
3008 | |||
3009 | /* Find the highest enabled wm level for this plane */ | ||
3010 | for (level = ilk_wm_max_level(dev); | ||
3011 | intel_state->wm_results.plane[pipe][plane][level] == 0; --level) | ||
3012 | { } | ||
3013 | |||
3014 | /* | ||
3015 | * If any of the planes on this pipe don't enable wm levels | ||
3016 | * that incur memory latencies higher then 30µs we can't enable | ||
3017 | * the SAGV | ||
3018 | */ | ||
3019 | if (dev_priv->wm.skl_latency[level] < SKL_SAGV_BLOCK_TIME) | ||
3020 | return false; | ||
3021 | } | ||
3022 | |||
3023 | return true; | ||
3024 | } | ||
3025 | |||
2878 | static void | 3026 | static void |
2879 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, | 3027 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
2880 | const struct intel_crtc_state *cstate, | 3028 | const struct intel_crtc_state *cstate, |
@@ -3107,8 +3255,6 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate) | |||
3107 | total_data_rate += intel_cstate->wm.skl.plane_y_data_rate[id]; | 3255 | total_data_rate += intel_cstate->wm.skl.plane_y_data_rate[id]; |
3108 | } | 3256 | } |
3109 | 3257 | ||
3110 | WARN_ON(cstate->plane_mask && total_data_rate == 0); | ||
3111 | |||
3112 | return total_data_rate; | 3258 | return total_data_rate; |
3113 | } | 3259 | } |
3114 | 3260 | ||
@@ -3912,9 +4058,24 @@ skl_compute_ddb(struct drm_atomic_state *state) | |||
3912 | * pretend that all pipes switched active status so that we'll | 4058 | * pretend that all pipes switched active status so that we'll |
3913 | * ensure a full DDB recompute. | 4059 | * ensure a full DDB recompute. |
3914 | */ | 4060 | */ |
3915 | if (dev_priv->wm.distrust_bios_wm) | 4061 | if (dev_priv->wm.distrust_bios_wm) { |
4062 | ret = drm_modeset_lock(&dev->mode_config.connection_mutex, | ||
4063 | state->acquire_ctx); | ||
4064 | if (ret) | ||
4065 | return ret; | ||
4066 | |||
3916 | intel_state->active_pipe_changes = ~0; | 4067 | intel_state->active_pipe_changes = ~0; |
3917 | 4068 | ||
4069 | /* | ||
4070 | * We usually only initialize intel_state->active_crtcs if we | ||
4071 | * we're doing a modeset; make sure this field is always | ||
4072 | * initialized during the sanitization process that happens | ||
4073 | * on the first commit too. | ||
4074 | */ | ||
4075 | if (!intel_state->modeset) | ||
4076 | intel_state->active_crtcs = dev_priv->active_crtcs; | ||
4077 | } | ||
4078 | |||
3918 | /* | 4079 | /* |
3919 | * If the modeset changes which CRTC's are active, we need to | 4080 | * If the modeset changes which CRTC's are active, we need to |
3920 | * recompute the DDB allocation for *all* active pipes, even | 4081 | * recompute the DDB allocation for *all* active pipes, even |
@@ -3943,11 +4104,33 @@ skl_compute_ddb(struct drm_atomic_state *state) | |||
3943 | ret = skl_allocate_pipe_ddb(cstate, ddb); | 4104 | ret = skl_allocate_pipe_ddb(cstate, ddb); |
3944 | if (ret) | 4105 | if (ret) |
3945 | return ret; | 4106 | return ret; |
4107 | |||
4108 | ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); | ||
4109 | if (ret) | ||
4110 | return ret; | ||
3946 | } | 4111 | } |
3947 | 4112 | ||
3948 | return 0; | 4113 | return 0; |
3949 | } | 4114 | } |
3950 | 4115 | ||
4116 | static void | ||
4117 | skl_copy_wm_for_pipe(struct skl_wm_values *dst, | ||
4118 | struct skl_wm_values *src, | ||
4119 | enum pipe pipe) | ||
4120 | { | ||
4121 | dst->wm_linetime[pipe] = src->wm_linetime[pipe]; | ||
4122 | memcpy(dst->plane[pipe], src->plane[pipe], | ||
4123 | sizeof(dst->plane[pipe])); | ||
4124 | memcpy(dst->plane_trans[pipe], src->plane_trans[pipe], | ||
4125 | sizeof(dst->plane_trans[pipe])); | ||
4126 | |||
4127 | dst->ddb.pipe[pipe] = src->ddb.pipe[pipe]; | ||
4128 | memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe], | ||
4129 | sizeof(dst->ddb.y_plane[pipe])); | ||
4130 | memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe], | ||
4131 | sizeof(dst->ddb.plane[pipe])); | ||
4132 | } | ||
4133 | |||
3951 | static int | 4134 | static int |
3952 | skl_compute_wm(struct drm_atomic_state *state) | 4135 | skl_compute_wm(struct drm_atomic_state *state) |
3953 | { | 4136 | { |
@@ -4020,8 +4203,10 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
4020 | struct drm_device *dev = crtc->dev; | 4203 | struct drm_device *dev = crtc->dev; |
4021 | struct drm_i915_private *dev_priv = to_i915(dev); | 4204 | struct drm_i915_private *dev_priv = to_i915(dev); |
4022 | struct skl_wm_values *results = &dev_priv->wm.skl_results; | 4205 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
4206 | struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw; | ||
4023 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | 4207 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
4024 | struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; | 4208 | struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; |
4209 | int pipe; | ||
4025 | 4210 | ||
4026 | if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) | 4211 | if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) |
4027 | return; | 4212 | return; |
@@ -4033,8 +4218,12 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
4033 | skl_write_wm_values(dev_priv, results); | 4218 | skl_write_wm_values(dev_priv, results); |
4034 | skl_flush_wm_values(dev_priv, results); | 4219 | skl_flush_wm_values(dev_priv, results); |
4035 | 4220 | ||
4036 | /* store the new configuration */ | 4221 | /* |
4037 | dev_priv->wm.skl_hw = *results; | 4222 | * Store the new configuration (but only for the pipes that have |
4223 | * changed; the other values weren't recomputed). | ||
4224 | */ | ||
4225 | for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes) | ||
4226 | skl_copy_wm_for_pipe(hw_vals, results, pipe); | ||
4038 | 4227 | ||
4039 | mutex_unlock(&dev_priv->wm.wm_mutex); | 4228 | mutex_unlock(&dev_priv->wm.wm_mutex); |
4040 | } | 4229 | } |
@@ -7658,8 +7847,53 @@ void intel_init_pm(struct drm_device *dev) | |||
7658 | } | 7847 | } |
7659 | } | 7848 | } |
7660 | 7849 | ||
7850 | static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv) | ||
7851 | { | ||
7852 | uint32_t flags = | ||
7853 | I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK; | ||
7854 | |||
7855 | switch (flags) { | ||
7856 | case GEN6_PCODE_SUCCESS: | ||
7857 | return 0; | ||
7858 | case GEN6_PCODE_UNIMPLEMENTED_CMD: | ||
7859 | case GEN6_PCODE_ILLEGAL_CMD: | ||
7860 | return -ENXIO; | ||
7861 | case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: | ||
7862 | return -EOVERFLOW; | ||
7863 | case GEN6_PCODE_TIMEOUT: | ||
7864 | return -ETIMEDOUT; | ||
7865 | default: | ||
7866 | MISSING_CASE(flags) | ||
7867 | return 0; | ||
7868 | } | ||
7869 | } | ||
7870 | |||
7871 | static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv) | ||
7872 | { | ||
7873 | uint32_t flags = | ||
7874 | I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK; | ||
7875 | |||
7876 | switch (flags) { | ||
7877 | case GEN6_PCODE_SUCCESS: | ||
7878 | return 0; | ||
7879 | case GEN6_PCODE_ILLEGAL_CMD: | ||
7880 | return -ENXIO; | ||
7881 | case GEN7_PCODE_TIMEOUT: | ||
7882 | return -ETIMEDOUT; | ||
7883 | case GEN7_PCODE_ILLEGAL_DATA: | ||
7884 | return -EINVAL; | ||
7885 | case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE: | ||
7886 | return -EOVERFLOW; | ||
7887 | default: | ||
7888 | MISSING_CASE(flags); | ||
7889 | return 0; | ||
7890 | } | ||
7891 | } | ||
7892 | |||
7661 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val) | 7893 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val) |
7662 | { | 7894 | { |
7895 | int status; | ||
7896 | |||
7663 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | 7897 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
7664 | 7898 | ||
7665 | /* GEN6_PCODE_* are outside of the forcewake domain, we can | 7899 | /* GEN6_PCODE_* are outside of the forcewake domain, we can |
@@ -7686,12 +7920,25 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val | |||
7686 | *val = I915_READ_FW(GEN6_PCODE_DATA); | 7920 | *val = I915_READ_FW(GEN6_PCODE_DATA); |
7687 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); | 7921 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); |
7688 | 7922 | ||
7923 | if (INTEL_GEN(dev_priv) > 6) | ||
7924 | status = gen7_check_mailbox_status(dev_priv); | ||
7925 | else | ||
7926 | status = gen6_check_mailbox_status(dev_priv); | ||
7927 | |||
7928 | if (status) { | ||
7929 | DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed: %d\n", | ||
7930 | status); | ||
7931 | return status; | ||
7932 | } | ||
7933 | |||
7689 | return 0; | 7934 | return 0; |
7690 | } | 7935 | } |
7691 | 7936 | ||
7692 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, | 7937 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, |
7693 | u32 mbox, u32 val) | 7938 | u32 mbox, u32 val) |
7694 | { | 7939 | { |
7940 | int status; | ||
7941 | |||
7695 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | 7942 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
7696 | 7943 | ||
7697 | /* GEN6_PCODE_* are outside of the forcewake domain, we can | 7944 | /* GEN6_PCODE_* are outside of the forcewake domain, we can |
@@ -7716,6 +7963,17 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, | |||
7716 | 7963 | ||
7717 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); | 7964 | I915_WRITE_FW(GEN6_PCODE_DATA, 0); |
7718 | 7965 | ||
7966 | if (INTEL_GEN(dev_priv) > 6) | ||
7967 | status = gen7_check_mailbox_status(dev_priv); | ||
7968 | else | ||
7969 | status = gen6_check_mailbox_status(dev_priv); | ||
7970 | |||
7971 | if (status) { | ||
7972 | DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed: %d\n", | ||
7973 | status); | ||
7974 | return status; | ||
7975 | } | ||
7976 | |||
7719 | return 0; | 7977 | return 0; |
7720 | } | 7978 | } |
7721 | 7979 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index df2657051afd..28c1423049c5 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c | |||
@@ -73,10 +73,12 @@ static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, | |||
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | ||
76 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
76 | static struct fb_deferred_io qxl_defio = { | 77 | static struct fb_deferred_io qxl_defio = { |
77 | .delay = QXL_DIRTY_DELAY, | 78 | .delay = QXL_DIRTY_DELAY, |
78 | .deferred_io = drm_fb_helper_deferred_io, | 79 | .deferred_io = drm_fb_helper_deferred_io, |
79 | }; | 80 | }; |
81 | #endif | ||
80 | 82 | ||
81 | static struct fb_ops qxlfb_ops = { | 83 | static struct fb_ops qxlfb_ops = { |
82 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
@@ -313,8 +315,10 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, | |||
313 | goto out_destroy_fbi; | 315 | goto out_destroy_fbi; |
314 | } | 316 | } |
315 | 317 | ||
318 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
316 | info->fbdefio = &qxl_defio; | 319 | info->fbdefio = &qxl_defio; |
317 | fb_deferred_io_init(info); | 320 | fb_deferred_io_init(info); |
321 | #endif | ||
318 | 322 | ||
319 | qdev->fbdev_info = info; | 323 | qdev->fbdev_info = info; |
320 | qdev->fbdev_qfb = &qfbdev->qfb; | 324 | qdev->fbdev_qfb = &qfbdev->qfb; |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a97abc8af657..1dcf39084555 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -627,7 +627,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
627 | if (radeon_crtc->ss.refdiv) { | 627 | if (radeon_crtc->ss.refdiv) { |
628 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; | 628 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
629 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; | 629 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; |
630 | if (rdev->family >= CHIP_RV770) | 630 | if (ASIC_IS_AVIVO(rdev) && |
631 | rdev->family != CHIP_RS780 && | ||
632 | rdev->family != CHIP_RS880) | ||
631 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 633 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
632 | } | 634 | } |
633 | } | 635 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 0c00e192c845..c2e0a1ccdfbc 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -263,8 +263,8 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, | |||
263 | 263 | ||
264 | rdev = radeon_get_rdev(bo->bdev); | 264 | rdev = radeon_get_rdev(bo->bdev); |
265 | ridx = radeon_copy_ring_index(rdev); | 265 | ridx = radeon_copy_ring_index(rdev); |
266 | old_start = old_mem->start << PAGE_SHIFT; | 266 | old_start = (u64)old_mem->start << PAGE_SHIFT; |
267 | new_start = new_mem->start << PAGE_SHIFT; | 267 | new_start = (u64)new_mem->start << PAGE_SHIFT; |
268 | 268 | ||
269 | switch (old_mem->mem_type) { | 269 | switch (old_mem->mem_type) { |
270 | case TTM_PL_VRAM: | 270 | case TTM_PL_VRAM: |
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 3d228ad90e0f..3dea1216bafd 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
@@ -840,6 +840,21 @@ static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = { | |||
840 | .destroy = tegra_output_encoder_destroy, | 840 | .destroy = tegra_output_encoder_destroy, |
841 | }; | 841 | }; |
842 | 842 | ||
843 | static void tegra_dsi_unprepare(struct tegra_dsi *dsi) | ||
844 | { | ||
845 | int err; | ||
846 | |||
847 | if (dsi->slave) | ||
848 | tegra_dsi_unprepare(dsi->slave); | ||
849 | |||
850 | err = tegra_mipi_disable(dsi->mipi); | ||
851 | if (err < 0) | ||
852 | dev_err(dsi->dev, "failed to disable MIPI calibration: %d\n", | ||
853 | err); | ||
854 | |||
855 | pm_runtime_put(dsi->dev); | ||
856 | } | ||
857 | |||
843 | static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) | 858 | static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) |
844 | { | 859 | { |
845 | struct tegra_output *output = encoder_to_output(encoder); | 860 | struct tegra_output *output = encoder_to_output(encoder); |
@@ -876,7 +891,26 @@ static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) | |||
876 | 891 | ||
877 | tegra_dsi_disable(dsi); | 892 | tegra_dsi_disable(dsi); |
878 | 893 | ||
879 | pm_runtime_put(dsi->dev); | 894 | tegra_dsi_unprepare(dsi); |
895 | } | ||
896 | |||
897 | static void tegra_dsi_prepare(struct tegra_dsi *dsi) | ||
898 | { | ||
899 | int err; | ||
900 | |||
901 | pm_runtime_get_sync(dsi->dev); | ||
902 | |||
903 | err = tegra_mipi_enable(dsi->mipi); | ||
904 | if (err < 0) | ||
905 | dev_err(dsi->dev, "failed to enable MIPI calibration: %d\n", | ||
906 | err); | ||
907 | |||
908 | err = tegra_dsi_pad_calibrate(dsi); | ||
909 | if (err < 0) | ||
910 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
911 | |||
912 | if (dsi->slave) | ||
913 | tegra_dsi_prepare(dsi->slave); | ||
880 | } | 914 | } |
881 | 915 | ||
882 | static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) | 916 | static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) |
@@ -887,13 +921,8 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) | |||
887 | struct tegra_dsi *dsi = to_dsi(output); | 921 | struct tegra_dsi *dsi = to_dsi(output); |
888 | struct tegra_dsi_state *state; | 922 | struct tegra_dsi_state *state; |
889 | u32 value; | 923 | u32 value; |
890 | int err; | ||
891 | |||
892 | pm_runtime_get_sync(dsi->dev); | ||
893 | 924 | ||
894 | err = tegra_dsi_pad_calibrate(dsi); | 925 | tegra_dsi_prepare(dsi); |
895 | if (err < 0) | ||
896 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
897 | 926 | ||
898 | state = tegra_dsi_get_state(dsi); | 927 | state = tegra_dsi_get_state(dsi); |
899 | 928 | ||
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index d5df555aeba0..9688bfa92ccd 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c | |||
@@ -203,6 +203,7 @@ static int udl_fb_open(struct fb_info *info, int user) | |||
203 | 203 | ||
204 | ufbdev->fb_count++; | 204 | ufbdev->fb_count++; |
205 | 205 | ||
206 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
206 | if (fb_defio && (info->fbdefio == NULL)) { | 207 | if (fb_defio && (info->fbdefio == NULL)) { |
207 | /* enable defio at last moment if not disabled by client */ | 208 | /* enable defio at last moment if not disabled by client */ |
208 | 209 | ||
@@ -218,6 +219,7 @@ static int udl_fb_open(struct fb_info *info, int user) | |||
218 | info->fbdefio = fbdefio; | 219 | info->fbdefio = fbdefio; |
219 | fb_deferred_io_init(info); | 220 | fb_deferred_io_init(info); |
220 | } | 221 | } |
222 | #endif | ||
221 | 223 | ||
222 | pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n", | 224 | pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n", |
223 | info->node, user, info, ufbdev->fb_count); | 225 | info->node, user, info, ufbdev->fb_count); |
@@ -235,12 +237,14 @@ static int udl_fb_release(struct fb_info *info, int user) | |||
235 | 237 | ||
236 | ufbdev->fb_count--; | 238 | ufbdev->fb_count--; |
237 | 239 | ||
240 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
238 | if ((ufbdev->fb_count == 0) && (info->fbdefio)) { | 241 | if ((ufbdev->fb_count == 0) && (info->fbdefio)) { |
239 | fb_deferred_io_cleanup(info); | 242 | fb_deferred_io_cleanup(info); |
240 | kfree(info->fbdefio); | 243 | kfree(info->fbdefio); |
241 | info->fbdefio = NULL; | 244 | info->fbdefio = NULL; |
242 | info->fbops->fb_mmap = udl_fb_mmap; | 245 | info->fbops->fb_mmap = udl_fb_mmap; |
243 | } | 246 | } |
247 | #endif | ||
244 | 248 | ||
245 | pr_warn("released /dev/fb%d user=%d count=%d\n", | 249 | pr_warn("released /dev/fb%d user=%d count=%d\n", |
246 | info->node, user, ufbdev->fb_count); | 250 | info->node, user, ufbdev->fb_count); |
diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index 52a6fd224127..e00809d996a2 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c | |||
@@ -242,20 +242,6 @@ struct tegra_mipi_device *tegra_mipi_request(struct device *device) | |||
242 | dev->pads = args.args[0]; | 242 | dev->pads = args.args[0]; |
243 | dev->device = device; | 243 | dev->device = device; |
244 | 244 | ||
245 | mutex_lock(&dev->mipi->lock); | ||
246 | |||
247 | if (dev->mipi->usage_count++ == 0) { | ||
248 | err = tegra_mipi_power_up(dev->mipi); | ||
249 | if (err < 0) { | ||
250 | dev_err(dev->mipi->dev, | ||
251 | "failed to power up MIPI bricks: %d\n", | ||
252 | err); | ||
253 | return ERR_PTR(err); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | mutex_unlock(&dev->mipi->lock); | ||
258 | |||
259 | return dev; | 245 | return dev; |
260 | 246 | ||
261 | put: | 247 | put: |
@@ -270,29 +256,42 @@ EXPORT_SYMBOL(tegra_mipi_request); | |||
270 | 256 | ||
271 | void tegra_mipi_free(struct tegra_mipi_device *device) | 257 | void tegra_mipi_free(struct tegra_mipi_device *device) |
272 | { | 258 | { |
273 | int err; | 259 | platform_device_put(device->pdev); |
260 | kfree(device); | ||
261 | } | ||
262 | EXPORT_SYMBOL(tegra_mipi_free); | ||
274 | 263 | ||
275 | mutex_lock(&device->mipi->lock); | 264 | int tegra_mipi_enable(struct tegra_mipi_device *dev) |
265 | { | ||
266 | int err = 0; | ||
276 | 267 | ||
277 | if (--device->mipi->usage_count == 0) { | 268 | mutex_lock(&dev->mipi->lock); |
278 | err = tegra_mipi_power_down(device->mipi); | ||
279 | if (err < 0) { | ||
280 | /* | ||
281 | * Not much that can be done here, so an error message | ||
282 | * will have to do. | ||
283 | */ | ||
284 | dev_err(device->mipi->dev, | ||
285 | "failed to power down MIPI bricks: %d\n", | ||
286 | err); | ||
287 | } | ||
288 | } | ||
289 | 269 | ||
290 | mutex_unlock(&device->mipi->lock); | 270 | if (dev->mipi->usage_count++ == 0) |
271 | err = tegra_mipi_power_up(dev->mipi); | ||
272 | |||
273 | mutex_unlock(&dev->mipi->lock); | ||
274 | |||
275 | return err; | ||
291 | 276 | ||
292 | platform_device_put(device->pdev); | ||
293 | kfree(device); | ||
294 | } | 277 | } |
295 | EXPORT_SYMBOL(tegra_mipi_free); | 278 | EXPORT_SYMBOL(tegra_mipi_enable); |
279 | |||
280 | int tegra_mipi_disable(struct tegra_mipi_device *dev) | ||
281 | { | ||
282 | int err = 0; | ||
283 | |||
284 | mutex_lock(&dev->mipi->lock); | ||
285 | |||
286 | if (--dev->mipi->usage_count == 0) | ||
287 | err = tegra_mipi_power_down(dev->mipi); | ||
288 | |||
289 | mutex_unlock(&dev->mipi->lock); | ||
290 | |||
291 | return err; | ||
292 | |||
293 | } | ||
294 | EXPORT_SYMBOL(tegra_mipi_disable); | ||
296 | 295 | ||
297 | static int tegra_mipi_wait(struct tegra_mipi *mipi) | 296 | static int tegra_mipi_wait(struct tegra_mipi *mipi) |
298 | { | 297 | { |
diff --git a/include/linux/host1x.h b/include/linux/host1x.h index d2ba7d334039..1ffbf2a8cb99 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h | |||
@@ -304,6 +304,8 @@ struct tegra_mipi_device; | |||
304 | 304 | ||
305 | struct tegra_mipi_device *tegra_mipi_request(struct device *device); | 305 | struct tegra_mipi_device *tegra_mipi_request(struct device *device); |
306 | void tegra_mipi_free(struct tegra_mipi_device *device); | 306 | void tegra_mipi_free(struct tegra_mipi_device *device); |
307 | int tegra_mipi_enable(struct tegra_mipi_device *device); | ||
308 | int tegra_mipi_disable(struct tegra_mipi_device *device); | ||
307 | int tegra_mipi_calibrate(struct tegra_mipi_device *device); | 309 | int tegra_mipi_calibrate(struct tegra_mipi_device *device); |
308 | 310 | ||
309 | #endif | 311 | #endif |