diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-05-05 03:57:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-05-05 03:57:27 -0400 |
commit | e8c8ce54807b19e90ac84e609b13f7d4e337eab1 (patch) | |
tree | ae7d65ae17d55aee197b605ce1a193fe594af614 /drivers/gpu | |
parent | 5db4298133d99b3dfc60d6899ac9df169769c899 (diff) | |
parent | 04974df8049fc4240d22759a91e035082ccd18b4 (diff) |
Merge tag 'v4.6-rc6' into locking/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/gpu')
83 files changed, 920 insertions, 354 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c4a21c6428f5..1bcbade479dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1591,6 +1591,8 @@ struct amdgpu_uvd { | |||
1591 | struct amdgpu_bo *vcpu_bo; | 1591 | struct amdgpu_bo *vcpu_bo; |
1592 | void *cpu_addr; | 1592 | void *cpu_addr; |
1593 | uint64_t gpu_addr; | 1593 | uint64_t gpu_addr; |
1594 | unsigned fw_version; | ||
1595 | void *saved_bo; | ||
1594 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; | 1596 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; |
1595 | struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; | 1597 | struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; |
1596 | struct delayed_work idle_work; | 1598 | struct delayed_work idle_work; |
@@ -2033,6 +2035,7 @@ struct amdgpu_device { | |||
2033 | 2035 | ||
2034 | /* tracking pinned memory */ | 2036 | /* tracking pinned memory */ |
2035 | u64 vram_pin_size; | 2037 | u64 vram_pin_size; |
2038 | u64 invisible_pin_size; | ||
2036 | u64 gart_pin_size; | 2039 | u64 gart_pin_size; |
2037 | 2040 | ||
2038 | /* amdkfd interface */ | 2041 | /* amdkfd interface */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index d6b0bff510aa..b7b583c42ea8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | |||
@@ -425,6 +425,10 @@ static int acp_resume(void *handle) | |||
425 | struct acp_pm_domain *apd; | 425 | struct acp_pm_domain *apd; |
426 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 426 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
427 | 427 | ||
428 | /* return early if no ACP */ | ||
429 | if (!adev->acp.acp_genpd) | ||
430 | return 0; | ||
431 | |||
428 | /* SMU block will power on ACP irrespective of ACP runtime status. | 432 | /* SMU block will power on ACP irrespective of ACP runtime status. |
429 | * Power off explicitly based on genpd ACP runtime status so that ACP | 433 | * Power off explicitly based on genpd ACP runtime status so that ACP |
430 | * hw and ACP-genpd status are in sync. | 434 | * hw and ACP-genpd status are in sync. |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 0020a0ea43ff..35a1248aaa77 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | |||
@@ -63,10 +63,6 @@ bool amdgpu_has_atpx(void) { | |||
63 | return amdgpu_atpx_priv.atpx_detected; | 63 | return amdgpu_atpx_priv.atpx_detected; |
64 | } | 64 | } |
65 | 65 | ||
66 | bool amdgpu_has_atpx_dgpu_power_cntl(void) { | ||
67 | return amdgpu_atpx_priv.atpx.functions.power_cntl; | ||
68 | } | ||
69 | |||
70 | /** | 66 | /** |
71 | * amdgpu_atpx_call - call an ATPX method | 67 | * amdgpu_atpx_call - call an ATPX method |
72 | * | 68 | * |
@@ -146,6 +142,13 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas | |||
146 | */ | 142 | */ |
147 | static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) | 143 | static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) |
148 | { | 144 | { |
145 | /* make sure required functions are enabled */ | ||
146 | /* dGPU power control is required */ | ||
147 | if (atpx->functions.power_cntl == false) { | ||
148 | printk("ATPX dGPU power cntl not present, forcing\n"); | ||
149 | atpx->functions.power_cntl = true; | ||
150 | } | ||
151 | |||
149 | if (atpx->functions.px_params) { | 152 | if (atpx->functions.px_params) { |
150 | union acpi_object *info; | 153 | union acpi_object *info; |
151 | struct atpx_px_params output; | 154 | struct atpx_px_params output; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 7a4b101e10c6..6043dc7c3a94 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, | |||
816 | struct drm_device *ddev = adev->ddev; | 816 | struct drm_device *ddev = adev->ddev; |
817 | struct drm_crtc *crtc; | 817 | struct drm_crtc *crtc; |
818 | uint32_t line_time_us, vblank_lines; | 818 | uint32_t line_time_us, vblank_lines; |
819 | struct cgs_mode_info *mode_info; | ||
819 | 820 | ||
820 | if (info == NULL) | 821 | if (info == NULL) |
821 | return -EINVAL; | 822 | return -EINVAL; |
822 | 823 | ||
824 | mode_info = info->mode_info; | ||
825 | |||
823 | if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { | 826 | if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { |
824 | list_for_each_entry(crtc, | 827 | list_for_each_entry(crtc, |
825 | &ddev->mode_config.crtc_list, head) { | 828 | &ddev->mode_config.crtc_list, head) { |
@@ -828,7 +831,7 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, | |||
828 | info->active_display_mask |= (1 << amdgpu_crtc->crtc_id); | 831 | info->active_display_mask |= (1 << amdgpu_crtc->crtc_id); |
829 | info->display_count++; | 832 | info->display_count++; |
830 | } | 833 | } |
831 | if (info->mode_info != NULL && | 834 | if (mode_info != NULL && |
832 | crtc->enabled && amdgpu_crtc->enabled && | 835 | crtc->enabled && amdgpu_crtc->enabled && |
833 | amdgpu_crtc->hw_mode.clock) { | 836 | amdgpu_crtc->hw_mode.clock) { |
834 | line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / | 837 | line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / |
@@ -836,10 +839,10 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, | |||
836 | vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - | 839 | vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - |
837 | amdgpu_crtc->hw_mode.crtc_vdisplay + | 840 | amdgpu_crtc->hw_mode.crtc_vdisplay + |
838 | (amdgpu_crtc->v_border * 2); | 841 | (amdgpu_crtc->v_border * 2); |
839 | info->mode_info->vblank_time_us = vblank_lines * line_time_us; | 842 | mode_info->vblank_time_us = vblank_lines * line_time_us; |
840 | info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); | 843 | mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); |
841 | info->mode_info->ref_clock = adev->clock.spll.reference_freq; | 844 | mode_info->ref_clock = adev->clock.spll.reference_freq; |
842 | info->mode_info++; | 845 | mode_info = NULL; |
843 | } | 846 | } |
844 | } | 847 | } |
845 | } | 848 | } |
@@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, | |||
847 | return 0; | 850 | return 0; |
848 | } | 851 | } |
849 | 852 | ||
853 | |||
854 | static int amdgpu_cgs_notify_dpm_enabled(void *cgs_device, bool enabled) | ||
855 | { | ||
856 | CGS_FUNC_ADEV; | ||
857 | |||
858 | adev->pm.dpm_enabled = enabled; | ||
859 | |||
860 | return 0; | ||
861 | } | ||
862 | |||
850 | /** \brief evaluate acpi namespace object, handle or pathname must be valid | 863 | /** \brief evaluate acpi namespace object, handle or pathname must be valid |
851 | * \param cgs_device | 864 | * \param cgs_device |
852 | * \param info input/output arguments for the control method | 865 | * \param info input/output arguments for the control method |
@@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { | |||
1097 | amdgpu_cgs_set_powergating_state, | 1110 | amdgpu_cgs_set_powergating_state, |
1098 | amdgpu_cgs_set_clockgating_state, | 1111 | amdgpu_cgs_set_clockgating_state, |
1099 | amdgpu_cgs_get_active_displays_info, | 1112 | amdgpu_cgs_get_active_displays_info, |
1113 | amdgpu_cgs_notify_dpm_enabled, | ||
1100 | amdgpu_cgs_call_acpi_method, | 1114 | amdgpu_cgs_call_acpi_method, |
1101 | amdgpu_cgs_query_system_info, | 1115 | amdgpu_cgs_query_system_info, |
1102 | }; | 1116 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 612117478b57..2139da773da6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -62,12 +62,6 @@ static const char *amdgpu_asic_name[] = { | |||
62 | "LAST", | 62 | "LAST", |
63 | }; | 63 | }; |
64 | 64 | ||
65 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
66 | bool amdgpu_has_atpx_dgpu_power_cntl(void); | ||
67 | #else | ||
68 | static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } | ||
69 | #endif | ||
70 | |||
71 | bool amdgpu_device_is_px(struct drm_device *dev) | 65 | bool amdgpu_device_is_px(struct drm_device *dev) |
72 | { | 66 | { |
73 | struct amdgpu_device *adev = dev->dev_private; | 67 | struct amdgpu_device *adev = dev->dev_private; |
@@ -1485,7 +1479,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1485 | 1479 | ||
1486 | if (amdgpu_runtime_pm == 1) | 1480 | if (amdgpu_runtime_pm == 1) |
1487 | runtime = true; | 1481 | runtime = true; |
1488 | if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl()) | 1482 | if (amdgpu_device_is_px(ddev)) |
1489 | runtime = true; | 1483 | runtime = true; |
1490 | vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); | 1484 | vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); |
1491 | if (runtime) | 1485 | if (runtime) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index f0ed974bd4e0..3fb405b3a614 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |||
@@ -57,7 +57,7 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work, | |||
57 | if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback)) | 57 | if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback)) |
58 | return true; | 58 | return true; |
59 | 59 | ||
60 | fence_put(*f); | 60 | fence_put(fence); |
61 | return false; | 61 | return false; |
62 | } | 62 | } |
63 | 63 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 4303b447efe8..d81f1f4883a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | |||
@@ -121,7 +121,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f) | |||
121 | { | 121 | { |
122 | struct amdgpu_device *adev = ring->adev; | 122 | struct amdgpu_device *adev = ring->adev; |
123 | struct amdgpu_fence *fence; | 123 | struct amdgpu_fence *fence; |
124 | struct fence **ptr; | 124 | struct fence *old, **ptr; |
125 | uint32_t seq; | 125 | uint32_t seq; |
126 | 126 | ||
127 | fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); | 127 | fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); |
@@ -141,7 +141,11 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f) | |||
141 | /* This function can't be called concurrently anyway, otherwise | 141 | /* This function can't be called concurrently anyway, otherwise |
142 | * emitting the fence would mess up the hardware ring buffer. | 142 | * emitting the fence would mess up the hardware ring buffer. |
143 | */ | 143 | */ |
144 | BUG_ON(rcu_dereference_protected(*ptr, 1)); | 144 | old = rcu_dereference_protected(*ptr, 1); |
145 | if (old && !fence_is_signaled(old)) { | ||
146 | DRM_INFO("rcu slot is busy\n"); | ||
147 | fence_wait(old, false); | ||
148 | } | ||
145 | 149 | ||
146 | rcu_assign_pointer(*ptr, fence_get(&fence->base)); | 150 | rcu_assign_pointer(*ptr, fence_get(&fence->base)); |
147 | 151 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index f594cfaa97e5..762cfdb85147 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | |||
@@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev) | |||
219 | if (r) { | 219 | if (r) { |
220 | return r; | 220 | return r; |
221 | } | 221 | } |
222 | adev->ddev->vblank_disable_allowed = true; | ||
223 | |||
222 | /* enable msi */ | 224 | /* enable msi */ |
223 | adev->irq.msi_enabled = false; | 225 | adev->irq.msi_enabled = false; |
224 | 226 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 7805a8706af7..b04337de65d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -303,7 +303,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
303 | fw_info.feature = adev->vce.fb_version; | 303 | fw_info.feature = adev->vce.fb_version; |
304 | break; | 304 | break; |
305 | case AMDGPU_INFO_FW_UVD: | 305 | case AMDGPU_INFO_FW_UVD: |
306 | fw_info.ver = 0; | 306 | fw_info.ver = adev->uvd.fw_version; |
307 | fw_info.feature = 0; | 307 | fw_info.feature = 0; |
308 | break; | 308 | break; |
309 | case AMDGPU_INFO_FW_GMC: | 309 | case AMDGPU_INFO_FW_GMC: |
@@ -382,8 +382,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
382 | struct drm_amdgpu_info_vram_gtt vram_gtt; | 382 | struct drm_amdgpu_info_vram_gtt vram_gtt; |
383 | 383 | ||
384 | vram_gtt.vram_size = adev->mc.real_vram_size; | 384 | vram_gtt.vram_size = adev->mc.real_vram_size; |
385 | vram_gtt.vram_size -= adev->vram_pin_size; | ||
385 | vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size; | 386 | vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size; |
386 | vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size; | 387 | vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size); |
387 | vram_gtt.gtt_size = adev->mc.gtt_size; | 388 | vram_gtt.gtt_size = adev->mc.gtt_size; |
388 | vram_gtt.gtt_size -= adev->gart_pin_size; | 389 | vram_gtt.gtt_size -= adev->gart_pin_size; |
389 | return copy_to_user(out, &vram_gtt, | 390 | return copy_to_user(out, &vram_gtt, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 8d432e6901af..81bd964d3dfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | |||
@@ -53,7 +53,7 @@ struct amdgpu_hpd; | |||
53 | 53 | ||
54 | #define AMDGPU_MAX_HPD_PINS 6 | 54 | #define AMDGPU_MAX_HPD_PINS 6 |
55 | #define AMDGPU_MAX_CRTCS 6 | 55 | #define AMDGPU_MAX_CRTCS 6 |
56 | #define AMDGPU_MAX_AFMT_BLOCKS 7 | 56 | #define AMDGPU_MAX_AFMT_BLOCKS 9 |
57 | 57 | ||
58 | enum amdgpu_rmx_type { | 58 | enum amdgpu_rmx_type { |
59 | RMX_OFF, | 59 | RMX_OFF, |
@@ -309,8 +309,8 @@ struct amdgpu_mode_info { | |||
309 | struct atom_context *atom_context; | 309 | struct atom_context *atom_context; |
310 | struct card_info *atom_card_info; | 310 | struct card_info *atom_card_info; |
311 | bool mode_config_initialized; | 311 | bool mode_config_initialized; |
312 | struct amdgpu_crtc *crtcs[6]; | 312 | struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; |
313 | struct amdgpu_afmt *afmt[7]; | 313 | struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; |
314 | /* DVI-I properties */ | 314 | /* DVI-I properties */ |
315 | struct drm_property *coherent_mode_property; | 315 | struct drm_property *coherent_mode_property; |
316 | /* DAC enable load detect */ | 316 | /* DAC enable load detect */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 56d1458393cc..e557fc1f17c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -424,9 +424,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
424 | bo->pin_count = 1; | 424 | bo->pin_count = 1; |
425 | if (gpu_addr != NULL) | 425 | if (gpu_addr != NULL) |
426 | *gpu_addr = amdgpu_bo_gpu_offset(bo); | 426 | *gpu_addr = amdgpu_bo_gpu_offset(bo); |
427 | if (domain == AMDGPU_GEM_DOMAIN_VRAM) | 427 | if (domain == AMDGPU_GEM_DOMAIN_VRAM) { |
428 | bo->adev->vram_pin_size += amdgpu_bo_size(bo); | 428 | bo->adev->vram_pin_size += amdgpu_bo_size(bo); |
429 | else | 429 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) |
430 | bo->adev->invisible_pin_size += amdgpu_bo_size(bo); | ||
431 | } else | ||
430 | bo->adev->gart_pin_size += amdgpu_bo_size(bo); | 432 | bo->adev->gart_pin_size += amdgpu_bo_size(bo); |
431 | } else { | 433 | } else { |
432 | dev_err(bo->adev->dev, "%p pin failed\n", bo); | 434 | dev_err(bo->adev->dev, "%p pin failed\n", bo); |
@@ -456,9 +458,11 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo) | |||
456 | } | 458 | } |
457 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); | 459 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); |
458 | if (likely(r == 0)) { | 460 | if (likely(r == 0)) { |
459 | if (bo->tbo.mem.mem_type == TTM_PL_VRAM) | 461 | if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { |
460 | bo->adev->vram_pin_size -= amdgpu_bo_size(bo); | 462 | bo->adev->vram_pin_size -= amdgpu_bo_size(bo); |
461 | else | 463 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) |
464 | bo->adev->invisible_pin_size -= amdgpu_bo_size(bo); | ||
465 | } else | ||
462 | bo->adev->gart_pin_size -= amdgpu_bo_size(bo); | 466 | bo->adev->gart_pin_size -= amdgpu_bo_size(bo); |
463 | } else { | 467 | } else { |
464 | dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); | 468 | dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); |
@@ -476,6 +480,17 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev) | |||
476 | return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM); | 480 | return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM); |
477 | } | 481 | } |
478 | 482 | ||
483 | static const char *amdgpu_vram_names[] = { | ||
484 | "UNKNOWN", | ||
485 | "GDDR1", | ||
486 | "DDR2", | ||
487 | "GDDR3", | ||
488 | "GDDR4", | ||
489 | "GDDR5", | ||
490 | "HBM", | ||
491 | "DDR3" | ||
492 | }; | ||
493 | |||
479 | int amdgpu_bo_init(struct amdgpu_device *adev) | 494 | int amdgpu_bo_init(struct amdgpu_device *adev) |
480 | { | 495 | { |
481 | /* Add an MTRR for the VRAM */ | 496 | /* Add an MTRR for the VRAM */ |
@@ -484,8 +499,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev) | |||
484 | DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n", | 499 | DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n", |
485 | adev->mc.mc_vram_size >> 20, | 500 | adev->mc.mc_vram_size >> 20, |
486 | (unsigned long long)adev->mc.aper_size >> 20); | 501 | (unsigned long long)adev->mc.aper_size >> 20); |
487 | DRM_INFO("RAM width %dbits DDR\n", | 502 | DRM_INFO("RAM width %dbits %s\n", |
488 | adev->mc.vram_width); | 503 | adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]); |
489 | return amdgpu_ttm_init(adev); | 504 | return amdgpu_ttm_init(adev); |
490 | } | 505 | } |
491 | 506 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 3cb6d6c413c7..e9c6ae6ed2f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | |||
@@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle) | |||
143 | adev->powerplay.pp_handle); | 143 | adev->powerplay.pp_handle); |
144 | 144 | ||
145 | #ifdef CONFIG_DRM_AMD_POWERPLAY | 145 | #ifdef CONFIG_DRM_AMD_POWERPLAY |
146 | if (adev->pp_enabled) { | 146 | if (adev->pp_enabled && adev->pm.dpm_enabled) { |
147 | amdgpu_pm_sysfs_init(adev); | 147 | amdgpu_pm_sysfs_init(adev); |
148 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL); | 148 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL); |
149 | } | 149 | } |
@@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle) | |||
161 | adev->powerplay.pp_handle); | 161 | adev->powerplay.pp_handle); |
162 | 162 | ||
163 | #ifdef CONFIG_DRM_AMD_POWERPLAY | 163 | #ifdef CONFIG_DRM_AMD_POWERPLAY |
164 | if (adev->pp_enabled) { | 164 | if (adev->pp_enabled) |
165 | if (amdgpu_dpm == 0) | 165 | adev->pm.dpm_enabled = true; |
166 | adev->pm.dpm_enabled = false; | ||
167 | else | ||
168 | adev->pm.dpm_enabled = true; | ||
169 | } | ||
170 | #endif | 166 | #endif |
171 | 167 | ||
172 | return ret; | 168 | return ret; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index f1a55d1888cb..11af4492b4be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -223,6 +223,8 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) | |||
223 | { | 223 | { |
224 | struct amdgpu_bo *rbo = container_of(bo, struct amdgpu_bo, tbo); | 224 | struct amdgpu_bo *rbo = container_of(bo, struct amdgpu_bo, tbo); |
225 | 225 | ||
226 | if (amdgpu_ttm_tt_get_usermm(bo->ttm)) | ||
227 | return -EPERM; | ||
226 | return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp); | 228 | return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp); |
227 | } | 229 | } |
228 | 230 | ||
@@ -622,7 +624,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | |||
622 | set_page_dirty(page); | 624 | set_page_dirty(page); |
623 | 625 | ||
624 | mark_page_accessed(page); | 626 | mark_page_accessed(page); |
625 | page_cache_release(page); | 627 | put_page(page); |
626 | } | 628 | } |
627 | 629 | ||
628 | sg_free_table(ttm->sg); | 630 | sg_free_table(ttm->sg); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index c1a581044417..871018c634e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -158,6 +158,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
158 | DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", | 158 | DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", |
159 | version_major, version_minor, family_id); | 159 | version_major, version_minor, family_id); |
160 | 160 | ||
161 | adev->uvd.fw_version = ((version_major << 24) | (version_minor << 16) | | ||
162 | (family_id << 8)); | ||
163 | |||
161 | bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) | 164 | bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) |
162 | + AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE; | 165 | + AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE; |
163 | r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true, | 166 | r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true, |
@@ -241,32 +244,30 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | |||
241 | 244 | ||
242 | int amdgpu_uvd_suspend(struct amdgpu_device *adev) | 245 | int amdgpu_uvd_suspend(struct amdgpu_device *adev) |
243 | { | 246 | { |
244 | struct amdgpu_ring *ring = &adev->uvd.ring; | 247 | unsigned size; |
245 | int i, r; | 248 | void *ptr; |
249 | int i; | ||
246 | 250 | ||
247 | if (adev->uvd.vcpu_bo == NULL) | 251 | if (adev->uvd.vcpu_bo == NULL) |
248 | return 0; | 252 | return 0; |
249 | 253 | ||
250 | for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { | 254 | for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) |
251 | uint32_t handle = atomic_read(&adev->uvd.handles[i]); | 255 | if (atomic_read(&adev->uvd.handles[i])) |
252 | if (handle != 0) { | 256 | break; |
253 | struct fence *fence; | ||
254 | 257 | ||
255 | amdgpu_uvd_note_usage(adev); | 258 | if (i == AMDGPU_MAX_UVD_HANDLES) |
259 | return 0; | ||
256 | 260 | ||
257 | r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence); | 261 | cancel_delayed_work_sync(&adev->uvd.idle_work); |
258 | if (r) { | ||
259 | DRM_ERROR("Error destroying UVD (%d)!\n", r); | ||
260 | continue; | ||
261 | } | ||
262 | 262 | ||
263 | fence_wait(fence, false); | 263 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); |
264 | fence_put(fence); | 264 | ptr = adev->uvd.cpu_addr; |
265 | 265 | ||
266 | adev->uvd.filp[i] = NULL; | 266 | adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); |
267 | atomic_set(&adev->uvd.handles[i], 0); | 267 | if (!adev->uvd.saved_bo) |
268 | } | 268 | return -ENOMEM; |
269 | } | 269 | |
270 | memcpy(adev->uvd.saved_bo, ptr, size); | ||
270 | 271 | ||
271 | return 0; | 272 | return 0; |
272 | } | 273 | } |
@@ -275,23 +276,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) | |||
275 | { | 276 | { |
276 | unsigned size; | 277 | unsigned size; |
277 | void *ptr; | 278 | void *ptr; |
278 | const struct common_firmware_header *hdr; | ||
279 | unsigned offset; | ||
280 | 279 | ||
281 | if (adev->uvd.vcpu_bo == NULL) | 280 | if (adev->uvd.vcpu_bo == NULL) |
282 | return -EINVAL; | 281 | return -EINVAL; |
283 | 282 | ||
284 | hdr = (const struct common_firmware_header *)adev->uvd.fw->data; | ||
285 | offset = le32_to_cpu(hdr->ucode_array_offset_bytes); | ||
286 | memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset, | ||
287 | (adev->uvd.fw->size) - offset); | ||
288 | |||
289 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); | 283 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); |
290 | size -= le32_to_cpu(hdr->ucode_size_bytes); | ||
291 | ptr = adev->uvd.cpu_addr; | 284 | ptr = adev->uvd.cpu_addr; |
292 | ptr += le32_to_cpu(hdr->ucode_size_bytes); | ||
293 | 285 | ||
294 | memset(ptr, 0, size); | 286 | if (adev->uvd.saved_bo != NULL) { |
287 | memcpy(ptr, adev->uvd.saved_bo, size); | ||
288 | kfree(adev->uvd.saved_bo); | ||
289 | adev->uvd.saved_bo = NULL; | ||
290 | } else { | ||
291 | const struct common_firmware_header *hdr; | ||
292 | unsigned offset; | ||
293 | |||
294 | hdr = (const struct common_firmware_header *)adev->uvd.fw->data; | ||
295 | offset = le32_to_cpu(hdr->ucode_array_offset_bytes); | ||
296 | memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset, | ||
297 | (adev->uvd.fw->size) - offset); | ||
298 | size -= le32_to_cpu(hdr->ucode_size_bytes); | ||
299 | ptr += le32_to_cpu(hdr->ucode_size_bytes); | ||
300 | memset(ptr, 0, size); | ||
301 | } | ||
295 | 302 | ||
296 | return 0; | 303 | return 0; |
297 | } | 304 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 4bec0c108cea..481a64fa9b47 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
@@ -234,6 +234,7 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev) | |||
234 | if (i == AMDGPU_MAX_VCE_HANDLES) | 234 | if (i == AMDGPU_MAX_VCE_HANDLES) |
235 | return 0; | 235 | return 0; |
236 | 236 | ||
237 | cancel_delayed_work_sync(&adev->vce.idle_work); | ||
237 | /* TODO: suspending running encoding sessions isn't supported */ | 238 | /* TODO: suspending running encoding sessions isn't supported */ |
238 | return -EINVAL; | 239 | return -EINVAL; |
239 | } | 240 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 82ce7d943884..a4a2e6cc61bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
@@ -903,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle) | |||
903 | gmc_v7_0_set_gart_funcs(adev); | 903 | gmc_v7_0_set_gart_funcs(adev); |
904 | gmc_v7_0_set_irq_funcs(adev); | 904 | gmc_v7_0_set_irq_funcs(adev); |
905 | 905 | ||
906 | if (adev->flags & AMD_IS_APU) { | ||
907 | adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; | ||
908 | } else { | ||
909 | u32 tmp = RREG32(mmMC_SEQ_MISC0); | ||
910 | tmp &= MC_SEQ_MISC0__MT__MASK; | ||
911 | adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp); | ||
912 | } | ||
913 | |||
914 | return 0; | 906 | return 0; |
915 | } | 907 | } |
916 | 908 | ||
@@ -918,7 +910,10 @@ static int gmc_v7_0_late_init(void *handle) | |||
918 | { | 910 | { |
919 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 911 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
920 | 912 | ||
921 | return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | 913 | if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) |
914 | return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | ||
915 | else | ||
916 | return 0; | ||
922 | } | 917 | } |
923 | 918 | ||
924 | static int gmc_v7_0_sw_init(void *handle) | 919 | static int gmc_v7_0_sw_init(void *handle) |
@@ -927,6 +922,14 @@ static int gmc_v7_0_sw_init(void *handle) | |||
927 | int dma_bits; | 922 | int dma_bits; |
928 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 923 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
929 | 924 | ||
925 | if (adev->flags & AMD_IS_APU) { | ||
926 | adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; | ||
927 | } else { | ||
928 | u32 tmp = RREG32(mmMC_SEQ_MISC0); | ||
929 | tmp &= MC_SEQ_MISC0__MT__MASK; | ||
930 | adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp); | ||
931 | } | ||
932 | |||
930 | r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault); | 933 | r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault); |
931 | if (r) | 934 | if (r) |
932 | return r; | 935 | return r; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 29bd7b57dc91..7a9db2c72c89 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
@@ -863,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle) | |||
863 | gmc_v8_0_set_gart_funcs(adev); | 863 | gmc_v8_0_set_gart_funcs(adev); |
864 | gmc_v8_0_set_irq_funcs(adev); | 864 | gmc_v8_0_set_irq_funcs(adev); |
865 | 865 | ||
866 | if (adev->flags & AMD_IS_APU) { | ||
867 | adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; | ||
868 | } else { | ||
869 | u32 tmp = RREG32(mmMC_SEQ_MISC0); | ||
870 | tmp &= MC_SEQ_MISC0__MT__MASK; | ||
871 | adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp); | ||
872 | } | ||
873 | |||
874 | return 0; | 866 | return 0; |
875 | } | 867 | } |
876 | 868 | ||
@@ -878,15 +870,33 @@ static int gmc_v8_0_late_init(void *handle) | |||
878 | { | 870 | { |
879 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 871 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
880 | 872 | ||
881 | return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | 873 | if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS) |
874 | return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); | ||
875 | else | ||
876 | return 0; | ||
882 | } | 877 | } |
883 | 878 | ||
879 | #define mmMC_SEQ_MISC0_FIJI 0xA71 | ||
880 | |||
884 | static int gmc_v8_0_sw_init(void *handle) | 881 | static int gmc_v8_0_sw_init(void *handle) |
885 | { | 882 | { |
886 | int r; | 883 | int r; |
887 | int dma_bits; | 884 | int dma_bits; |
888 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 885 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
889 | 886 | ||
887 | if (adev->flags & AMD_IS_APU) { | ||
888 | adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; | ||
889 | } else { | ||
890 | u32 tmp; | ||
891 | |||
892 | if (adev->asic_type == CHIP_FIJI) | ||
893 | tmp = RREG32(mmMC_SEQ_MISC0_FIJI); | ||
894 | else | ||
895 | tmp = RREG32(mmMC_SEQ_MISC0); | ||
896 | tmp &= MC_SEQ_MISC0__MT__MASK; | ||
897 | adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp); | ||
898 | } | ||
899 | |||
890 | r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault); | 900 | r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault); |
891 | if (r) | 901 | if (r) |
892 | return r; | 902 | return r; |
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c index b6f7d7bff929..0f14199cf716 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c | |||
@@ -307,7 +307,7 @@ static int tonga_ih_sw_fini(void *handle) | |||
307 | 307 | ||
308 | amdgpu_irq_fini(adev); | 308 | amdgpu_irq_fini(adev); |
309 | amdgpu_ih_ring_fini(adev); | 309 | amdgpu_ih_ring_fini(adev); |
310 | amdgpu_irq_add_domain(adev); | 310 | amdgpu_irq_remove_domain(adev); |
311 | 311 | ||
312 | return 0; | 312 | return 0; |
313 | } | 313 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index c606ccb38d8b..cb463753115b 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | |||
@@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle) | |||
224 | int r; | 224 | int r; |
225 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 225 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
226 | 226 | ||
227 | r = amdgpu_uvd_suspend(adev); | 227 | r = uvd_v4_2_hw_fini(adev); |
228 | if (r) | 228 | if (r) |
229 | return r; | 229 | return r; |
230 | 230 | ||
231 | r = uvd_v4_2_hw_fini(adev); | 231 | r = amdgpu_uvd_suspend(adev); |
232 | if (r) | 232 | if (r) |
233 | return r; | 233 | return r; |
234 | 234 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index e3c852d9d79a..16476d80f475 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | |||
@@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle) | |||
220 | int r; | 220 | int r; |
221 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 221 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
222 | 222 | ||
223 | r = amdgpu_uvd_suspend(adev); | 223 | r = uvd_v5_0_hw_fini(adev); |
224 | if (r) | 224 | if (r) |
225 | return r; | 225 | return r; |
226 | 226 | ||
227 | r = uvd_v5_0_hw_fini(adev); | 227 | r = amdgpu_uvd_suspend(adev); |
228 | if (r) | 228 | if (r) |
229 | return r; | 229 | return r; |
230 | 230 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 3375e614ac67..d49379145ef2 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | |||
@@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle) | |||
214 | int r; | 214 | int r; |
215 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 215 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
216 | 216 | ||
217 | r = uvd_v6_0_hw_fini(adev); | ||
218 | if (r) | ||
219 | return r; | ||
220 | |||
217 | /* Skip this for APU for now */ | 221 | /* Skip this for APU for now */ |
218 | if (!(adev->flags & AMD_IS_APU)) { | 222 | if (!(adev->flags & AMD_IS_APU)) { |
219 | r = amdgpu_uvd_suspend(adev); | 223 | r = amdgpu_uvd_suspend(adev); |
220 | if (r) | 224 | if (r) |
221 | return r; | 225 | return r; |
222 | } | 226 | } |
223 | r = uvd_v6_0_hw_fini(adev); | ||
224 | if (r) | ||
225 | return r; | ||
226 | 227 | ||
227 | return r; | 228 | return r; |
228 | } | 229 | } |
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h index aec38fc3834f..ab84d4947247 100644 --- a/drivers/gpu/drm/amd/include/cgs_common.h +++ b/drivers/gpu/drm/amd/include/cgs_common.h | |||
@@ -589,6 +589,8 @@ typedef int(*cgs_get_active_displays_info)( | |||
589 | void *cgs_device, | 589 | void *cgs_device, |
590 | struct cgs_display_info *info); | 590 | struct cgs_display_info *info); |
591 | 591 | ||
592 | typedef int (*cgs_notify_dpm_enabled)(void *cgs_device, bool enabled); | ||
593 | |||
592 | typedef int (*cgs_call_acpi_method)(void *cgs_device, | 594 | typedef int (*cgs_call_acpi_method)(void *cgs_device, |
593 | uint32_t acpi_method, | 595 | uint32_t acpi_method, |
594 | uint32_t acpi_function, | 596 | uint32_t acpi_function, |
@@ -644,6 +646,8 @@ struct cgs_ops { | |||
644 | cgs_set_clockgating_state set_clockgating_state; | 646 | cgs_set_clockgating_state set_clockgating_state; |
645 | /* display manager */ | 647 | /* display manager */ |
646 | cgs_get_active_displays_info get_active_displays_info; | 648 | cgs_get_active_displays_info get_active_displays_info; |
649 | /* notify dpm enabled */ | ||
650 | cgs_notify_dpm_enabled notify_dpm_enabled; | ||
647 | /* ACPI */ | 651 | /* ACPI */ |
648 | cgs_call_acpi_method call_acpi_method; | 652 | cgs_call_acpi_method call_acpi_method; |
649 | /* get system info */ | 653 | /* get system info */ |
@@ -734,8 +738,12 @@ struct cgs_device | |||
734 | CGS_CALL(set_powergating_state, dev, block_type, state) | 738 | CGS_CALL(set_powergating_state, dev, block_type, state) |
735 | #define cgs_set_clockgating_state(dev, block_type, state) \ | 739 | #define cgs_set_clockgating_state(dev, block_type, state) \ |
736 | CGS_CALL(set_clockgating_state, dev, block_type, state) | 740 | CGS_CALL(set_clockgating_state, dev, block_type, state) |
741 | #define cgs_notify_dpm_enabled(dev, enabled) \ | ||
742 | CGS_CALL(notify_dpm_enabled, dev, enabled) | ||
743 | |||
737 | #define cgs_get_active_displays_info(dev, info) \ | 744 | #define cgs_get_active_displays_info(dev, info) \ |
738 | CGS_CALL(get_active_displays_info, dev, info) | 745 | CGS_CALL(get_active_displays_info, dev, info) |
746 | |||
739 | #define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) \ | 747 | #define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) \ |
740 | CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) | 748 | CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) |
741 | #define cgs_query_system_info(dev, sys_info) \ | 749 | #define cgs_query_system_info(dev, sys_info) \ |
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c index 6b52c78cb404..56856a2864d1 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c | |||
@@ -137,14 +137,14 @@ static const pem_event_action *resume_event[] = { | |||
137 | reset_display_configCounter_tasks, | 137 | reset_display_configCounter_tasks, |
138 | update_dal_configuration_tasks, | 138 | update_dal_configuration_tasks, |
139 | vari_bright_resume_tasks, | 139 | vari_bright_resume_tasks, |
140 | block_adjust_power_state_tasks, | ||
141 | setup_asic_tasks, | 140 | setup_asic_tasks, |
142 | enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */ | 141 | enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */ |
143 | enable_dynamic_state_management_tasks, | 142 | enable_dynamic_state_management_tasks, |
144 | enable_clock_power_gatings_tasks, | 143 | enable_clock_power_gatings_tasks, |
145 | enable_disable_bapm_tasks, | 144 | enable_disable_bapm_tasks, |
146 | initialize_thermal_controller_tasks, | 145 | initialize_thermal_controller_tasks, |
147 | reset_boot_state_tasks, | 146 | get_2d_performance_state_tasks, |
147 | set_performance_state_tasks, | ||
148 | adjust_power_state_tasks, | 148 | adjust_power_state_tasks, |
149 | enable_disable_fps_tasks, | 149 | enable_disable_fps_tasks, |
150 | notify_hw_power_source_tasks, | 150 | notify_hw_power_source_tasks, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 51dedf84623c..89f31bc5b68b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | |||
@@ -2389,6 +2389,7 @@ static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr, | |||
2389 | 2389 | ||
2390 | for(count = 0; count < table->VceLevelCount; count++) { | 2390 | for(count = 0; count < table->VceLevelCount; count++) { |
2391 | table->VceLevel[count].Frequency = mm_table->entries[count].eclk; | 2391 | table->VceLevel[count].Frequency = mm_table->entries[count].eclk; |
2392 | table->VceLevel[count].MinVoltage = 0; | ||
2392 | table->VceLevel[count].MinVoltage |= | 2393 | table->VceLevel[count].MinVoltage |= |
2393 | (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; | 2394 | (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; |
2394 | table->VceLevel[count].MinVoltage |= | 2395 | table->VceLevel[count].MinVoltage |= |
@@ -2465,6 +2466,7 @@ static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr, | |||
2465 | 2466 | ||
2466 | for (count = 0; count < table->SamuLevelCount; count++) { | 2467 | for (count = 0; count < table->SamuLevelCount; count++) { |
2467 | /* not sure whether we need evclk or not */ | 2468 | /* not sure whether we need evclk or not */ |
2469 | table->SamuLevel[count].MinVoltage = 0; | ||
2468 | table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; | 2470 | table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; |
2469 | table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * | 2471 | table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * |
2470 | VOLTAGE_SCALE) << VDDC_SHIFT; | 2472 | VOLTAGE_SCALE) << VDDC_SHIFT; |
@@ -2562,6 +2564,7 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, | |||
2562 | table->UvdBootLevel = 0; | 2564 | table->UvdBootLevel = 0; |
2563 | 2565 | ||
2564 | for (count = 0; count < table->UvdLevelCount; count++) { | 2566 | for (count = 0; count < table->UvdLevelCount; count++) { |
2567 | table->UvdLevel[count].MinVoltage = 0; | ||
2565 | table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; | 2568 | table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; |
2566 | table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; | 2569 | table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; |
2567 | table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * | 2570 | table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * |
@@ -2900,6 +2903,8 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2900 | if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control) | 2903 | if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control) |
2901 | fiji_populate_smc_voltage_tables(hwmgr, table); | 2904 | fiji_populate_smc_voltage_tables(hwmgr, table); |
2902 | 2905 | ||
2906 | table->SystemFlags = 0; | ||
2907 | |||
2903 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 2908 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
2904 | PHM_PlatformCaps_AutomaticDCTransition)) | 2909 | PHM_PlatformCaps_AutomaticDCTransition)) |
2905 | table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; | 2910 | table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; |
@@ -2997,6 +3002,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr) | |||
2997 | table->MemoryThermThrottleEnable = 1; | 3002 | table->MemoryThermThrottleEnable = 1; |
2998 | table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/ | 3003 | table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/ |
2999 | table->PCIeGenInterval = 1; | 3004 | table->PCIeGenInterval = 1; |
3005 | table->VRConfig = 0; | ||
3000 | 3006 | ||
3001 | result = fiji_populate_vr_config(hwmgr, table); | 3007 | result = fiji_populate_vr_config(hwmgr, table); |
3002 | PP_ASSERT_WITH_CODE(0 == result, | 3008 | PP_ASSERT_WITH_CODE(0 == result, |
@@ -5195,6 +5201,67 @@ static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr, | |||
5195 | return size; | 5201 | return size; |
5196 | } | 5202 | } |
5197 | 5203 | ||
5204 | static inline bool fiji_are_power_levels_equal(const struct fiji_performance_level *pl1, | ||
5205 | const struct fiji_performance_level *pl2) | ||
5206 | { | ||
5207 | return ((pl1->memory_clock == pl2->memory_clock) && | ||
5208 | (pl1->engine_clock == pl2->engine_clock) && | ||
5209 | (pl1->pcie_gen == pl2->pcie_gen) && | ||
5210 | (pl1->pcie_lane == pl2->pcie_lane)); | ||
5211 | } | ||
5212 | |||
5213 | int fiji_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal) | ||
5214 | { | ||
5215 | const struct fiji_power_state *psa = cast_const_phw_fiji_power_state(pstate1); | ||
5216 | const struct fiji_power_state *psb = cast_const_phw_fiji_power_state(pstate2); | ||
5217 | int i; | ||
5218 | |||
5219 | if (equal == NULL || psa == NULL || psb == NULL) | ||
5220 | return -EINVAL; | ||
5221 | |||
5222 | /* If the two states don't even have the same number of performance levels they cannot be the same state. */ | ||
5223 | if (psa->performance_level_count != psb->performance_level_count) { | ||
5224 | *equal = false; | ||
5225 | return 0; | ||
5226 | } | ||
5227 | |||
5228 | for (i = 0; i < psa->performance_level_count; i++) { | ||
5229 | if (!fiji_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) { | ||
5230 | /* If we have found even one performance level pair that is different the states are different. */ | ||
5231 | *equal = false; | ||
5232 | return 0; | ||
5233 | } | ||
5234 | } | ||
5235 | |||
5236 | /* If all performance levels are the same try to use the UVD clocks to break the tie.*/ | ||
5237 | *equal = ((psa->uvd_clks.vclk == psb->uvd_clks.vclk) && (psa->uvd_clks.dclk == psb->uvd_clks.dclk)); | ||
5238 | *equal &= ((psa->vce_clks.evclk == psb->vce_clks.evclk) && (psa->vce_clks.ecclk == psb->vce_clks.ecclk)); | ||
5239 | *equal &= (psa->sclk_threshold == psb->sclk_threshold); | ||
5240 | *equal &= (psa->acp_clk == psb->acp_clk); | ||
5241 | |||
5242 | return 0; | ||
5243 | } | ||
5244 | |||
5245 | bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) | ||
5246 | { | ||
5247 | struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); | ||
5248 | bool is_update_required = false; | ||
5249 | struct cgs_display_info info = {0,0,NULL}; | ||
5250 | |||
5251 | cgs_get_active_displays_info(hwmgr->device, &info); | ||
5252 | |||
5253 | if (data->display_timing.num_existing_displays != info.display_count) | ||
5254 | is_update_required = true; | ||
5255 | /* TO DO NEED TO GET DEEP SLEEP CLOCK FROM DAL | ||
5256 | if (phm_cap_enabled(hwmgr->hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) { | ||
5257 | cgs_get_min_clock_settings(hwmgr->device, &min_clocks); | ||
5258 | if(min_clocks.engineClockInSR != data->display_timing.minClockInSR) | ||
5259 | is_update_required = true; | ||
5260 | */ | ||
5261 | return is_update_required; | ||
5262 | } | ||
5263 | |||
5264 | |||
5198 | static const struct pp_hwmgr_func fiji_hwmgr_funcs = { | 5265 | static const struct pp_hwmgr_func fiji_hwmgr_funcs = { |
5199 | .backend_init = &fiji_hwmgr_backend_init, | 5266 | .backend_init = &fiji_hwmgr_backend_init, |
5200 | .backend_fini = &tonga_hwmgr_backend_fini, | 5267 | .backend_fini = &tonga_hwmgr_backend_fini, |
@@ -5230,6 +5297,8 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = { | |||
5230 | .register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt, | 5297 | .register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt, |
5231 | .set_fan_control_mode = fiji_set_fan_control_mode, | 5298 | .set_fan_control_mode = fiji_set_fan_control_mode, |
5232 | .get_fan_control_mode = fiji_get_fan_control_mode, | 5299 | .get_fan_control_mode = fiji_get_fan_control_mode, |
5300 | .check_states_equal = fiji_check_states_equal, | ||
5301 | .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration, | ||
5233 | .get_pp_table = fiji_get_pp_table, | 5302 | .get_pp_table = fiji_get_pp_table, |
5234 | .set_pp_table = fiji_set_pp_table, | 5303 | .set_pp_table = fiji_set_pp_table, |
5235 | .force_clock_level = fiji_force_clock_level, | 5304 | .force_clock_level = fiji_force_clock_level, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index be31bed2538a..fa208ada6892 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c | |||
@@ -58,6 +58,9 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr) | |||
58 | 58 | ||
59 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress); | 59 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress); |
60 | 60 | ||
61 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM); | ||
62 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM); | ||
63 | |||
61 | if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) && | 64 | if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) && |
62 | acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION)) | 65 | acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION)) |
63 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); | 66 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); |
@@ -130,18 +133,25 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr, | |||
130 | 133 | ||
131 | int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) | 134 | int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) |
132 | { | 135 | { |
136 | int ret = 1; | ||
137 | bool enabled; | ||
133 | PHM_FUNC_CHECK(hwmgr); | 138 | PHM_FUNC_CHECK(hwmgr); |
134 | 139 | ||
135 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, | 140 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
136 | PHM_PlatformCaps_TablelessHardwareInterface)) { | 141 | PHM_PlatformCaps_TablelessHardwareInterface)) { |
137 | if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable) | 142 | if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable) |
138 | return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr); | 143 | ret = hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr); |
139 | } else { | 144 | } else { |
140 | return phm_dispatch_table(hwmgr, | 145 | ret = phm_dispatch_table(hwmgr, |
141 | &(hwmgr->enable_dynamic_state_management), | 146 | &(hwmgr->enable_dynamic_state_management), |
142 | NULL, NULL); | 147 | NULL, NULL); |
143 | } | 148 | } |
144 | return 0; | 149 | |
150 | enabled = ret == 0 ? true : false; | ||
151 | |||
152 | cgs_notify_dpm_enabled(hwmgr->device, enabled); | ||
153 | |||
154 | return ret; | ||
145 | } | 155 | } |
146 | 156 | ||
147 | int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level) | 157 | int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level) |
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 56b829f97699..3ac1ae4d8caf 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c | |||
@@ -57,14 +57,13 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
57 | DRM_ERROR("failed to map control registers area\n"); | 57 | DRM_ERROR("failed to map control registers area\n"); |
58 | ret = PTR_ERR(hdlcd->mmio); | 58 | ret = PTR_ERR(hdlcd->mmio); |
59 | hdlcd->mmio = NULL; | 59 | hdlcd->mmio = NULL; |
60 | goto fail; | 60 | return ret; |
61 | } | 61 | } |
62 | 62 | ||
63 | version = hdlcd_read(hdlcd, HDLCD_REG_VERSION); | 63 | version = hdlcd_read(hdlcd, HDLCD_REG_VERSION); |
64 | if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) { | 64 | if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) { |
65 | DRM_ERROR("unknown product id: 0x%x\n", version); | 65 | DRM_ERROR("unknown product id: 0x%x\n", version); |
66 | ret = -EINVAL; | 66 | return -EINVAL; |
67 | goto fail; | ||
68 | } | 67 | } |
69 | DRM_INFO("found ARM HDLCD version r%dp%d\n", | 68 | DRM_INFO("found ARM HDLCD version r%dp%d\n", |
70 | (version & HDLCD_VERSION_MAJOR_MASK) >> 8, | 69 | (version & HDLCD_VERSION_MAJOR_MASK) >> 8, |
@@ -73,7 +72,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
73 | /* Get the optional framebuffer memory resource */ | 72 | /* Get the optional framebuffer memory resource */ |
74 | ret = of_reserved_mem_device_init(drm->dev); | 73 | ret = of_reserved_mem_device_init(drm->dev); |
75 | if (ret && ret != -ENODEV) | 74 | if (ret && ret != -ENODEV) |
76 | goto fail; | 75 | return ret; |
77 | 76 | ||
78 | ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32)); | 77 | ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32)); |
79 | if (ret) | 78 | if (ret) |
@@ -101,8 +100,6 @@ irq_fail: | |||
101 | drm_crtc_cleanup(&hdlcd->crtc); | 100 | drm_crtc_cleanup(&hdlcd->crtc); |
102 | setup_fail: | 101 | setup_fail: |
103 | of_reserved_mem_device_release(drm->dev); | 102 | of_reserved_mem_device_release(drm->dev); |
104 | fail: | ||
105 | devm_clk_put(drm->dev, hdlcd->clk); | ||
106 | 103 | ||
107 | return ret; | 104 | return ret; |
108 | } | 105 | } |
@@ -412,7 +409,6 @@ err_unload: | |||
412 | pm_runtime_put_sync(drm->dev); | 409 | pm_runtime_put_sync(drm->dev); |
413 | pm_runtime_disable(drm->dev); | 410 | pm_runtime_disable(drm->dev); |
414 | of_reserved_mem_device_release(drm->dev); | 411 | of_reserved_mem_device_release(drm->dev); |
415 | devm_clk_put(dev, hdlcd->clk); | ||
416 | err_free: | 412 | err_free: |
417 | drm_dev_unref(drm); | 413 | drm_dev_unref(drm); |
418 | 414 | ||
@@ -436,10 +432,6 @@ static void hdlcd_drm_unbind(struct device *dev) | |||
436 | pm_runtime_put_sync(drm->dev); | 432 | pm_runtime_put_sync(drm->dev); |
437 | pm_runtime_disable(drm->dev); | 433 | pm_runtime_disable(drm->dev); |
438 | of_reserved_mem_device_release(drm->dev); | 434 | of_reserved_mem_device_release(drm->dev); |
439 | if (!IS_ERR(hdlcd->clk)) { | ||
440 | devm_clk_put(drm->dev, hdlcd->clk); | ||
441 | hdlcd->clk = NULL; | ||
442 | } | ||
443 | drm_mode_config_cleanup(drm); | 435 | drm_mode_config_cleanup(drm); |
444 | drm_dev_unregister(drm); | 436 | drm_dev_unregister(drm); |
445 | drm_dev_unref(drm); | 437 | drm_dev_unref(drm); |
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 6e731db31aa4..aca7f9cc6109 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c | |||
@@ -481,7 +481,7 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, | |||
481 | 481 | ||
482 | release: | 482 | release: |
483 | for_each_sg(sgt->sgl, sg, num, i) | 483 | for_each_sg(sgt->sgl, sg, num, i) |
484 | page_cache_release(sg_page(sg)); | 484 | put_page(sg_page(sg)); |
485 | free_table: | 485 | free_table: |
486 | sg_free_table(sgt); | 486 | sg_free_table(sgt); |
487 | free_sgt: | 487 | free_sgt: |
@@ -502,7 +502,7 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, | |||
502 | if (dobj->obj.filp) { | 502 | if (dobj->obj.filp) { |
503 | struct scatterlist *sg; | 503 | struct scatterlist *sg; |
504 | for_each_sg(sgt->sgl, sg, sgt->nents, i) | 504 | for_each_sg(sgt->sgl, sg, sgt->nents, i) |
505 | page_cache_release(sg_page(sg)); | 505 | put_page(sg_page(sg)); |
506 | } | 506 | } |
507 | 507 | ||
508 | sg_free_table(sgt); | 508 | sg_free_table(sgt); |
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 27fbd79d0daf..71ea0521ea96 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
@@ -1672,13 +1672,19 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, | |||
1672 | u8 sinks[DRM_DP_MAX_SDP_STREAMS]; | 1672 | u8 sinks[DRM_DP_MAX_SDP_STREAMS]; |
1673 | int i; | 1673 | int i; |
1674 | 1674 | ||
1675 | port = drm_dp_get_validated_port_ref(mgr, port); | ||
1676 | if (!port) | ||
1677 | return -EINVAL; | ||
1678 | |||
1675 | port_num = port->port_num; | 1679 | port_num = port->port_num; |
1676 | mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); | 1680 | mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); |
1677 | if (!mstb) { | 1681 | if (!mstb) { |
1678 | mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num); | 1682 | mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num); |
1679 | 1683 | ||
1680 | if (!mstb) | 1684 | if (!mstb) { |
1685 | drm_dp_put_port(port); | ||
1681 | return -EINVAL; | 1686 | return -EINVAL; |
1687 | } | ||
1682 | } | 1688 | } |
1683 | 1689 | ||
1684 | txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); | 1690 | txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); |
@@ -1707,6 +1713,7 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, | |||
1707 | kfree(txmsg); | 1713 | kfree(txmsg); |
1708 | fail_put: | 1714 | fail_put: |
1709 | drm_dp_put_mst_branch_device(mstb); | 1715 | drm_dp_put_mst_branch_device(mstb); |
1716 | drm_dp_put_port(port); | ||
1710 | return ret; | 1717 | return ret; |
1711 | } | 1718 | } |
1712 | 1719 | ||
@@ -1789,6 +1796,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) | |||
1789 | req_payload.start_slot = cur_slots; | 1796 | req_payload.start_slot = cur_slots; |
1790 | if (mgr->proposed_vcpis[i]) { | 1797 | if (mgr->proposed_vcpis[i]) { |
1791 | port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); | 1798 | port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); |
1799 | port = drm_dp_get_validated_port_ref(mgr, port); | ||
1800 | if (!port) { | ||
1801 | mutex_unlock(&mgr->payload_lock); | ||
1802 | return -EINVAL; | ||
1803 | } | ||
1792 | req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; | 1804 | req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; |
1793 | req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; | 1805 | req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; |
1794 | } else { | 1806 | } else { |
@@ -1816,6 +1828,9 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) | |||
1816 | mgr->payloads[i].payload_state = req_payload.payload_state; | 1828 | mgr->payloads[i].payload_state = req_payload.payload_state; |
1817 | } | 1829 | } |
1818 | cur_slots += req_payload.num_slots; | 1830 | cur_slots += req_payload.num_slots; |
1831 | |||
1832 | if (port) | ||
1833 | drm_dp_put_port(port); | ||
1819 | } | 1834 | } |
1820 | 1835 | ||
1821 | for (i = 0; i < mgr->max_payloads; i++) { | 1836 | for (i = 0; i < mgr->max_payloads; i++) { |
@@ -2121,6 +2136,8 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) | |||
2121 | 2136 | ||
2122 | if (mgr->mst_primary) { | 2137 | if (mgr->mst_primary) { |
2123 | int sret; | 2138 | int sret; |
2139 | u8 guid[16]; | ||
2140 | |||
2124 | sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); | 2141 | sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); |
2125 | if (sret != DP_RECEIVER_CAP_SIZE) { | 2142 | if (sret != DP_RECEIVER_CAP_SIZE) { |
2126 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); | 2143 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); |
@@ -2135,6 +2152,16 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) | |||
2135 | ret = -1; | 2152 | ret = -1; |
2136 | goto out_unlock; | 2153 | goto out_unlock; |
2137 | } | 2154 | } |
2155 | |||
2156 | /* Some hubs forget their guids after they resume */ | ||
2157 | sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); | ||
2158 | if (sret != 16) { | ||
2159 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); | ||
2160 | ret = -1; | ||
2161 | goto out_unlock; | ||
2162 | } | ||
2163 | drm_dp_check_mstb_guid(mgr->mst_primary, guid); | ||
2164 | |||
2138 | ret = 0; | 2165 | ret = 0; |
2139 | } else | 2166 | } else |
2140 | ret = -1; | 2167 | ret = -1; |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 414d7f61aa05..558ef9fc39e6 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -205,7 +205,7 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
205 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 205 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
206 | /* 0x0f - 1024x768@43Hz, interlace */ | 206 | /* 0x0f - 1024x768@43Hz, interlace */ |
207 | { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032, | 207 | { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032, |
208 | 1208, 1264, 0, 768, 768, 772, 817, 0, | 208 | 1208, 1264, 0, 768, 768, 776, 817, 0, |
209 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | | 209 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
210 | DRM_MODE_FLAG_INTERLACE) }, | 210 | DRM_MODE_FLAG_INTERLACE) }, |
211 | /* 0x10 - 1024x768@60Hz */ | 211 | /* 0x10 - 1024x768@60Hz */ |
@@ -522,12 +522,12 @@ static const struct drm_display_mode edid_est_modes[] = { | |||
522 | 720, 840, 0, 480, 481, 484, 500, 0, | 522 | 720, 840, 0, 480, 481, 484, 500, 0, |
523 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */ | 523 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */ |
524 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, | 524 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, |
525 | 704, 832, 0, 480, 489, 491, 520, 0, | 525 | 704, 832, 0, 480, 489, 492, 520, 0, |
526 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */ | 526 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */ |
527 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704, | 527 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704, |
528 | 768, 864, 0, 480, 483, 486, 525, 0, | 528 | 768, 864, 0, 480, 483, 486, 525, 0, |
529 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */ | 529 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */ |
530 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656, | 530 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, |
531 | 752, 800, 0, 480, 490, 492, 525, 0, | 531 | 752, 800, 0, 480, 490, 492, 525, 0, |
532 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */ | 532 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */ |
533 | { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738, | 533 | { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738, |
@@ -539,7 +539,7 @@ static const struct drm_display_mode edid_est_modes[] = { | |||
539 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, | 539 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, |
540 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, | 540 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, |
541 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */ | 541 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */ |
542 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040, | 542 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040, |
543 | 1136, 1312, 0, 768, 769, 772, 800, 0, | 543 | 1136, 1312, 0, 768, 769, 772, 800, 0, |
544 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */ | 544 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */ |
545 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, | 545 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, |
@@ -2241,7 +2241,7 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) | |||
2241 | { | 2241 | { |
2242 | int i, j, m, modes = 0; | 2242 | int i, j, m, modes = 0; |
2243 | struct drm_display_mode *mode; | 2243 | struct drm_display_mode *mode; |
2244 | u8 *est = ((u8 *)timing) + 5; | 2244 | u8 *est = ((u8 *)timing) + 6; |
2245 | 2245 | ||
2246 | for (i = 0; i < 6; i++) { | 2246 | for (i = 0; i < 6; i++) { |
2247 | for (j = 7; j >= 0; j--) { | 2247 | for (j = 7; j >= 0; j--) { |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 2e8c77e71e1f..da0c5320789f 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -534,7 +534,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) | |||
534 | 534 | ||
535 | fail: | 535 | fail: |
536 | while (i--) | 536 | while (i--) |
537 | page_cache_release(pages[i]); | 537 | put_page(pages[i]); |
538 | 538 | ||
539 | drm_free_large(pages); | 539 | drm_free_large(pages); |
540 | return ERR_CAST(p); | 540 | return ERR_CAST(p); |
@@ -569,7 +569,7 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, | |||
569 | mark_page_accessed(pages[i]); | 569 | mark_page_accessed(pages[i]); |
570 | 570 | ||
571 | /* Undo the reference we took when populating the table */ | 571 | /* Undo the reference we took when populating the table */ |
572 | page_cache_release(pages[i]); | 572 | put_page(pages[i]); |
573 | } | 573 | } |
574 | 574 | ||
575 | drm_free_large(pages); | 575 | drm_free_large(pages); |
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 09198d0b5814..306dde18a94a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c | |||
@@ -572,6 +572,24 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) | |||
572 | goto fail; | 572 | goto fail; |
573 | } | 573 | } |
574 | 574 | ||
575 | /* | ||
576 | * Set the GPU linear window to be at the end of the DMA window, where | ||
577 | * the CMA area is likely to reside. This ensures that we are able to | ||
578 | * map the command buffers while having the linear window overlap as | ||
579 | * much RAM as possible, so we can optimize mappings for other buffers. | ||
580 | * | ||
581 | * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads | ||
582 | * to different views of the memory on the individual engines. | ||
583 | */ | ||
584 | if (!(gpu->identity.features & chipFeatures_PIPE_3D) || | ||
585 | (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { | ||
586 | u32 dma_mask = (u32)dma_get_required_mask(gpu->dev); | ||
587 | if (dma_mask < PHYS_OFFSET + SZ_2G) | ||
588 | gpu->memory_base = PHYS_OFFSET; | ||
589 | else | ||
590 | gpu->memory_base = dma_mask - SZ_2G + 1; | ||
591 | } | ||
592 | |||
575 | ret = etnaviv_hw_reset(gpu); | 593 | ret = etnaviv_hw_reset(gpu); |
576 | if (ret) | 594 | if (ret) |
577 | goto fail; | 595 | goto fail; |
@@ -1566,7 +1584,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) | |||
1566 | { | 1584 | { |
1567 | struct device *dev = &pdev->dev; | 1585 | struct device *dev = &pdev->dev; |
1568 | struct etnaviv_gpu *gpu; | 1586 | struct etnaviv_gpu *gpu; |
1569 | u32 dma_mask; | ||
1570 | int err = 0; | 1587 | int err = 0; |
1571 | 1588 | ||
1572 | gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL); | 1589 | gpu = devm_kzalloc(dev, sizeof(*gpu), GFP_KERNEL); |
@@ -1576,18 +1593,6 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) | |||
1576 | gpu->dev = &pdev->dev; | 1593 | gpu->dev = &pdev->dev; |
1577 | mutex_init(&gpu->lock); | 1594 | mutex_init(&gpu->lock); |
1578 | 1595 | ||
1579 | /* | ||
1580 | * Set the GPU linear window to be at the end of the DMA window, where | ||
1581 | * the CMA area is likely to reside. This ensures that we are able to | ||
1582 | * map the command buffers while having the linear window overlap as | ||
1583 | * much RAM as possible, so we can optimize mappings for other buffers. | ||
1584 | */ | ||
1585 | dma_mask = (u32)dma_get_required_mask(dev); | ||
1586 | if (dma_mask < PHYS_OFFSET + SZ_2G) | ||
1587 | gpu->memory_base = PHYS_OFFSET; | ||
1588 | else | ||
1589 | gpu->memory_base = dma_mask - SZ_2G + 1; | ||
1590 | |||
1591 | /* Map registers: */ | 1596 | /* Map registers: */ |
1592 | gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev)); | 1597 | gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev)); |
1593 | if (IS_ERR(gpu->mmio)) | 1598 | if (IS_ERR(gpu->mmio)) |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index f17d39279596..baddf33fb475 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
@@ -94,7 +94,7 @@ comment "Sub-drivers" | |||
94 | 94 | ||
95 | config DRM_EXYNOS_G2D | 95 | config DRM_EXYNOS_G2D |
96 | bool "G2D" | 96 | bool "G2D" |
97 | depends on !VIDEO_SAMSUNG_S5P_G2D | 97 | depends on VIDEO_SAMSUNG_S5P_G2D=n |
98 | select FRAME_VECTOR | 98 | select FRAME_VECTOR |
99 | help | 99 | help |
100 | Choose this option if you want to use Exynos G2D for DRM. | 100 | Choose this option if you want to use Exynos G2D for DRM. |
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile index 968b31c522b2..23d2f958739b 100644 --- a/drivers/gpu/drm/exynos/Makefile +++ b/drivers/gpu/drm/exynos/Makefile | |||
@@ -2,10 +2,10 @@ | |||
2 | # Makefile for the drm device driver. This driver provides support for the | 2 | # Makefile for the drm device driver. This driver provides support for the |
3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
4 | 4 | ||
5 | exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \ | 5 | exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \ |
6 | exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \ | 6 | exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o |
7 | exynos_drm_plane.o | ||
8 | 7 | ||
8 | exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o | ||
9 | exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o | 9 | exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o |
10 | exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o | 10 | exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o |
11 | exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o | 11 | exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 7f55ba6771c6..011211e4167d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c | |||
@@ -101,7 +101,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) | |||
101 | return 0; | 101 | return 0; |
102 | 102 | ||
103 | err: | 103 | err: |
104 | list_for_each_entry_reverse(subdrv, &subdrv->list, list) { | 104 | list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) { |
105 | if (subdrv->close) | 105 | if (subdrv->close) |
106 | subdrv->close(dev, subdrv->dev, file); | 106 | subdrv->close(dev, subdrv->dev, file); |
107 | } | 107 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index d614194644c8..81cc5537cf25 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -199,17 +199,6 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index) | |||
199 | return exynos_fb->dma_addr[index]; | 199 | return exynos_fb->dma_addr[index]; |
200 | } | 200 | } |
201 | 201 | ||
202 | static void exynos_drm_output_poll_changed(struct drm_device *dev) | ||
203 | { | ||
204 | struct exynos_drm_private *private = dev->dev_private; | ||
205 | struct drm_fb_helper *fb_helper = private->fb_helper; | ||
206 | |||
207 | if (fb_helper) | ||
208 | drm_fb_helper_hotplug_event(fb_helper); | ||
209 | else | ||
210 | exynos_drm_fbdev_init(dev); | ||
211 | } | ||
212 | |||
213 | static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { | 202 | static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { |
214 | .fb_create = exynos_user_fb_create, | 203 | .fb_create = exynos_user_fb_create, |
215 | .output_poll_changed = exynos_drm_output_poll_changed, | 204 | .output_poll_changed = exynos_drm_output_poll_changed, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 4ae860c44f1d..72d7c0b7c216 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -317,3 +317,14 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev) | |||
317 | 317 | ||
318 | drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper); | 318 | drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper); |
319 | } | 319 | } |
320 | |||
321 | void exynos_drm_output_poll_changed(struct drm_device *dev) | ||
322 | { | ||
323 | struct exynos_drm_private *private = dev->dev_private; | ||
324 | struct drm_fb_helper *fb_helper = private->fb_helper; | ||
325 | |||
326 | if (fb_helper) | ||
327 | drm_fb_helper_hotplug_event(fb_helper); | ||
328 | else | ||
329 | exynos_drm_fbdev_init(dev); | ||
330 | } | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h index e16d7f0ae192..330eef87f718 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h | |||
@@ -15,9 +15,30 @@ | |||
15 | #ifndef _EXYNOS_DRM_FBDEV_H_ | 15 | #ifndef _EXYNOS_DRM_FBDEV_H_ |
16 | #define _EXYNOS_DRM_FBDEV_H_ | 16 | #define _EXYNOS_DRM_FBDEV_H_ |
17 | 17 | ||
18 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
19 | |||
18 | int exynos_drm_fbdev_init(struct drm_device *dev); | 20 | int exynos_drm_fbdev_init(struct drm_device *dev); |
19 | int exynos_drm_fbdev_reinit(struct drm_device *dev); | ||
20 | void exynos_drm_fbdev_fini(struct drm_device *dev); | 21 | void exynos_drm_fbdev_fini(struct drm_device *dev); |
21 | void exynos_drm_fbdev_restore_mode(struct drm_device *dev); | 22 | void exynos_drm_fbdev_restore_mode(struct drm_device *dev); |
23 | void exynos_drm_output_poll_changed(struct drm_device *dev); | ||
24 | |||
25 | #else | ||
26 | |||
27 | static inline int exynos_drm_fbdev_init(struct drm_device *dev) | ||
28 | { | ||
29 | return 0; | ||
30 | } | ||
31 | |||
32 | static inline void exynos_drm_fbdev_fini(struct drm_device *dev) | ||
33 | { | ||
34 | } | ||
35 | |||
36 | static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev) | ||
37 | { | ||
38 | } | ||
39 | |||
40 | #define exynos_drm_output_poll_changed (NULL) | ||
41 | |||
42 | #endif | ||
22 | 43 | ||
23 | #endif | 44 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 51d484ae9f49..018449f8d557 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -888,7 +888,7 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) | |||
888 | * clock. On these SoCs the bootloader may enable it but any | 888 | * clock. On these SoCs the bootloader may enable it but any |
889 | * power domain off/on will reset it to disable state. | 889 | * power domain off/on will reset it to disable state. |
890 | */ | 890 | */ |
891 | if (ctx->driver_data != &exynos5_fimd_driver_data || | 891 | if (ctx->driver_data != &exynos5_fimd_driver_data && |
892 | ctx->driver_data != &exynos5420_fimd_driver_data) | 892 | ctx->driver_data != &exynos5420_fimd_driver_data) |
893 | return; | 893 | return; |
894 | 894 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index 9869d70e9e54..a0def0be6d65 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c | |||
@@ -129,7 +129,7 @@ static void mic_set_path(struct exynos_mic *mic, bool enable) | |||
129 | } else | 129 | } else |
130 | val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); | 130 | val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); |
131 | 131 | ||
132 | regmap_write(mic->sysreg, DSD_CFG_MUX, val); | 132 | ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val); |
133 | if (ret) | 133 | if (ret) |
134 | DRM_ERROR("mic: Failed to read system register\n"); | 134 | DRM_ERROR("mic: Failed to read system register\n"); |
135 | } | 135 | } |
@@ -457,6 +457,7 @@ static int exynos_mic_probe(struct platform_device *pdev) | |||
457 | "samsung,disp-syscon"); | 457 | "samsung,disp-syscon"); |
458 | if (IS_ERR(mic->sysreg)) { | 458 | if (IS_ERR(mic->sysreg)) { |
459 | DRM_ERROR("mic: Failed to get system register.\n"); | 459 | DRM_ERROR("mic: Failed to get system register.\n"); |
460 | ret = PTR_ERR(mic->sysreg); | ||
460 | goto err; | 461 | goto err; |
461 | } | 462 | } |
462 | 463 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index d86227236f55..50185ac347b2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -11,9 +11,10 @@ | |||
11 | 11 | ||
12 | #include <drm/drmP.h> | 12 | #include <drm/drmP.h> |
13 | 13 | ||
14 | #include <drm/exynos_drm.h> | 14 | #include <drm/drm_atomic.h> |
15 | #include <drm/drm_plane_helper.h> | ||
16 | #include <drm/drm_atomic_helper.h> | 15 | #include <drm/drm_atomic_helper.h> |
16 | #include <drm/drm_plane_helper.h> | ||
17 | #include <drm/exynos_drm.h> | ||
17 | #include "exynos_drm_drv.h" | 18 | #include "exynos_drm_drv.h" |
18 | #include "exynos_drm_crtc.h" | 19 | #include "exynos_drm_crtc.h" |
19 | #include "exynos_drm_fb.h" | 20 | #include "exynos_drm_fb.h" |
@@ -57,11 +58,12 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last) | |||
57 | } | 58 | } |
58 | 59 | ||
59 | static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) | 60 | static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) |
60 | |||
61 | { | 61 | { |
62 | struct drm_plane_state *state = &exynos_state->base; | 62 | struct drm_plane_state *state = &exynos_state->base; |
63 | struct drm_crtc *crtc = exynos_state->base.crtc; | 63 | struct drm_crtc *crtc = state->crtc; |
64 | struct drm_display_mode *mode = &crtc->state->adjusted_mode; | 64 | struct drm_crtc_state *crtc_state = |
65 | drm_atomic_get_existing_crtc_state(state->state, crtc); | ||
66 | struct drm_display_mode *mode = &crtc_state->adjusted_mode; | ||
65 | int crtc_x, crtc_y; | 67 | int crtc_x, crtc_y; |
66 | unsigned int crtc_w, crtc_h; | 68 | unsigned int crtc_w, crtc_h; |
67 | unsigned int src_x, src_y; | 69 | unsigned int src_x, src_y; |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 7bb1f1aff932..c52f9adf5e04 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c | |||
@@ -220,7 +220,7 @@ i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) | |||
220 | * FIXME: This is the old dp aux helper, gma500 is the last driver that needs to | 220 | * FIXME: This is the old dp aux helper, gma500 is the last driver that needs to |
221 | * be ported over to the new helper code in drm_dp_helper.c like i915 or radeon. | 221 | * be ported over to the new helper code in drm_dp_helper.c like i915 or radeon. |
222 | */ | 222 | */ |
223 | static int __deprecated | 223 | static int |
224 | i2c_dp_aux_add_bus(struct i2c_adapter *adapter) | 224 | i2c_dp_aux_add_bus(struct i2c_adapter *adapter) |
225 | { | 225 | { |
226 | int error; | 226 | int error; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 20e82008b8b6..30798cbc6fc0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -758,10 +758,10 @@ static int i915_drm_resume(struct drm_device *dev) | |||
758 | dev_priv->display.hpd_irq_setup(dev); | 758 | dev_priv->display.hpd_irq_setup(dev); |
759 | spin_unlock_irq(&dev_priv->irq_lock); | 759 | spin_unlock_irq(&dev_priv->irq_lock); |
760 | 760 | ||
761 | intel_display_resume(dev); | ||
762 | |||
763 | intel_dp_mst_resume(dev); | 761 | intel_dp_mst_resume(dev); |
764 | 762 | ||
763 | intel_display_resume(dev); | ||
764 | |||
765 | /* | 765 | /* |
766 | * ... but also need to make sure that hotplug processing | 766 | * ... but also need to make sure that hotplug processing |
767 | * doesn't cause havoc. Like in the driver load code we don't | 767 | * doesn't cause havoc. Like in the driver load code we don't |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 10480939159c..daba7ebb9699 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -2634,8 +2634,9 @@ struct drm_i915_cmd_table { | |||
2634 | 2634 | ||
2635 | /* WaRsDisableCoarsePowerGating:skl,bxt */ | 2635 | /* WaRsDisableCoarsePowerGating:skl,bxt */ |
2636 | #define NEEDS_WaRsDisableCoarsePowerGating(dev) (IS_BXT_REVID(dev, 0, BXT_REVID_A1) || \ | 2636 | #define NEEDS_WaRsDisableCoarsePowerGating(dev) (IS_BXT_REVID(dev, 0, BXT_REVID_A1) || \ |
2637 | ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && \ | 2637 | IS_SKL_GT3(dev) || \ |
2638 | IS_SKL_REVID(dev, 0, SKL_REVID_F0))) | 2638 | IS_SKL_GT4(dev)) |
2639 | |||
2639 | /* | 2640 | /* |
2640 | * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts | 2641 | * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts |
2641 | * even when in MSI mode. This results in spurious interrupt warnings if the | 2642 | * even when in MSI mode. This results in spurious interrupt warnings if the |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3d31d3ac589e..dabc08987b5e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -177,7 +177,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) | |||
177 | drm_clflush_virt_range(vaddr, PAGE_SIZE); | 177 | drm_clflush_virt_range(vaddr, PAGE_SIZE); |
178 | kunmap_atomic(src); | 178 | kunmap_atomic(src); |
179 | 179 | ||
180 | page_cache_release(page); | 180 | put_page(page); |
181 | vaddr += PAGE_SIZE; | 181 | vaddr += PAGE_SIZE; |
182 | } | 182 | } |
183 | 183 | ||
@@ -243,7 +243,7 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj) | |||
243 | set_page_dirty(page); | 243 | set_page_dirty(page); |
244 | if (obj->madv == I915_MADV_WILLNEED) | 244 | if (obj->madv == I915_MADV_WILLNEED) |
245 | mark_page_accessed(page); | 245 | mark_page_accessed(page); |
246 | page_cache_release(page); | 246 | put_page(page); |
247 | vaddr += PAGE_SIZE; | 247 | vaddr += PAGE_SIZE; |
248 | } | 248 | } |
249 | obj->dirty = 0; | 249 | obj->dirty = 0; |
@@ -2206,7 +2206,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) | |||
2206 | if (obj->madv == I915_MADV_WILLNEED) | 2206 | if (obj->madv == I915_MADV_WILLNEED) |
2207 | mark_page_accessed(page); | 2207 | mark_page_accessed(page); |
2208 | 2208 | ||
2209 | page_cache_release(page); | 2209 | put_page(page); |
2210 | } | 2210 | } |
2211 | obj->dirty = 0; | 2211 | obj->dirty = 0; |
2212 | 2212 | ||
@@ -2346,7 +2346,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
2346 | err_pages: | 2346 | err_pages: |
2347 | sg_mark_end(sg); | 2347 | sg_mark_end(sg); |
2348 | for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) | 2348 | for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) |
2349 | page_cache_release(sg_page_iter_page(&sg_iter)); | 2349 | put_page(sg_page_iter_page(&sg_iter)); |
2350 | sg_free_table(st); | 2350 | sg_free_table(st); |
2351 | kfree(st); | 2351 | kfree(st); |
2352 | 2352 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 6be40f3ba2c7..4d30b60defda 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
@@ -501,19 +501,24 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) | |||
501 | if (pvec != NULL) { | 501 | if (pvec != NULL) { |
502 | struct mm_struct *mm = obj->userptr.mm->mm; | 502 | struct mm_struct *mm = obj->userptr.mm->mm; |
503 | 503 | ||
504 | down_read(&mm->mmap_sem); | 504 | ret = -EFAULT; |
505 | while (pinned < npages) { | 505 | if (atomic_inc_not_zero(&mm->mm_users)) { |
506 | ret = get_user_pages_remote(work->task, mm, | 506 | down_read(&mm->mmap_sem); |
507 | obj->userptr.ptr + pinned * PAGE_SIZE, | 507 | while (pinned < npages) { |
508 | npages - pinned, | 508 | ret = get_user_pages_remote |
509 | !obj->userptr.read_only, 0, | 509 | (work->task, mm, |
510 | pvec + pinned, NULL); | 510 | obj->userptr.ptr + pinned * PAGE_SIZE, |
511 | if (ret < 0) | 511 | npages - pinned, |
512 | break; | 512 | !obj->userptr.read_only, 0, |
513 | 513 | pvec + pinned, NULL); | |
514 | pinned += ret; | 514 | if (ret < 0) |
515 | break; | ||
516 | |||
517 | pinned += ret; | ||
518 | } | ||
519 | up_read(&mm->mmap_sem); | ||
520 | mmput(mm); | ||
515 | } | 521 | } |
516 | up_read(&mm->mmap_sem); | ||
517 | } | 522 | } |
518 | 523 | ||
519 | mutex_lock(&dev->struct_mutex); | 524 | mutex_lock(&dev->struct_mutex); |
@@ -683,7 +688,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) | |||
683 | set_page_dirty(page); | 688 | set_page_dirty(page); |
684 | 689 | ||
685 | mark_page_accessed(page); | 690 | mark_page_accessed(page); |
686 | page_cache_release(page); | 691 | put_page(page); |
687 | } | 692 | } |
688 | obj->dirty = 0; | 693 | obj->dirty = 0; |
689 | 694 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d1a46ef5ab3f..1c212205d0e7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1829,7 +1829,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) | |||
1829 | /* IRQs are synced during runtime_suspend, we don't require a wakeref */ | 1829 | /* IRQs are synced during runtime_suspend, we don't require a wakeref */ |
1830 | disable_rpm_wakeref_asserts(dev_priv); | 1830 | disable_rpm_wakeref_asserts(dev_priv); |
1831 | 1831 | ||
1832 | for (;;) { | 1832 | do { |
1833 | master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; | 1833 | master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; |
1834 | iir = I915_READ(VLV_IIR); | 1834 | iir = I915_READ(VLV_IIR); |
1835 | 1835 | ||
@@ -1857,7 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) | |||
1857 | 1857 | ||
1858 | I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL); | 1858 | I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL); |
1859 | POSTING_READ(GEN8_MASTER_IRQ); | 1859 | POSTING_READ(GEN8_MASTER_IRQ); |
1860 | } | 1860 | } while (0); |
1861 | 1861 | ||
1862 | enable_rpm_wakeref_asserts(dev_priv); | 1862 | enable_rpm_wakeref_asserts(dev_priv); |
1863 | 1863 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index a2bd698fe2f7..937e77228466 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
@@ -506,6 +506,8 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
506 | struct intel_connector *intel_connector = to_intel_connector(connector); | 506 | struct intel_connector *intel_connector = to_intel_connector(connector); |
507 | struct drm_device *dev = connector->dev; | 507 | struct drm_device *dev = connector->dev; |
508 | 508 | ||
509 | intel_connector->unregister(intel_connector); | ||
510 | |||
509 | /* need to nuke the connector */ | 511 | /* need to nuke the connector */ |
510 | drm_modeset_lock_all(dev); | 512 | drm_modeset_lock_all(dev); |
511 | if (connector->state->crtc) { | 513 | if (connector->state->crtc) { |
@@ -519,11 +521,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
519 | 521 | ||
520 | WARN(ret, "Disabling mst crtc failed with %i\n", ret); | 522 | WARN(ret, "Disabling mst crtc failed with %i\n", ret); |
521 | } | 523 | } |
522 | drm_modeset_unlock_all(dev); | ||
523 | 524 | ||
524 | intel_connector->unregister(intel_connector); | ||
525 | |||
526 | drm_modeset_lock_all(dev); | ||
527 | intel_connector_remove_from_fbdev(intel_connector); | 525 | intel_connector_remove_from_fbdev(intel_connector); |
528 | drm_connector_cleanup(connector); | 526 | drm_connector_cleanup(connector); |
529 | drm_modeset_unlock_all(dev); | 527 | drm_modeset_unlock_all(dev); |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6a978ce80244..5c6080fd0968 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -841,11 +841,11 @@ static int logical_ring_prepare(struct drm_i915_gem_request *req, int bytes) | |||
841 | if (unlikely(total_bytes > remain_usable)) { | 841 | if (unlikely(total_bytes > remain_usable)) { |
842 | /* | 842 | /* |
843 | * The base request will fit but the reserved space | 843 | * The base request will fit but the reserved space |
844 | * falls off the end. So only need to to wait for the | 844 | * falls off the end. So don't need an immediate wrap |
845 | * reserved size after flushing out the remainder. | 845 | * and only need to effectively wait for the reserved |
846 | * size space from the start of ringbuffer. | ||
846 | */ | 847 | */ |
847 | wait_bytes = remain_actual + ringbuf->reserved_size; | 848 | wait_bytes = remain_actual + ringbuf->reserved_size; |
848 | need_wrap = true; | ||
849 | } else if (total_bytes > ringbuf->space) { | 849 | } else if (total_bytes > ringbuf->space) { |
850 | /* No wrapping required, just waiting. */ | 850 | /* No wrapping required, just waiting. */ |
851 | wait_bytes = total_bytes; | 851 | wait_bytes = total_bytes; |
@@ -1913,15 +1913,18 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request) | |||
1913 | struct intel_ringbuffer *ringbuf = request->ringbuf; | 1913 | struct intel_ringbuffer *ringbuf = request->ringbuf; |
1914 | int ret; | 1914 | int ret; |
1915 | 1915 | ||
1916 | ret = intel_logical_ring_begin(request, 6 + WA_TAIL_DWORDS); | 1916 | ret = intel_logical_ring_begin(request, 8 + WA_TAIL_DWORDS); |
1917 | if (ret) | 1917 | if (ret) |
1918 | return ret; | 1918 | return ret; |
1919 | 1919 | ||
1920 | /* We're using qword write, seqno should be aligned to 8 bytes. */ | ||
1921 | BUILD_BUG_ON(I915_GEM_HWS_INDEX & 1); | ||
1922 | |||
1920 | /* w/a for post sync ops following a GPGPU operation we | 1923 | /* w/a for post sync ops following a GPGPU operation we |
1921 | * need a prior CS_STALL, which is emitted by the flush | 1924 | * need a prior CS_STALL, which is emitted by the flush |
1922 | * following the batch. | 1925 | * following the batch. |
1923 | */ | 1926 | */ |
1924 | intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(5)); | 1927 | intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6)); |
1925 | intel_logical_ring_emit(ringbuf, | 1928 | intel_logical_ring_emit(ringbuf, |
1926 | (PIPE_CONTROL_GLOBAL_GTT_IVB | | 1929 | (PIPE_CONTROL_GLOBAL_GTT_IVB | |
1927 | PIPE_CONTROL_CS_STALL | | 1930 | PIPE_CONTROL_CS_STALL | |
@@ -1929,7 +1932,10 @@ static int gen8_emit_request_render(struct drm_i915_gem_request *request) | |||
1929 | intel_logical_ring_emit(ringbuf, hws_seqno_address(request->ring)); | 1932 | intel_logical_ring_emit(ringbuf, hws_seqno_address(request->ring)); |
1930 | intel_logical_ring_emit(ringbuf, 0); | 1933 | intel_logical_ring_emit(ringbuf, 0); |
1931 | intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); | 1934 | intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); |
1935 | /* We're thrashing one dword of HWS. */ | ||
1936 | intel_logical_ring_emit(ringbuf, 0); | ||
1932 | intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); | 1937 | intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); |
1938 | intel_logical_ring_emit(ringbuf, MI_NOOP); | ||
1933 | return intel_logical_ring_advance_and_submit(request); | 1939 | return intel_logical_ring_advance_and_submit(request); |
1934 | } | 1940 | } |
1935 | 1941 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 30a8403a8f4f..cd9fe609aefb 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -478,11 +478,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
478 | * and as part of the cleanup in the hw state restore we also redisable | 478 | * and as part of the cleanup in the hw state restore we also redisable |
479 | * the vga plane. | 479 | * the vga plane. |
480 | */ | 480 | */ |
481 | if (!HAS_PCH_SPLIT(dev)) { | 481 | if (!HAS_PCH_SPLIT(dev)) |
482 | drm_modeset_lock_all(dev); | ||
483 | intel_display_resume(dev); | 482 | intel_display_resume(dev); |
484 | drm_modeset_unlock_all(dev); | ||
485 | } | ||
486 | 483 | ||
487 | dev_priv->modeset_restore = MODESET_DONE; | 484 | dev_priv->modeset_restore = MODESET_DONE; |
488 | 485 | ||
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 347d4df49a9b..8ed3cf34f82d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2876,25 +2876,28 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, | |||
2876 | const struct drm_plane_state *pstate, | 2876 | const struct drm_plane_state *pstate, |
2877 | int y) | 2877 | int y) |
2878 | { | 2878 | { |
2879 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); | 2879 | struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); |
2880 | struct drm_framebuffer *fb = pstate->fb; | 2880 | struct drm_framebuffer *fb = pstate->fb; |
2881 | uint32_t width = 0, height = 0; | ||
2882 | |||
2883 | width = drm_rect_width(&intel_pstate->src) >> 16; | ||
2884 | height = drm_rect_height(&intel_pstate->src) >> 16; | ||
2885 | |||
2886 | if (intel_rotation_90_or_270(pstate->rotation)) | ||
2887 | swap(width, height); | ||
2881 | 2888 | ||
2882 | /* for planar format */ | 2889 | /* for planar format */ |
2883 | if (fb->pixel_format == DRM_FORMAT_NV12) { | 2890 | if (fb->pixel_format == DRM_FORMAT_NV12) { |
2884 | if (y) /* y-plane data rate */ | 2891 | if (y) /* y-plane data rate */ |
2885 | return intel_crtc->config->pipe_src_w * | 2892 | return width * height * |
2886 | intel_crtc->config->pipe_src_h * | ||
2887 | drm_format_plane_cpp(fb->pixel_format, 0); | 2893 | drm_format_plane_cpp(fb->pixel_format, 0); |
2888 | else /* uv-plane data rate */ | 2894 | else /* uv-plane data rate */ |
2889 | return (intel_crtc->config->pipe_src_w/2) * | 2895 | return (width / 2) * (height / 2) * |
2890 | (intel_crtc->config->pipe_src_h/2) * | ||
2891 | drm_format_plane_cpp(fb->pixel_format, 1); | 2896 | drm_format_plane_cpp(fb->pixel_format, 1); |
2892 | } | 2897 | } |
2893 | 2898 | ||
2894 | /* for packed formats */ | 2899 | /* for packed formats */ |
2895 | return intel_crtc->config->pipe_src_w * | 2900 | return width * height * drm_format_plane_cpp(fb->pixel_format, 0); |
2896 | intel_crtc->config->pipe_src_h * | ||
2897 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
2898 | } | 2901 | } |
2899 | 2902 | ||
2900 | /* | 2903 | /* |
@@ -2973,8 +2976,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
2973 | struct drm_framebuffer *fb = plane->state->fb; | 2976 | struct drm_framebuffer *fb = plane->state->fb; |
2974 | int id = skl_wm_plane_id(intel_plane); | 2977 | int id = skl_wm_plane_id(intel_plane); |
2975 | 2978 | ||
2976 | if (fb == NULL) | 2979 | if (!to_intel_plane_state(plane->state)->visible) |
2977 | continue; | 2980 | continue; |
2981 | |||
2978 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | 2982 | if (plane->type == DRM_PLANE_TYPE_CURSOR) |
2979 | continue; | 2983 | continue; |
2980 | 2984 | ||
@@ -3000,7 +3004,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
3000 | uint16_t plane_blocks, y_plane_blocks = 0; | 3004 | uint16_t plane_blocks, y_plane_blocks = 0; |
3001 | int id = skl_wm_plane_id(intel_plane); | 3005 | int id = skl_wm_plane_id(intel_plane); |
3002 | 3006 | ||
3003 | if (pstate->fb == NULL) | 3007 | if (!to_intel_plane_state(pstate)->visible) |
3004 | continue; | 3008 | continue; |
3005 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | 3009 | if (plane->type == DRM_PLANE_TYPE_CURSOR) |
3006 | continue; | 3010 | continue; |
@@ -3123,26 +3127,36 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | |||
3123 | { | 3127 | { |
3124 | struct drm_plane *plane = &intel_plane->base; | 3128 | struct drm_plane *plane = &intel_plane->base; |
3125 | struct drm_framebuffer *fb = plane->state->fb; | 3129 | struct drm_framebuffer *fb = plane->state->fb; |
3130 | struct intel_plane_state *intel_pstate = | ||
3131 | to_intel_plane_state(plane->state); | ||
3126 | uint32_t latency = dev_priv->wm.skl_latency[level]; | 3132 | uint32_t latency = dev_priv->wm.skl_latency[level]; |
3127 | uint32_t method1, method2; | 3133 | uint32_t method1, method2; |
3128 | uint32_t plane_bytes_per_line, plane_blocks_per_line; | 3134 | uint32_t plane_bytes_per_line, plane_blocks_per_line; |
3129 | uint32_t res_blocks, res_lines; | 3135 | uint32_t res_blocks, res_lines; |
3130 | uint32_t selected_result; | 3136 | uint32_t selected_result; |
3131 | uint8_t cpp; | 3137 | uint8_t cpp; |
3138 | uint32_t width = 0, height = 0; | ||
3132 | 3139 | ||
3133 | if (latency == 0 || !cstate->base.active || !fb) | 3140 | if (latency == 0 || !cstate->base.active || !intel_pstate->visible) |
3134 | return false; | 3141 | return false; |
3135 | 3142 | ||
3143 | width = drm_rect_width(&intel_pstate->src) >> 16; | ||
3144 | height = drm_rect_height(&intel_pstate->src) >> 16; | ||
3145 | |||
3146 | if (intel_rotation_90_or_270(plane->state->rotation)) | ||
3147 | swap(width, height); | ||
3148 | |||
3136 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); | 3149 | cpp = drm_format_plane_cpp(fb->pixel_format, 0); |
3137 | method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), | 3150 | method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), |
3138 | cpp, latency); | 3151 | cpp, latency); |
3139 | method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), | 3152 | method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), |
3140 | cstate->base.adjusted_mode.crtc_htotal, | 3153 | cstate->base.adjusted_mode.crtc_htotal, |
3141 | cstate->pipe_src_w, | 3154 | width, |
3142 | cpp, fb->modifier[0], | 3155 | cpp, |
3156 | fb->modifier[0], | ||
3143 | latency); | 3157 | latency); |
3144 | 3158 | ||
3145 | plane_bytes_per_line = cstate->pipe_src_w * cpp; | 3159 | plane_bytes_per_line = width * cpp; |
3146 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); | 3160 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
3147 | 3161 | ||
3148 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || | 3162 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 45ce45a5e122..9121646d7c4d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -968,7 +968,7 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) | |||
968 | 968 | ||
969 | /* WaForceContextSaveRestoreNonCoherent:skl,bxt */ | 969 | /* WaForceContextSaveRestoreNonCoherent:skl,bxt */ |
970 | tmp = HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT; | 970 | tmp = HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT; |
971 | if (IS_SKL_REVID(dev, SKL_REVID_F0, SKL_REVID_F0) || | 971 | if (IS_SKL_REVID(dev, SKL_REVID_F0, REVID_FOREVER) || |
972 | IS_BXT_REVID(dev, BXT_REVID_B0, REVID_FOREVER)) | 972 | IS_BXT_REVID(dev, BXT_REVID_B0, REVID_FOREVER)) |
973 | tmp |= HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE; | 973 | tmp |= HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE; |
974 | WA_SET_BIT_MASKED(HDC_CHICKEN0, tmp); | 974 | WA_SET_BIT_MASKED(HDC_CHICKEN0, tmp); |
@@ -1085,7 +1085,8 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) | |||
1085 | WA_SET_BIT_MASKED(HIZ_CHICKEN, | 1085 | WA_SET_BIT_MASKED(HIZ_CHICKEN, |
1086 | BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); | 1086 | BDW_HIZ_POWER_COMPILER_CLOCK_GATING_DISABLE); |
1087 | 1087 | ||
1088 | if (IS_SKL_REVID(dev, 0, SKL_REVID_F0)) { | 1088 | /* This is tied to WaForceContextSaveRestoreNonCoherent */ |
1089 | if (IS_SKL_REVID(dev, 0, REVID_FOREVER)) { | ||
1089 | /* | 1090 | /* |
1090 | *Use Force Non-Coherent whenever executing a 3D context. This | 1091 | *Use Force Non-Coherent whenever executing a 3D context. This |
1091 | * is a workaround for a possible hang in the unlikely event | 1092 | * is a workaround for a possible hang in the unlikely event |
@@ -2090,10 +2091,12 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, | |||
2090 | { | 2091 | { |
2091 | struct drm_i915_private *dev_priv = to_i915(dev); | 2092 | struct drm_i915_private *dev_priv = to_i915(dev); |
2092 | struct drm_i915_gem_object *obj = ringbuf->obj; | 2093 | struct drm_i915_gem_object *obj = ringbuf->obj; |
2094 | /* Ring wraparound at offset 0 sometimes hangs. No idea why. */ | ||
2095 | unsigned flags = PIN_OFFSET_BIAS | 4096; | ||
2093 | int ret; | 2096 | int ret; |
2094 | 2097 | ||
2095 | if (HAS_LLC(dev_priv) && !obj->stolen) { | 2098 | if (HAS_LLC(dev_priv) && !obj->stolen) { |
2096 | ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, 0); | 2099 | ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, flags); |
2097 | if (ret) | 2100 | if (ret) |
2098 | return ret; | 2101 | return ret; |
2099 | 2102 | ||
@@ -2109,7 +2112,8 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, | |||
2109 | return -ENOMEM; | 2112 | return -ENOMEM; |
2110 | } | 2113 | } |
2111 | } else { | 2114 | } else { |
2112 | ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE); | 2115 | ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, |
2116 | flags | PIN_MAPPABLE); | ||
2113 | if (ret) | 2117 | if (ret) |
2114 | return ret; | 2118 | return ret; |
2115 | 2119 | ||
@@ -2454,11 +2458,11 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring, int bytes) | |||
2454 | if (unlikely(total_bytes > remain_usable)) { | 2458 | if (unlikely(total_bytes > remain_usable)) { |
2455 | /* | 2459 | /* |
2456 | * The base request will fit but the reserved space | 2460 | * The base request will fit but the reserved space |
2457 | * falls off the end. So only need to to wait for the | 2461 | * falls off the end. So don't need an immediate wrap |
2458 | * reserved size after flushing out the remainder. | 2462 | * and only need to effectively wait for the reserved |
2463 | * size space from the start of ringbuffer. | ||
2459 | */ | 2464 | */ |
2460 | wait_bytes = remain_actual + ringbuf->reserved_size; | 2465 | wait_bytes = remain_actual + ringbuf->reserved_size; |
2461 | need_wrap = true; | ||
2462 | } else if (total_bytes > ringbuf->space) { | 2466 | } else if (total_bytes > ringbuf->space) { |
2463 | /* No wrapping required, just waiting. */ | 2467 | /* No wrapping required, just waiting. */ |
2464 | wait_bytes = total_bytes; | 2468 | wait_bytes = total_bytes; |
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 436d8f2b8682..68b6f69aa682 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
@@ -1189,7 +1189,11 @@ static void intel_uncore_fw_domains_init(struct drm_device *dev) | |||
1189 | } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { | 1189 | } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
1190 | dev_priv->uncore.funcs.force_wake_get = | 1190 | dev_priv->uncore.funcs.force_wake_get = |
1191 | fw_domains_get_with_thread_status; | 1191 | fw_domains_get_with_thread_status; |
1192 | dev_priv->uncore.funcs.force_wake_put = fw_domains_put; | 1192 | if (IS_HASWELL(dev)) |
1193 | dev_priv->uncore.funcs.force_wake_put = | ||
1194 | fw_domains_put_with_fifo; | ||
1195 | else | ||
1196 | dev_priv->uncore.funcs.force_wake_put = fw_domains_put; | ||
1193 | fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, | 1197 | fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, |
1194 | FORCEWAKE_MT, FORCEWAKE_ACK_HSW); | 1198 | FORCEWAKE_MT, FORCEWAKE_ACK_HSW); |
1195 | } else if (IS_IVYBRIDGE(dev)) { | 1199 | } else if (IS_IVYBRIDGE(dev)) { |
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index 2a95d10e9d92..a24631fdf4ad 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c | |||
@@ -225,8 +225,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, | |||
225 | if (!iores) | 225 | if (!iores) |
226 | return -ENXIO; | 226 | return -ENXIO; |
227 | 227 | ||
228 | platform_set_drvdata(pdev, hdmi); | ||
229 | |||
230 | encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); | 228 | encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); |
231 | /* | 229 | /* |
232 | * If we failed to find the CRTC(s) which this encoder is | 230 | * If we failed to find the CRTC(s) which this encoder is |
@@ -245,7 +243,16 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, | |||
245 | drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, | 243 | drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, |
246 | DRM_MODE_ENCODER_TMDS, NULL); | 244 | DRM_MODE_ENCODER_TMDS, NULL); |
247 | 245 | ||
248 | return dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data); | 246 | ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data); |
247 | |||
248 | /* | ||
249 | * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), | ||
250 | * which would have called the encoder cleanup. Do it manually. | ||
251 | */ | ||
252 | if (ret) | ||
253 | drm_encoder_cleanup(encoder); | ||
254 | |||
255 | return ret; | ||
249 | } | 256 | } |
250 | 257 | ||
251 | static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, | 258 | static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, |
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 9876e0f0c3e1..e26dcdec2aba 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |||
@@ -326,7 +326,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, | |||
326 | { | 326 | { |
327 | struct imx_drm_device *imxdrm = drm->dev_private; | 327 | struct imx_drm_device *imxdrm = drm->dev_private; |
328 | struct imx_drm_crtc *imx_drm_crtc; | 328 | struct imx_drm_crtc *imx_drm_crtc; |
329 | int ret; | ||
330 | 329 | ||
331 | /* | 330 | /* |
332 | * The vblank arrays are dimensioned by MAX_CRTC - we can't | 331 | * The vblank arrays are dimensioned by MAX_CRTC - we can't |
@@ -351,10 +350,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, | |||
351 | 350 | ||
352 | *new_crtc = imx_drm_crtc; | 351 | *new_crtc = imx_drm_crtc; |
353 | 352 | ||
354 | ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256); | ||
355 | if (ret) | ||
356 | goto err_register; | ||
357 | |||
358 | drm_crtc_helper_add(crtc, | 353 | drm_crtc_helper_add(crtc, |
359 | imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); | 354 | imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); |
360 | 355 | ||
@@ -362,11 +357,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, | |||
362 | imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs, NULL); | 357 | imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs, NULL); |
363 | 358 | ||
364 | return 0; | 359 | return 0; |
365 | |||
366 | err_register: | ||
367 | imxdrm->crtc[--imxdrm->pipes] = NULL; | ||
368 | kfree(imx_drm_crtc); | ||
369 | return ret; | ||
370 | } | 360 | } |
371 | EXPORT_SYMBOL_GPL(imx_drm_add_crtc); | 361 | EXPORT_SYMBOL_GPL(imx_drm_add_crtc); |
372 | 362 | ||
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 588827844f30..681ec6eb77d9 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c | |||
@@ -72,22 +72,101 @@ static inline int calc_bandwidth(int width, int height, unsigned int vref) | |||
72 | int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, | 72 | int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, |
73 | int x, int y) | 73 | int x, int y) |
74 | { | 74 | { |
75 | struct drm_gem_cma_object *cma_obj; | 75 | struct drm_gem_cma_object *cma_obj[3]; |
76 | unsigned long eba; | 76 | unsigned long eba, ubo, vbo; |
77 | int active; | 77 | int active, i; |
78 | 78 | ||
79 | cma_obj = drm_fb_cma_get_gem_obj(fb, 0); | 79 | for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { |
80 | if (!cma_obj) { | 80 | cma_obj[i] = drm_fb_cma_get_gem_obj(fb, i); |
81 | DRM_DEBUG_KMS("entry is null.\n"); | 81 | if (!cma_obj[i]) { |
82 | return -EFAULT; | 82 | DRM_DEBUG_KMS("plane %d entry is null.\n", i); |
83 | return -EFAULT; | ||
84 | } | ||
83 | } | 85 | } |
84 | 86 | ||
85 | dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d", | 87 | eba = cma_obj[0]->paddr + fb->offsets[0] + |
86 | &cma_obj->paddr, x, y); | ||
87 | |||
88 | eba = cma_obj->paddr + fb->offsets[0] + | ||
89 | fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; | 88 | fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; |
90 | 89 | ||
90 | if (eba & 0x7) { | ||
91 | DRM_DEBUG_KMS("base address must be a multiple of 8.\n"); | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
95 | if (fb->pitches[0] < 1 || fb->pitches[0] > 16384) { | ||
96 | DRM_DEBUG_KMS("pitches out of range.\n"); | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
100 | if (ipu_plane->enabled && fb->pitches[0] != ipu_plane->stride[0]) { | ||
101 | DRM_DEBUG_KMS("pitches must not change while plane is enabled.\n"); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | |||
105 | ipu_plane->stride[0] = fb->pitches[0]; | ||
106 | |||
107 | switch (fb->pixel_format) { | ||
108 | case DRM_FORMAT_YUV420: | ||
109 | case DRM_FORMAT_YVU420: | ||
110 | /* | ||
111 | * Multiplanar formats have to meet the following restrictions: | ||
112 | * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO | ||
113 | * - EBA, UBO and VBO are a multiple of 8 | ||
114 | * - UBO and VBO are unsigned and not larger than 0xfffff8 | ||
115 | * - Only EBA may be changed while scanout is active | ||
116 | * - The strides of U and V planes must be identical. | ||
117 | */ | ||
118 | ubo = cma_obj[1]->paddr + fb->offsets[1] + | ||
119 | fb->pitches[1] * y / 2 + x / 2 - eba; | ||
120 | vbo = cma_obj[2]->paddr + fb->offsets[2] + | ||
121 | fb->pitches[2] * y / 2 + x / 2 - eba; | ||
122 | |||
123 | if ((ubo & 0x7) || (vbo & 0x7)) { | ||
124 | DRM_DEBUG_KMS("U/V buffer offsets must be a multiple of 8.\n"); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | |||
128 | if ((ubo > 0xfffff8) || (vbo > 0xfffff8)) { | ||
129 | DRM_DEBUG_KMS("U/V buffer offsets must be positive and not larger than 0xfffff8.\n"); | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | |||
133 | if (ipu_plane->enabled && ((ipu_plane->u_offset != ubo) || | ||
134 | (ipu_plane->v_offset != vbo))) { | ||
135 | DRM_DEBUG_KMS("U/V buffer offsets must not change while plane is enabled.\n"); | ||
136 | return -EINVAL; | ||
137 | } | ||
138 | |||
139 | if (fb->pitches[1] != fb->pitches[2]) { | ||
140 | DRM_DEBUG_KMS("U/V pitches must be identical.\n"); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | |||
144 | if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) { | ||
145 | DRM_DEBUG_KMS("U/V pitches out of range.\n"); | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | |||
149 | if (ipu_plane->enabled && | ||
150 | (ipu_plane->stride[1] != fb->pitches[1])) { | ||
151 | DRM_DEBUG_KMS("U/V pitches must not change while plane is enabled.\n"); | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | ipu_plane->u_offset = ubo; | ||
156 | ipu_plane->v_offset = vbo; | ||
157 | ipu_plane->stride[1] = fb->pitches[1]; | ||
158 | |||
159 | dev_dbg(ipu_plane->base.dev->dev, | ||
160 | "phys = %pad %pad %pad, x = %d, y = %d", | ||
161 | &cma_obj[0]->paddr, &cma_obj[1]->paddr, | ||
162 | &cma_obj[2]->paddr, x, y); | ||
163 | break; | ||
164 | default: | ||
165 | dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d", | ||
166 | &cma_obj[0]->paddr, x, y); | ||
167 | break; | ||
168 | } | ||
169 | |||
91 | if (ipu_plane->enabled) { | 170 | if (ipu_plane->enabled) { |
92 | active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); | 171 | active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); |
93 | ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); | 172 | ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); |
@@ -201,12 +280,6 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, | |||
201 | } | 280 | } |
202 | } | 281 | } |
203 | 282 | ||
204 | ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w); | ||
205 | if (ret) { | ||
206 | dev_err(dev, "initializing dmfc channel failed with %d\n", ret); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc, | 283 | ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc, |
211 | calc_bandwidth(crtc_w, crtc_h, | 284 | calc_bandwidth(crtc_w, crtc_h, |
212 | calc_vref(mode)), 64); | 285 | calc_vref(mode)), 64); |
@@ -215,6 +288,8 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, | |||
215 | return ret; | 288 | return ret; |
216 | } | 289 | } |
217 | 290 | ||
291 | ipu_dmfc_config_wait4eot(ipu_plane->dmfc, crtc_w); | ||
292 | |||
218 | ipu_cpmem_zero(ipu_plane->ipu_ch); | 293 | ipu_cpmem_zero(ipu_plane->ipu_ch); |
219 | ipu_cpmem_set_resolution(ipu_plane->ipu_ch, src_w, src_h); | 294 | ipu_cpmem_set_resolution(ipu_plane->ipu_ch, src_w, src_h); |
220 | ret = ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->pixel_format); | 295 | ret = ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->pixel_format); |
@@ -233,6 +308,18 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, | |||
233 | if (interlaced) | 308 | if (interlaced) |
234 | ipu_cpmem_interlaced_scan(ipu_plane->ipu_ch, fb->pitches[0]); | 309 | ipu_cpmem_interlaced_scan(ipu_plane->ipu_ch, fb->pitches[0]); |
235 | 310 | ||
311 | if (fb->pixel_format == DRM_FORMAT_YUV420) { | ||
312 | ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, | ||
313 | ipu_plane->stride[1], | ||
314 | ipu_plane->u_offset, | ||
315 | ipu_plane->v_offset); | ||
316 | } else if (fb->pixel_format == DRM_FORMAT_YVU420) { | ||
317 | ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, | ||
318 | ipu_plane->stride[1], | ||
319 | ipu_plane->v_offset, | ||
320 | ipu_plane->u_offset); | ||
321 | } | ||
322 | |||
236 | ipu_plane->w = src_w; | 323 | ipu_plane->w = src_w; |
237 | ipu_plane->h = src_h; | 324 | ipu_plane->h = src_h; |
238 | 325 | ||
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h index 3a443b413c60..4448fd4ad4eb 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.h +++ b/drivers/gpu/drm/imx/ipuv3-plane.h | |||
@@ -29,6 +29,10 @@ struct ipu_plane { | |||
29 | int w; | 29 | int w; |
30 | int h; | 30 | int h; |
31 | 31 | ||
32 | unsigned int u_offset; | ||
33 | unsigned int v_offset; | ||
34 | unsigned int stride[2]; | ||
35 | |||
32 | bool enabled; | 36 | bool enabled; |
33 | }; | 37 | }; |
34 | 38 | ||
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h index 16641cec18a2..b5370cb56e3c 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h | |||
@@ -11,6 +11,7 @@ struct nvkm_device_tegra { | |||
11 | 11 | ||
12 | struct reset_control *rst; | 12 | struct reset_control *rst; |
13 | struct clk *clk; | 13 | struct clk *clk; |
14 | struct clk *clk_ref; | ||
14 | struct clk *clk_pwr; | 15 | struct clk *clk_pwr; |
15 | 16 | ||
16 | struct regulator *vdd; | 17 | struct regulator *vdd; |
@@ -36,6 +37,10 @@ struct nvkm_device_tegra_func { | |||
36 | * bypassed). A value of 0 means an IOMMU is never used. | 37 | * bypassed). A value of 0 means an IOMMU is never used. |
37 | */ | 38 | */ |
38 | u8 iommu_bit; | 39 | u8 iommu_bit; |
40 | /* | ||
41 | * Whether the chip requires a reference clock | ||
42 | */ | ||
43 | bool require_ref_clk; | ||
39 | }; | 44 | }; |
40 | 45 | ||
41 | int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *, | 46 | int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index ae96ebc490fb..e81aefe5ffa7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -1276,18 +1276,18 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
1276 | break; | 1276 | break; |
1277 | default: | 1277 | default: |
1278 | if (disp->dithering_mode) { | 1278 | if (disp->dithering_mode) { |
1279 | nv_connector->dithering_mode = DITHERING_MODE_AUTO; | ||
1279 | drm_object_attach_property(&connector->base, | 1280 | drm_object_attach_property(&connector->base, |
1280 | disp->dithering_mode, | 1281 | disp->dithering_mode, |
1281 | nv_connector-> | 1282 | nv_connector-> |
1282 | dithering_mode); | 1283 | dithering_mode); |
1283 | nv_connector->dithering_mode = DITHERING_MODE_AUTO; | ||
1284 | } | 1284 | } |
1285 | if (disp->dithering_depth) { | 1285 | if (disp->dithering_depth) { |
1286 | nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; | ||
1286 | drm_object_attach_property(&connector->base, | 1287 | drm_object_attach_property(&connector->base, |
1287 | disp->dithering_depth, | 1288 | disp->dithering_depth, |
1288 | nv_connector-> | 1289 | nv_connector-> |
1289 | dithering_depth); | 1290 | dithering_depth); |
1290 | nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; | ||
1291 | } | 1291 | } |
1292 | break; | 1292 | break; |
1293 | } | 1293 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c index 2dfe58af12e4..4c4cc2260257 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.c +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c | |||
@@ -55,6 +55,11 @@ static const struct nvkm_device_tegra_func gk20a_platform_data = { | |||
55 | .iommu_bit = 34, | 55 | .iommu_bit = 34, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static const struct nvkm_device_tegra_func gm20b_platform_data = { | ||
59 | .iommu_bit = 34, | ||
60 | .require_ref_clk = true, | ||
61 | }; | ||
62 | |||
58 | static const struct of_device_id nouveau_platform_match[] = { | 63 | static const struct of_device_id nouveau_platform_match[] = { |
59 | { | 64 | { |
60 | .compatible = "nvidia,gk20a", | 65 | .compatible = "nvidia,gk20a", |
@@ -62,7 +67,7 @@ static const struct of_device_id nouveau_platform_match[] = { | |||
62 | }, | 67 | }, |
63 | { | 68 | { |
64 | .compatible = "nvidia,gm20b", | 69 | .compatible = "nvidia,gm20b", |
65 | .data = &gk20a_platform_data, | 70 | .data = &gm20b_platform_data, |
66 | }, | 71 | }, |
67 | { } | 72 | { } |
68 | }; | 73 | }; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 9afa5f3e3c1c..ec12efb4689a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | |||
@@ -35,6 +35,11 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) | |||
35 | ret = clk_prepare_enable(tdev->clk); | 35 | ret = clk_prepare_enable(tdev->clk); |
36 | if (ret) | 36 | if (ret) |
37 | goto err_clk; | 37 | goto err_clk; |
38 | if (tdev->clk_ref) { | ||
39 | ret = clk_prepare_enable(tdev->clk_ref); | ||
40 | if (ret) | ||
41 | goto err_clk_ref; | ||
42 | } | ||
38 | ret = clk_prepare_enable(tdev->clk_pwr); | 43 | ret = clk_prepare_enable(tdev->clk_pwr); |
39 | if (ret) | 44 | if (ret) |
40 | goto err_clk_pwr; | 45 | goto err_clk_pwr; |
@@ -57,6 +62,9 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) | |||
57 | err_clamp: | 62 | err_clamp: |
58 | clk_disable_unprepare(tdev->clk_pwr); | 63 | clk_disable_unprepare(tdev->clk_pwr); |
59 | err_clk_pwr: | 64 | err_clk_pwr: |
65 | if (tdev->clk_ref) | ||
66 | clk_disable_unprepare(tdev->clk_ref); | ||
67 | err_clk_ref: | ||
60 | clk_disable_unprepare(tdev->clk); | 68 | clk_disable_unprepare(tdev->clk); |
61 | err_clk: | 69 | err_clk: |
62 | regulator_disable(tdev->vdd); | 70 | regulator_disable(tdev->vdd); |
@@ -71,6 +79,8 @@ nvkm_device_tegra_power_down(struct nvkm_device_tegra *tdev) | |||
71 | udelay(10); | 79 | udelay(10); |
72 | 80 | ||
73 | clk_disable_unprepare(tdev->clk_pwr); | 81 | clk_disable_unprepare(tdev->clk_pwr); |
82 | if (tdev->clk_ref) | ||
83 | clk_disable_unprepare(tdev->clk_ref); | ||
74 | clk_disable_unprepare(tdev->clk); | 84 | clk_disable_unprepare(tdev->clk); |
75 | udelay(10); | 85 | udelay(10); |
76 | 86 | ||
@@ -274,6 +284,13 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, | |||
274 | goto free; | 284 | goto free; |
275 | } | 285 | } |
276 | 286 | ||
287 | if (func->require_ref_clk) | ||
288 | tdev->clk_ref = devm_clk_get(&pdev->dev, "ref"); | ||
289 | if (IS_ERR(tdev->clk_ref)) { | ||
290 | ret = PTR_ERR(tdev->clk_ref); | ||
291 | goto free; | ||
292 | } | ||
293 | |||
277 | tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr"); | 294 | tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr"); |
278 | if (IS_ERR(tdev->clk_pwr)) { | 295 | if (IS_ERR(tdev->clk_pwr)) { |
279 | ret = PTR_ERR(tdev->clk_pwr); | 296 | ret = PTR_ERR(tdev->clk_pwr); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index c56a886229f1..b2de290da16f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | |||
@@ -1832,6 +1832,8 @@ gf100_gr_init(struct gf100_gr *gr) | |||
1832 | 1832 | ||
1833 | gf100_gr_mmio(gr, gr->func->mmio); | 1833 | gf100_gr_mmio(gr, gr->func->mmio); |
1834 | 1834 | ||
1835 | nvkm_mask(device, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001); | ||
1836 | |||
1835 | memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); | 1837 | memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); |
1836 | for (i = 0, gpc = -1; i < gr->tpc_total; i++) { | 1838 | for (i = 0, gpc = -1; i < gr->tpc_total; i++) { |
1837 | do { | 1839 | do { |
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 43e5f503d1c5..030409a3ee4e 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c | |||
@@ -375,10 +375,15 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, | |||
375 | 375 | ||
376 | qxl_bo_kunmap(user_bo); | 376 | qxl_bo_kunmap(user_bo); |
377 | 377 | ||
378 | qcrtc->cur_x += qcrtc->hot_spot_x - hot_x; | ||
379 | qcrtc->cur_y += qcrtc->hot_spot_y - hot_y; | ||
380 | qcrtc->hot_spot_x = hot_x; | ||
381 | qcrtc->hot_spot_y = hot_y; | ||
382 | |||
378 | cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); | 383 | cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); |
379 | cmd->type = QXL_CURSOR_SET; | 384 | cmd->type = QXL_CURSOR_SET; |
380 | cmd->u.set.position.x = qcrtc->cur_x; | 385 | cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; |
381 | cmd->u.set.position.y = qcrtc->cur_y; | 386 | cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; |
382 | 387 | ||
383 | cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0); | 388 | cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0); |
384 | 389 | ||
@@ -441,8 +446,8 @@ static int qxl_crtc_cursor_move(struct drm_crtc *crtc, | |||
441 | 446 | ||
442 | cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); | 447 | cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); |
443 | cmd->type = QXL_CURSOR_MOVE; | 448 | cmd->type = QXL_CURSOR_MOVE; |
444 | cmd->u.position.x = qcrtc->cur_x; | 449 | cmd->u.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; |
445 | cmd->u.position.y = qcrtc->cur_y; | 450 | cmd->u.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; |
446 | qxl_release_unmap(qdev, release, &cmd->release_info); | 451 | qxl_release_unmap(qdev, release, &cmd->release_info); |
447 | 452 | ||
448 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | 453 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); |
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 6e6b9b1519b8..3f3897eb458c 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h | |||
@@ -135,6 +135,8 @@ struct qxl_crtc { | |||
135 | int index; | 135 | int index; |
136 | int cur_x; | 136 | int cur_x; |
137 | int cur_y; | 137 | int cur_y; |
138 | int hot_spot_x; | ||
139 | int hot_spot_y; | ||
138 | }; | 140 | }; |
139 | 141 | ||
140 | struct qxl_output { | 142 | struct qxl_output { |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index cf61e0856f4a..b80b08f71cb4 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -275,13 +275,15 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
275 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) | 275 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
276 | atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); | 276 | atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); |
277 | atombios_blank_crtc(crtc, ATOM_DISABLE); | 277 | atombios_blank_crtc(crtc, ATOM_DISABLE); |
278 | drm_vblank_on(dev, radeon_crtc->crtc_id); | 278 | if (dev->num_crtcs > radeon_crtc->crtc_id) |
279 | drm_vblank_on(dev, radeon_crtc->crtc_id); | ||
279 | radeon_crtc_load_lut(crtc); | 280 | radeon_crtc_load_lut(crtc); |
280 | break; | 281 | break; |
281 | case DRM_MODE_DPMS_STANDBY: | 282 | case DRM_MODE_DPMS_STANDBY: |
282 | case DRM_MODE_DPMS_SUSPEND: | 283 | case DRM_MODE_DPMS_SUSPEND: |
283 | case DRM_MODE_DPMS_OFF: | 284 | case DRM_MODE_DPMS_OFF: |
284 | drm_vblank_off(dev, radeon_crtc->crtc_id); | 285 | if (dev->num_crtcs > radeon_crtc->crtc_id) |
286 | drm_vblank_off(dev, radeon_crtc->crtc_id); | ||
285 | if (radeon_crtc->enabled) | 287 | if (radeon_crtc->enabled) |
286 | atombios_blank_crtc(crtc, ATOM_ENABLE); | 288 | atombios_blank_crtc(crtc, ATOM_ENABLE); |
287 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) | 289 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 76c4bdf21b20..34f7a29d9366 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2608,10 +2608,152 @@ static void evergreen_agp_enable(struct radeon_device *rdev) | |||
2608 | WREG32(VM_CONTEXT1_CNTL, 0); | 2608 | WREG32(VM_CONTEXT1_CNTL, 0); |
2609 | } | 2609 | } |
2610 | 2610 | ||
2611 | static const unsigned ni_dig_offsets[] = | ||
2612 | { | ||
2613 | NI_DIG0_REGISTER_OFFSET, | ||
2614 | NI_DIG1_REGISTER_OFFSET, | ||
2615 | NI_DIG2_REGISTER_OFFSET, | ||
2616 | NI_DIG3_REGISTER_OFFSET, | ||
2617 | NI_DIG4_REGISTER_OFFSET, | ||
2618 | NI_DIG5_REGISTER_OFFSET | ||
2619 | }; | ||
2620 | |||
2621 | static const unsigned ni_tx_offsets[] = | ||
2622 | { | ||
2623 | NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1, | ||
2624 | NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1, | ||
2625 | NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1, | ||
2626 | NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1, | ||
2627 | NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1, | ||
2628 | NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 | ||
2629 | }; | ||
2630 | |||
2631 | static const unsigned evergreen_dp_offsets[] = | ||
2632 | { | ||
2633 | EVERGREEN_DP0_REGISTER_OFFSET, | ||
2634 | EVERGREEN_DP1_REGISTER_OFFSET, | ||
2635 | EVERGREEN_DP2_REGISTER_OFFSET, | ||
2636 | EVERGREEN_DP3_REGISTER_OFFSET, | ||
2637 | EVERGREEN_DP4_REGISTER_OFFSET, | ||
2638 | EVERGREEN_DP5_REGISTER_OFFSET | ||
2639 | }; | ||
2640 | |||
2641 | |||
2642 | /* | ||
2643 | * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc | ||
2644 | * We go from crtc to connector and it is not relible since it | ||
2645 | * should be an opposite direction .If crtc is enable then | ||
2646 | * find the dig_fe which selects this crtc and insure that it enable. | ||
2647 | * if such dig_fe is found then find dig_be which selects found dig_be and | ||
2648 | * insure that it enable and in DP_SST mode. | ||
2649 | * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing | ||
2650 | * from dp symbols clocks . | ||
2651 | */ | ||
2652 | static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev, | ||
2653 | unsigned crtc_id, unsigned *ret_dig_fe) | ||
2654 | { | ||
2655 | unsigned i; | ||
2656 | unsigned dig_fe; | ||
2657 | unsigned dig_be; | ||
2658 | unsigned dig_en_be; | ||
2659 | unsigned uniphy_pll; | ||
2660 | unsigned digs_fe_selected; | ||
2661 | unsigned dig_be_mode; | ||
2662 | unsigned dig_fe_mask; | ||
2663 | bool is_enabled = false; | ||
2664 | bool found_crtc = false; | ||
2665 | |||
2666 | /* loop through all running dig_fe to find selected crtc */ | ||
2667 | for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { | ||
2668 | dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]); | ||
2669 | if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON && | ||
2670 | crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) { | ||
2671 | /* found running pipe */ | ||
2672 | found_crtc = true; | ||
2673 | dig_fe_mask = 1 << i; | ||
2674 | dig_fe = i; | ||
2675 | break; | ||
2676 | } | ||
2677 | } | ||
2678 | |||
2679 | if (found_crtc) { | ||
2680 | /* loop through all running dig_be to find selected dig_fe */ | ||
2681 | for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { | ||
2682 | dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]); | ||
2683 | /* if dig_fe_selected by dig_be? */ | ||
2684 | digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be); | ||
2685 | dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be); | ||
2686 | if (dig_fe_mask & digs_fe_selected && | ||
2687 | /* if dig_be in sst mode? */ | ||
2688 | dig_be_mode == NI_DIG_BE_DPSST) { | ||
2689 | dig_en_be = RREG32(NI_DIG_BE_EN_CNTL + | ||
2690 | ni_dig_offsets[i]); | ||
2691 | uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 + | ||
2692 | ni_tx_offsets[i]); | ||
2693 | /* dig_be enable and tx is running */ | ||
2694 | if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE && | ||
2695 | dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON && | ||
2696 | uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) { | ||
2697 | is_enabled = true; | ||
2698 | *ret_dig_fe = dig_fe; | ||
2699 | break; | ||
2700 | } | ||
2701 | } | ||
2702 | } | ||
2703 | } | ||
2704 | |||
2705 | return is_enabled; | ||
2706 | } | ||
2707 | |||
2708 | /* | ||
2709 | * Blank dig when in dp sst mode | ||
2710 | * Dig ignores crtc timing | ||
2711 | */ | ||
2712 | static void evergreen_blank_dp_output(struct radeon_device *rdev, | ||
2713 | unsigned dig_fe) | ||
2714 | { | ||
2715 | unsigned stream_ctrl; | ||
2716 | unsigned fifo_ctrl; | ||
2717 | unsigned counter = 0; | ||
2718 | |||
2719 | if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) { | ||
2720 | DRM_ERROR("invalid dig_fe %d\n", dig_fe); | ||
2721 | return; | ||
2722 | } | ||
2723 | |||
2724 | stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | ||
2725 | evergreen_dp_offsets[dig_fe]); | ||
2726 | if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) { | ||
2727 | DRM_ERROR("dig %d , should be enable\n", dig_fe); | ||
2728 | return; | ||
2729 | } | ||
2730 | |||
2731 | stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE; | ||
2732 | WREG32(EVERGREEN_DP_VID_STREAM_CNTL + | ||
2733 | evergreen_dp_offsets[dig_fe], stream_ctrl); | ||
2734 | |||
2735 | stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | ||
2736 | evergreen_dp_offsets[dig_fe]); | ||
2737 | while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) { | ||
2738 | msleep(1); | ||
2739 | counter++; | ||
2740 | stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + | ||
2741 | evergreen_dp_offsets[dig_fe]); | ||
2742 | } | ||
2743 | if (counter >= 32 ) | ||
2744 | DRM_ERROR("counter exceeds %d\n", counter); | ||
2745 | |||
2746 | fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]); | ||
2747 | fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET; | ||
2748 | WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl); | ||
2749 | |||
2750 | } | ||
2751 | |||
2611 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 2752 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
2612 | { | 2753 | { |
2613 | u32 crtc_enabled, tmp, frame_count, blackout; | 2754 | u32 crtc_enabled, tmp, frame_count, blackout; |
2614 | int i, j; | 2755 | int i, j; |
2756 | unsigned dig_fe; | ||
2615 | 2757 | ||
2616 | if (!ASIC_IS_NODCE(rdev)) { | 2758 | if (!ASIC_IS_NODCE(rdev)) { |
2617 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 2759 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
@@ -2651,7 +2793,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
2651 | break; | 2793 | break; |
2652 | udelay(1); | 2794 | udelay(1); |
2653 | } | 2795 | } |
2654 | 2796 | /*we should disable dig if it drives dp sst*/ | |
2797 | /*but we are in radeon_device_init and the topology is unknown*/ | ||
2798 | /*and it is available after radeon_modeset_init*/ | ||
2799 | /*the following method radeon_atom_encoder_dpms_dig*/ | ||
2800 | /*does the job if we initialize it properly*/ | ||
2801 | /*for now we do it this manually*/ | ||
2802 | /**/ | ||
2803 | if (ASIC_IS_DCE5(rdev) && | ||
2804 | evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe)) | ||
2805 | evergreen_blank_dp_output(rdev, dig_fe); | ||
2806 | /*we could remove 6 lines below*/ | ||
2655 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ | 2807 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ |
2656 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); | 2808 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); |
2657 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); | 2809 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index aa939dfed3a3..b436badf9efa 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -250,8 +250,43 @@ | |||
250 | 250 | ||
251 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ | 251 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ |
252 | #define EVERGREEN_HDMI_BASE 0x7030 | 252 | #define EVERGREEN_HDMI_BASE 0x7030 |
253 | /*DIG block*/ | ||
254 | #define NI_DIG0_REGISTER_OFFSET (0x7000 - 0x7000) | ||
255 | #define NI_DIG1_REGISTER_OFFSET (0x7C00 - 0x7000) | ||
256 | #define NI_DIG2_REGISTER_OFFSET (0x10800 - 0x7000) | ||
257 | #define NI_DIG3_REGISTER_OFFSET (0x11400 - 0x7000) | ||
258 | #define NI_DIG4_REGISTER_OFFSET (0x12000 - 0x7000) | ||
259 | #define NI_DIG5_REGISTER_OFFSET (0x12C00 - 0x7000) | ||
260 | |||
261 | |||
262 | #define NI_DIG_FE_CNTL 0x7000 | ||
263 | # define NI_DIG_FE_CNTL_SOURCE_SELECT(x) ((x) & 0x3) | ||
264 | # define NI_DIG_FE_CNTL_SYMCLK_FE_ON (1<<24) | ||
265 | |||
266 | |||
267 | #define NI_DIG_BE_CNTL 0x7140 | ||
268 | # define NI_DIG_BE_CNTL_FE_SOURCE_SELECT(x) (((x) >> 8 ) & 0x3F) | ||
269 | # define NI_DIG_FE_CNTL_MODE(x) (((x) >> 16) & 0x7 ) | ||
270 | |||
271 | #define NI_DIG_BE_EN_CNTL 0x7144 | ||
272 | # define NI_DIG_BE_EN_CNTL_ENABLE (1 << 0) | ||
273 | # define NI_DIG_BE_EN_CNTL_SYMBCLK_ON (1 << 8) | ||
274 | # define NI_DIG_BE_DPSST 0 | ||
253 | 275 | ||
254 | /* Display Port block */ | 276 | /* Display Port block */ |
277 | #define EVERGREEN_DP0_REGISTER_OFFSET (0x730C - 0x730C) | ||
278 | #define EVERGREEN_DP1_REGISTER_OFFSET (0x7F0C - 0x730C) | ||
279 | #define EVERGREEN_DP2_REGISTER_OFFSET (0x10B0C - 0x730C) | ||
280 | #define EVERGREEN_DP3_REGISTER_OFFSET (0x1170C - 0x730C) | ||
281 | #define EVERGREEN_DP4_REGISTER_OFFSET (0x1230C - 0x730C) | ||
282 | #define EVERGREEN_DP5_REGISTER_OFFSET (0x12F0C - 0x730C) | ||
283 | |||
284 | |||
285 | #define EVERGREEN_DP_VID_STREAM_CNTL 0x730C | ||
286 | # define EVERGREEN_DP_VID_STREAM_CNTL_ENABLE (1 << 0) | ||
287 | # define EVERGREEN_DP_VID_STREAM_STATUS (1 <<16) | ||
288 | #define EVERGREEN_DP_STEER_FIFO 0x7310 | ||
289 | # define EVERGREEN_DP_STEER_FIFO_RESET (1 << 0) | ||
255 | #define EVERGREEN_DP_SEC_CNTL 0x7280 | 290 | #define EVERGREEN_DP_SEC_CNTL 0x7280 |
256 | # define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) | 291 | # define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) |
257 | # define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) | 292 | # define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) |
@@ -266,4 +301,15 @@ | |||
266 | # define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) | 301 | # define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) |
267 | # define EVERGREEN_DP_SEC_SS_EN (1 << 28) | 302 | # define EVERGREEN_DP_SEC_SS_EN (1 << 28) |
268 | 303 | ||
304 | /*DCIO_UNIPHY block*/ | ||
305 | #define NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1 (0x6600 -0x6600) | ||
306 | #define NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1 (0x6640 -0x6600) | ||
307 | #define NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1 (0x6680 - 0x6600) | ||
308 | #define NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1 (0x66C0 - 0x6600) | ||
309 | #define NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1 (0x6700 - 0x6600) | ||
310 | #define NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 (0x6740 - 0x6600) | ||
311 | |||
312 | #define NI_DCIO_UNIPHY0_PLL_CONTROL1 0x6618 | ||
313 | # define NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE (1 << 0) | ||
314 | |||
269 | #endif | 315 | #endif |
diff --git a/drivers/gpu/drm/radeon/ni_reg.h b/drivers/gpu/drm/radeon/ni_reg.h index da310a70c0f0..827ccc87cbc3 100644 --- a/drivers/gpu/drm/radeon/ni_reg.h +++ b/drivers/gpu/drm/radeon/ni_reg.h | |||
@@ -109,6 +109,8 @@ | |||
109 | #define NI_DP_MSE_SAT2 0x7398 | 109 | #define NI_DP_MSE_SAT2 0x7398 |
110 | 110 | ||
111 | #define NI_DP_MSE_SAT_UPDATE 0x739c | 111 | #define NI_DP_MSE_SAT_UPDATE 0x739c |
112 | # define NI_DP_MSE_SAT_UPDATE_MASK 0x3 | ||
113 | # define NI_DP_MSE_16_MTP_KEEPOUT 0x100 | ||
112 | 114 | ||
113 | #define NI_DIG_BE_CNTL 0x7140 | 115 | #define NI_DIG_BE_CNTL 0x7140 |
114 | # define NI_DIG_FE_SOURCE_SELECT(x) (((x) & 0x7f) << 8) | 116 | # define NI_DIG_FE_SOURCE_SELECT(x) (((x) & 0x7f) << 8) |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index fd8c4d317e60..95f4fea89302 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -62,10 +62,6 @@ bool radeon_has_atpx(void) { | |||
62 | return radeon_atpx_priv.atpx_detected; | 62 | return radeon_atpx_priv.atpx_detected; |
63 | } | 63 | } |
64 | 64 | ||
65 | bool radeon_has_atpx_dgpu_power_cntl(void) { | ||
66 | return radeon_atpx_priv.atpx.functions.power_cntl; | ||
67 | } | ||
68 | |||
69 | /** | 65 | /** |
70 | * radeon_atpx_call - call an ATPX method | 66 | * radeon_atpx_call - call an ATPX method |
71 | * | 67 | * |
@@ -145,6 +141,13 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas | |||
145 | */ | 141 | */ |
146 | static int radeon_atpx_validate(struct radeon_atpx *atpx) | 142 | static int radeon_atpx_validate(struct radeon_atpx *atpx) |
147 | { | 143 | { |
144 | /* make sure required functions are enabled */ | ||
145 | /* dGPU power control is required */ | ||
146 | if (atpx->functions.power_cntl == false) { | ||
147 | printk("ATPX dGPU power cntl not present, forcing\n"); | ||
148 | atpx->functions.power_cntl = true; | ||
149 | } | ||
150 | |||
148 | if (atpx->functions.px_params) { | 151 | if (atpx->functions.px_params) { |
149 | union acpi_object *info; | 152 | union acpi_object *info; |
150 | struct atpx_px_params output; | 153 | struct atpx_px_params output; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index cfcc099c537d..81a63d7f5cd9 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -2002,10 +2002,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
2002 | rdev->mode_info.dither_property, | 2002 | rdev->mode_info.dither_property, |
2003 | RADEON_FMT_DITHER_DISABLE); | 2003 | RADEON_FMT_DITHER_DISABLE); |
2004 | 2004 | ||
2005 | if (radeon_audio != 0) | 2005 | if (radeon_audio != 0) { |
2006 | drm_object_attach_property(&radeon_connector->base.base, | 2006 | drm_object_attach_property(&radeon_connector->base.base, |
2007 | rdev->mode_info.audio_property, | 2007 | rdev->mode_info.audio_property, |
2008 | RADEON_AUDIO_AUTO); | 2008 | RADEON_AUDIO_AUTO); |
2009 | radeon_connector->audio = RADEON_AUDIO_AUTO; | ||
2010 | } | ||
2009 | if (ASIC_IS_DCE5(rdev)) | 2011 | if (ASIC_IS_DCE5(rdev)) |
2010 | drm_object_attach_property(&radeon_connector->base.base, | 2012 | drm_object_attach_property(&radeon_connector->base.base, |
2011 | rdev->mode_info.output_csc_property, | 2013 | rdev->mode_info.output_csc_property, |
@@ -2130,6 +2132,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
2130 | drm_object_attach_property(&radeon_connector->base.base, | 2132 | drm_object_attach_property(&radeon_connector->base.base, |
2131 | rdev->mode_info.audio_property, | 2133 | rdev->mode_info.audio_property, |
2132 | RADEON_AUDIO_AUTO); | 2134 | RADEON_AUDIO_AUTO); |
2135 | radeon_connector->audio = RADEON_AUDIO_AUTO; | ||
2133 | } | 2136 | } |
2134 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | 2137 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
2135 | radeon_connector->dac_load_detect = true; | 2138 | radeon_connector->dac_load_detect = true; |
@@ -2185,6 +2188,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
2185 | drm_object_attach_property(&radeon_connector->base.base, | 2188 | drm_object_attach_property(&radeon_connector->base.base, |
2186 | rdev->mode_info.audio_property, | 2189 | rdev->mode_info.audio_property, |
2187 | RADEON_AUDIO_AUTO); | 2190 | RADEON_AUDIO_AUTO); |
2191 | radeon_connector->audio = RADEON_AUDIO_AUTO; | ||
2188 | } | 2192 | } |
2189 | if (ASIC_IS_DCE5(rdev)) | 2193 | if (ASIC_IS_DCE5(rdev)) |
2190 | drm_object_attach_property(&radeon_connector->base.base, | 2194 | drm_object_attach_property(&radeon_connector->base.base, |
@@ -2237,6 +2241,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
2237 | drm_object_attach_property(&radeon_connector->base.base, | 2241 | drm_object_attach_property(&radeon_connector->base.base, |
2238 | rdev->mode_info.audio_property, | 2242 | rdev->mode_info.audio_property, |
2239 | RADEON_AUDIO_AUTO); | 2243 | RADEON_AUDIO_AUTO); |
2244 | radeon_connector->audio = RADEON_AUDIO_AUTO; | ||
2240 | } | 2245 | } |
2241 | if (ASIC_IS_DCE5(rdev)) | 2246 | if (ASIC_IS_DCE5(rdev)) |
2242 | drm_object_attach_property(&radeon_connector->base.base, | 2247 | drm_object_attach_property(&radeon_connector->base.base, |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4fd1a961012d..d0826fb0434c 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -103,12 +103,6 @@ static const char radeon_family_name[][16] = { | |||
103 | "LAST", | 103 | "LAST", |
104 | }; | 104 | }; |
105 | 105 | ||
106 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
107 | bool radeon_has_atpx_dgpu_power_cntl(void); | ||
108 | #else | ||
109 | static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; } | ||
110 | #endif | ||
111 | |||
112 | #define RADEON_PX_QUIRK_DISABLE_PX (1 << 0) | 106 | #define RADEON_PX_QUIRK_DISABLE_PX (1 << 0) |
113 | #define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1) | 107 | #define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1) |
114 | 108 | ||
@@ -1305,9 +1299,9 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1305 | } | 1299 | } |
1306 | rdev->fence_context = fence_context_alloc(RADEON_NUM_RINGS); | 1300 | rdev->fence_context = fence_context_alloc(RADEON_NUM_RINGS); |
1307 | 1301 | ||
1308 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", | 1302 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X 0x%02X).\n", |
1309 | radeon_family_name[rdev->family], pdev->vendor, pdev->device, | 1303 | radeon_family_name[rdev->family], pdev->vendor, pdev->device, |
1310 | pdev->subsystem_vendor, pdev->subsystem_device); | 1304 | pdev->subsystem_vendor, pdev->subsystem_device, pdev->revision); |
1311 | 1305 | ||
1312 | /* mutex initialization are all done here so we | 1306 | /* mutex initialization are all done here so we |
1313 | * can recall function without having locking issues */ | 1307 | * can recall function without having locking issues */ |
@@ -1439,7 +1433,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1439 | * ignore it */ | 1433 | * ignore it */ |
1440 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); | 1434 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); |
1441 | 1435 | ||
1442 | if ((rdev->flags & RADEON_IS_PX) && radeon_has_atpx_dgpu_power_cntl()) | 1436 | if (rdev->flags & RADEON_IS_PX) |
1443 | runtime = true; | 1437 | runtime = true; |
1444 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); | 1438 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); |
1445 | if (runtime) | 1439 | if (runtime) |
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 43cffb526b0c..de504ea29c06 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c | |||
@@ -89,8 +89,16 @@ static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary, | |||
89 | WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1); | 89 | WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1); |
90 | 90 | ||
91 | do { | 91 | do { |
92 | unsigned value1, value2; | ||
93 | udelay(10); | ||
92 | temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset); | 94 | temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset); |
93 | } while ((temp & 0x1) && retries++ < 10000); | 95 | |
96 | value1 = temp & NI_DP_MSE_SAT_UPDATE_MASK; | ||
97 | value2 = temp & NI_DP_MSE_16_MTP_KEEPOUT; | ||
98 | |||
99 | if (!value1 && !value2) | ||
100 | break; | ||
101 | } while (retries++ < 50); | ||
94 | 102 | ||
95 | if (retries == 10000) | 103 | if (retries == 10000) |
96 | DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset); | 104 | DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset); |
@@ -150,7 +158,7 @@ static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn | |||
150 | return 0; | 158 | return 0; |
151 | } | 159 | } |
152 | 160 | ||
153 | static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, uint32_t y) | 161 | static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, s64 avg_time_slots_per_mtp) |
154 | { | 162 | { |
155 | struct drm_device *dev = mst->base.dev; | 163 | struct drm_device *dev = mst->base.dev; |
156 | struct radeon_device *rdev = dev->dev_private; | 164 | struct radeon_device *rdev = dev->dev_private; |
@@ -158,6 +166,8 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui | |||
158 | uint32_t val, temp; | 166 | uint32_t val, temp; |
159 | uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe); | 167 | uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe); |
160 | int retries = 0; | 168 | int retries = 0; |
169 | uint32_t x = drm_fixp2int(avg_time_slots_per_mtp); | ||
170 | uint32_t y = drm_fixp2int_ceil((avg_time_slots_per_mtp - x) << 26); | ||
161 | 171 | ||
162 | val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y); | 172 | val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y); |
163 | 173 | ||
@@ -165,6 +175,7 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui | |||
165 | 175 | ||
166 | do { | 176 | do { |
167 | temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset); | 177 | temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset); |
178 | udelay(10); | ||
168 | } while ((temp & 0x1) && (retries++ < 10000)); | 179 | } while ((temp & 0x1) && (retries++ < 10000)); |
169 | 180 | ||
170 | if (retries >= 10000) | 181 | if (retries >= 10000) |
@@ -246,14 +257,8 @@ radeon_dp_mst_connector_destroy(struct drm_connector *connector) | |||
246 | kfree(radeon_connector); | 257 | kfree(radeon_connector); |
247 | } | 258 | } |
248 | 259 | ||
249 | static int radeon_connector_dpms(struct drm_connector *connector, int mode) | ||
250 | { | ||
251 | DRM_DEBUG_KMS("\n"); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = { | 260 | static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = { |
256 | .dpms = radeon_connector_dpms, | 261 | .dpms = drm_helper_connector_dpms, |
257 | .detect = radeon_dp_mst_detect, | 262 | .detect = radeon_dp_mst_detect, |
258 | .fill_modes = drm_helper_probe_single_connector_modes, | 263 | .fill_modes = drm_helper_probe_single_connector_modes, |
259 | .destroy = radeon_dp_mst_connector_destroy, | 264 | .destroy = radeon_dp_mst_connector_destroy, |
@@ -394,7 +399,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
394 | struct drm_crtc *crtc; | 399 | struct drm_crtc *crtc; |
395 | struct radeon_crtc *radeon_crtc; | 400 | struct radeon_crtc *radeon_crtc; |
396 | int ret, slots; | 401 | int ret, slots; |
397 | 402 | s64 fixed_pbn, fixed_pbn_per_slot, avg_time_slots_per_mtp; | |
398 | if (!ASIC_IS_DCE5(rdev)) { | 403 | if (!ASIC_IS_DCE5(rdev)) { |
399 | DRM_ERROR("got mst dpms on non-DCE5\n"); | 404 | DRM_ERROR("got mst dpms on non-DCE5\n"); |
400 | return; | 405 | return; |
@@ -456,7 +461,11 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
456 | 461 | ||
457 | mst_enc->enc_active = true; | 462 | mst_enc->enc_active = true; |
458 | radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary); | 463 | radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary); |
459 | radeon_dp_mst_set_vcp_size(radeon_encoder, slots, 0); | 464 | |
465 | fixed_pbn = drm_int2fixp(mst_enc->pbn); | ||
466 | fixed_pbn_per_slot = drm_int2fixp(radeon_connector->mst_port->mst_mgr.pbn_div); | ||
467 | avg_time_slots_per_mtp = drm_fixp_div(fixed_pbn, fixed_pbn_per_slot); | ||
468 | radeon_dp_mst_set_vcp_size(radeon_encoder, avg_time_slots_per_mtp); | ||
460 | 469 | ||
461 | atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0, | 470 | atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0, |
462 | mst_enc->fe); | 471 | mst_enc->fe); |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 979f3bf65f2c..1e9304d1c88f 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -291,6 +291,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
291 | if (r) { | 291 | if (r) { |
292 | return r; | 292 | return r; |
293 | } | 293 | } |
294 | rdev->ddev->vblank_disable_allowed = true; | ||
295 | |||
294 | /* enable msi */ | 296 | /* enable msi */ |
295 | rdev->msi_enabled = 0; | 297 | rdev->msi_enabled = 0; |
296 | 298 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 24152dfef199..478d4099b0d0 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -331,13 +331,15 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
331 | RADEON_CRTC_DISP_REQ_EN_B)); | 331 | RADEON_CRTC_DISP_REQ_EN_B)); |
332 | WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); | 332 | WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); |
333 | } | 333 | } |
334 | drm_vblank_on(dev, radeon_crtc->crtc_id); | 334 | if (dev->num_crtcs > radeon_crtc->crtc_id) |
335 | drm_vblank_on(dev, radeon_crtc->crtc_id); | ||
335 | radeon_crtc_load_lut(crtc); | 336 | radeon_crtc_load_lut(crtc); |
336 | break; | 337 | break; |
337 | case DRM_MODE_DPMS_STANDBY: | 338 | case DRM_MODE_DPMS_STANDBY: |
338 | case DRM_MODE_DPMS_SUSPEND: | 339 | case DRM_MODE_DPMS_SUSPEND: |
339 | case DRM_MODE_DPMS_OFF: | 340 | case DRM_MODE_DPMS_OFF: |
340 | drm_vblank_off(dev, radeon_crtc->crtc_id); | 341 | if (dev->num_crtcs > radeon_crtc->crtc_id) |
342 | drm_vblank_off(dev, radeon_crtc->crtc_id); | ||
341 | if (radeon_crtc->crtc_id) | 343 | if (radeon_crtc->crtc_id) |
342 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); | 344 | WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); |
343 | else { | 345 | else { |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index c008312e1bcd..90f739478a1b 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -235,6 +235,8 @@ static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) | |||
235 | { | 235 | { |
236 | struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); | 236 | struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); |
237 | 237 | ||
238 | if (radeon_ttm_tt_has_userptr(bo->ttm)) | ||
239 | return -EPERM; | ||
238 | return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp); | 240 | return drm_vma_node_verify_access(&rbo->gem_base.vma_node, filp); |
239 | } | 241 | } |
240 | 242 | ||
@@ -615,7 +617,7 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | |||
615 | set_page_dirty(page); | 617 | set_page_dirty(page); |
616 | 618 | ||
617 | mark_page_accessed(page); | 619 | mark_page_accessed(page); |
618 | page_cache_release(page); | 620 | put_page(page); |
619 | } | 621 | } |
620 | 622 | ||
621 | sg_free_table(ttm->sg); | 623 | sg_free_table(ttm->sg); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index af4df81c4e0c..e6abc09b67e3 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -2931,6 +2931,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = { | |||
2931 | { PCI_VENDOR_ID_ATI, 0x6811, 0x1462, 0x2015, 0, 120000 }, | 2931 | { PCI_VENDOR_ID_ATI, 0x6811, 0x1462, 0x2015, 0, 120000 }, |
2932 | { PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 }, | 2932 | { PCI_VENDOR_ID_ATI, 0x6811, 0x1043, 0x2015, 0, 120000 }, |
2933 | { PCI_VENDOR_ID_ATI, 0x6811, 0x148c, 0x2015, 0, 120000 }, | 2933 | { PCI_VENDOR_ID_ATI, 0x6811, 0x148c, 0x2015, 0, 120000 }, |
2934 | { PCI_VENDOR_ID_ATI, 0x6810, 0x1682, 0x9275, 0, 120000 }, | ||
2934 | { 0, 0, 0, 0 }, | 2935 | { 0, 0, 0, 0 }, |
2935 | }; | 2936 | }; |
2936 | 2937 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 4cbf26555093..e3daafa1be13 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -230,22 +230,13 @@ EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); | |||
230 | 230 | ||
231 | void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) | 231 | void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo) |
232 | { | 232 | { |
233 | struct ttm_bo_device *bdev = bo->bdev; | 233 | int put_count = 0; |
234 | struct ttm_mem_type_manager *man; | ||
235 | 234 | ||
236 | lockdep_assert_held(&bo->resv->lock.base); | 235 | lockdep_assert_held(&bo->resv->lock.base); |
237 | 236 | ||
238 | if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) { | 237 | put_count = ttm_bo_del_from_lru(bo); |
239 | list_del_init(&bo->swap); | 238 | ttm_bo_list_ref_sub(bo, put_count, true); |
240 | list_del_init(&bo->lru); | 239 | ttm_bo_add_to_lru(bo); |
241 | |||
242 | } else { | ||
243 | if (bo->ttm && !(bo->ttm->page_flags & TTM_PAGE_FLAG_SG)) | ||
244 | list_move_tail(&bo->swap, &bo->glob->swap_lru); | ||
245 | |||
246 | man = &bdev->man[bo->mem.mem_type]; | ||
247 | list_move_tail(&bo->lru, &man->lru); | ||
248 | } | ||
249 | } | 240 | } |
250 | EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); | 241 | EXPORT_SYMBOL(ttm_bo_move_to_lru_tail); |
251 | 242 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 4e19d0f9cc30..077ae9b2865d 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -311,7 +311,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) | |||
311 | goto out_err; | 311 | goto out_err; |
312 | 312 | ||
313 | copy_highpage(to_page, from_page); | 313 | copy_highpage(to_page, from_page); |
314 | page_cache_release(from_page); | 314 | put_page(from_page); |
315 | } | 315 | } |
316 | 316 | ||
317 | if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP)) | 317 | if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP)) |
@@ -361,7 +361,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) | |||
361 | copy_highpage(to_page, from_page); | 361 | copy_highpage(to_page, from_page); |
362 | set_page_dirty(to_page); | 362 | set_page_dirty(to_page); |
363 | mark_page_accessed(to_page); | 363 | mark_page_accessed(to_page); |
364 | page_cache_release(to_page); | 364 | put_page(to_page); |
365 | } | 365 | } |
366 | 366 | ||
367 | ttm_tt_unpopulate(ttm); | 367 | ttm_tt_unpopulate(ttm); |
diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index e797dfc07ae3..7e2a12c4fed2 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c | |||
@@ -188,7 +188,7 @@ via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) | |||
188 | if (NULL != (page = vsg->pages[i])) { | 188 | if (NULL != (page = vsg->pages[i])) { |
189 | if (!PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) | 189 | if (!PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction)) |
190 | SetPageDirty(page); | 190 | SetPageDirty(page); |
191 | page_cache_release(page); | 191 | put_page(page); |
192 | } | 192 | } |
193 | } | 193 | } |
194 | case dr_via_pages_alloc: | 194 | case dr_via_pages_alloc: |
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 4854dac87e24..5fd1fd06effc 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c | |||
@@ -267,11 +267,23 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, | |||
267 | return 0; | 267 | return 0; |
268 | } | 268 | } |
269 | 269 | ||
270 | static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, | ||
271 | struct drm_crtc_state *old_state) | ||
272 | { | ||
273 | unsigned long flags; | ||
274 | |||
275 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
276 | if (crtc->state->event) | ||
277 | drm_crtc_send_vblank_event(crtc, crtc->state->event); | ||
278 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
279 | } | ||
280 | |||
270 | static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = { | 281 | static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = { |
271 | .enable = virtio_gpu_crtc_enable, | 282 | .enable = virtio_gpu_crtc_enable, |
272 | .disable = virtio_gpu_crtc_disable, | 283 | .disable = virtio_gpu_crtc_disable, |
273 | .mode_set_nofb = virtio_gpu_crtc_mode_set_nofb, | 284 | .mode_set_nofb = virtio_gpu_crtc_mode_set_nofb, |
274 | .atomic_check = virtio_gpu_crtc_atomic_check, | 285 | .atomic_check = virtio_gpu_crtc_atomic_check, |
286 | .atomic_flush = virtio_gpu_crtc_atomic_flush, | ||
275 | }; | 287 | }; |
276 | 288 | ||
277 | static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder, | 289 | static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 723ba16c6084..1a1a87cbf109 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -3293,19 +3293,19 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { | |||
3293 | &vmw_cmd_dx_cid_check, true, false, true), | 3293 | &vmw_cmd_dx_cid_check, true, false, true), |
3294 | VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_dx_define_query, | 3294 | VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_dx_define_query, |
3295 | true, false, true), | 3295 | true, false, true), |
3296 | VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_ok, | 3296 | VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_dx_cid_check, |
3297 | true, false, true), | 3297 | true, false, true), |
3298 | VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_QUERY, &vmw_cmd_dx_bind_query, | 3298 | VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_QUERY, &vmw_cmd_dx_bind_query, |
3299 | true, false, true), | 3299 | true, false, true), |
3300 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_QUERY_OFFSET, | 3300 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_QUERY_OFFSET, |
3301 | &vmw_cmd_ok, true, false, true), | 3301 | &vmw_cmd_dx_cid_check, true, false, true), |
3302 | VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_ok, | 3302 | VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_dx_cid_check, |
3303 | true, false, true), | 3303 | true, false, true), |
3304 | VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_ok, | 3304 | VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_dx_cid_check, |
3305 | true, false, true), | 3305 | true, false, true), |
3306 | VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid, | 3306 | VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid, |
3307 | true, false, true), | 3307 | true, false, true), |
3308 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_invalid, | 3308 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_dx_cid_check, |
3309 | true, false, true), | 3309 | true, false, true), |
3310 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VIEWPORTS, &vmw_cmd_dx_cid_check, | 3310 | VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VIEWPORTS, &vmw_cmd_dx_cid_check, |
3311 | true, false, true), | 3311 | true, false, true), |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 3b1faf7862a5..679a4cb98ee3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -573,9 +573,9 @@ static int vmw_fb_set_par(struct fb_info *info) | |||
573 | mode = old_mode; | 573 | mode = old_mode; |
574 | old_mode = NULL; | 574 | old_mode = NULL; |
575 | } else if (!vmw_kms_validate_mode_vram(vmw_priv, | 575 | } else if (!vmw_kms_validate_mode_vram(vmw_priv, |
576 | mode->hdisplay * | 576 | mode->hdisplay * |
577 | (var->bits_per_pixel + 7) / 8, | 577 | DIV_ROUND_UP(var->bits_per_pixel, 8), |
578 | mode->vdisplay)) { | 578 | mode->vdisplay)) { |
579 | drm_mode_destroy(vmw_priv->dev, mode); | 579 | drm_mode_destroy(vmw_priv->dev, mode); |
580 | return -EINVAL; | 580 | return -EINVAL; |
581 | } | 581 | } |
diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c index 883a314cd83a..6494a4d28171 100644 --- a/drivers/gpu/ipu-v3/ipu-cpmem.c +++ b/drivers/gpu/ipu-v3/ipu-cpmem.c | |||
@@ -395,60 +395,48 @@ void ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel *ch, u32 pixel_format) | |||
395 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved); | 395 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved); |
396 | 396 | ||
397 | void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch, | 397 | void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch, |
398 | u32 pixel_format, int stride, | 398 | unsigned int uv_stride, |
399 | int u_offset, int v_offset) | 399 | unsigned int u_offset, unsigned int v_offset) |
400 | { | 400 | { |
401 | switch (pixel_format) { | 401 | ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, uv_stride - 1); |
402 | case V4L2_PIX_FMT_YUV420: | 402 | ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8); |
403 | case V4L2_PIX_FMT_YUV422P: | 403 | ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8); |
404 | ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, (stride / 2) - 1); | ||
405 | ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8); | ||
406 | ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8); | ||
407 | break; | ||
408 | case V4L2_PIX_FMT_YVU420: | ||
409 | ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, (stride / 2) - 1); | ||
410 | ipu_ch_param_write_field(ch, IPU_FIELD_UBO, v_offset / 8); | ||
411 | ipu_ch_param_write_field(ch, IPU_FIELD_VBO, u_offset / 8); | ||
412 | break; | ||
413 | case V4L2_PIX_FMT_NV12: | ||
414 | case V4L2_PIX_FMT_NV16: | ||
415 | ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, stride - 1); | ||
416 | ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8); | ||
417 | ipu_ch_param_write_field(ch, IPU_FIELD_VBO, u_offset / 8); | ||
418 | break; | ||
419 | } | ||
420 | } | 404 | } |
421 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full); | 405 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full); |
422 | 406 | ||
423 | void ipu_cpmem_set_yuv_planar(struct ipuv3_channel *ch, | 407 | void ipu_cpmem_set_yuv_planar(struct ipuv3_channel *ch, |
424 | u32 pixel_format, int stride, int height) | 408 | u32 pixel_format, int stride, int height) |
425 | { | 409 | { |
426 | int u_offset, v_offset; | 410 | int fourcc, u_offset, v_offset; |
427 | int uv_stride = 0; | 411 | int uv_stride = 0; |
428 | 412 | ||
429 | switch (pixel_format) { | 413 | fourcc = v4l2_pix_fmt_to_drm_fourcc(pixel_format); |
430 | case V4L2_PIX_FMT_YUV420: | 414 | switch (fourcc) { |
431 | case V4L2_PIX_FMT_YVU420: | 415 | case DRM_FORMAT_YUV420: |
432 | uv_stride = stride / 2; | 416 | uv_stride = stride / 2; |
433 | u_offset = stride * height; | 417 | u_offset = stride * height; |
434 | v_offset = u_offset + (uv_stride * height / 2); | 418 | v_offset = u_offset + (uv_stride * height / 2); |
435 | ipu_cpmem_set_yuv_planar_full(ch, pixel_format, stride, | ||
436 | u_offset, v_offset); | ||
437 | break; | 419 | break; |
438 | case V4L2_PIX_FMT_YUV422P: | 420 | case DRM_FORMAT_YVU420: |
421 | uv_stride = stride / 2; | ||
422 | v_offset = stride * height; | ||
423 | u_offset = v_offset + (uv_stride * height / 2); | ||
424 | break; | ||
425 | case DRM_FORMAT_YUV422: | ||
439 | uv_stride = stride / 2; | 426 | uv_stride = stride / 2; |
440 | u_offset = stride * height; | 427 | u_offset = stride * height; |
441 | v_offset = u_offset + (uv_stride * height); | 428 | v_offset = u_offset + (uv_stride * height); |
442 | ipu_cpmem_set_yuv_planar_full(ch, pixel_format, stride, | ||
443 | u_offset, v_offset); | ||
444 | break; | 429 | break; |
445 | case V4L2_PIX_FMT_NV12: | 430 | case DRM_FORMAT_NV12: |
446 | case V4L2_PIX_FMT_NV16: | 431 | case DRM_FORMAT_NV16: |
432 | uv_stride = stride; | ||
447 | u_offset = stride * height; | 433 | u_offset = stride * height; |
448 | ipu_cpmem_set_yuv_planar_full(ch, pixel_format, stride, | 434 | v_offset = 0; |
449 | u_offset, 0); | ||
450 | break; | 435 | break; |
436 | default: | ||
437 | return; | ||
451 | } | 438 | } |
439 | ipu_cpmem_set_yuv_planar_full(ch, uv_stride, u_offset, v_offset); | ||
452 | } | 440 | } |
453 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar); | 441 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar); |
454 | 442 | ||
@@ -684,17 +672,25 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image) | |||
684 | 672 | ||
685 | switch (pix->pixelformat) { | 673 | switch (pix->pixelformat) { |
686 | case V4L2_PIX_FMT_YUV420: | 674 | case V4L2_PIX_FMT_YUV420: |
687 | case V4L2_PIX_FMT_YVU420: | ||
688 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); | 675 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); |
689 | u_offset = U_OFFSET(pix, image->rect.left, | 676 | u_offset = U_OFFSET(pix, image->rect.left, |
690 | image->rect.top) - offset; | 677 | image->rect.top) - offset; |
691 | v_offset = V_OFFSET(pix, image->rect.left, | 678 | v_offset = V_OFFSET(pix, image->rect.left, |
692 | image->rect.top) - offset; | 679 | image->rect.top) - offset; |
693 | 680 | ||
694 | ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat, | 681 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2, |
695 | pix->bytesperline, | ||
696 | u_offset, v_offset); | 682 | u_offset, v_offset); |
697 | break; | 683 | break; |
684 | case V4L2_PIX_FMT_YVU420: | ||
685 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); | ||
686 | u_offset = U_OFFSET(pix, image->rect.left, | ||
687 | image->rect.top) - offset; | ||
688 | v_offset = V_OFFSET(pix, image->rect.left, | ||
689 | image->rect.top) - offset; | ||
690 | |||
691 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2, | ||
692 | v_offset, u_offset); | ||
693 | break; | ||
698 | case V4L2_PIX_FMT_YUV422P: | 694 | case V4L2_PIX_FMT_YUV422P: |
699 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); | 695 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); |
700 | u_offset = U2_OFFSET(pix, image->rect.left, | 696 | u_offset = U2_OFFSET(pix, image->rect.left, |
@@ -702,8 +698,7 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image) | |||
702 | v_offset = V2_OFFSET(pix, image->rect.left, | 698 | v_offset = V2_OFFSET(pix, image->rect.left, |
703 | image->rect.top) - offset; | 699 | image->rect.top) - offset; |
704 | 700 | ||
705 | ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat, | 701 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2, |
706 | pix->bytesperline, | ||
707 | u_offset, v_offset); | 702 | u_offset, v_offset); |
708 | break; | 703 | break; |
709 | case V4L2_PIX_FMT_NV12: | 704 | case V4L2_PIX_FMT_NV12: |
@@ -712,8 +707,7 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image) | |||
712 | image->rect.top) - offset; | 707 | image->rect.top) - offset; |
713 | v_offset = 0; | 708 | v_offset = 0; |
714 | 709 | ||
715 | ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat, | 710 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline, |
716 | pix->bytesperline, | ||
717 | u_offset, v_offset); | 711 | u_offset, v_offset); |
718 | break; | 712 | break; |
719 | case V4L2_PIX_FMT_NV16: | 713 | case V4L2_PIX_FMT_NV16: |
@@ -722,8 +716,7 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image) | |||
722 | image->rect.top) - offset; | 716 | image->rect.top) - offset; |
723 | v_offset = 0; | 717 | v_offset = 0; |
724 | 718 | ||
725 | ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat, | 719 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline, |
726 | pix->bytesperline, | ||
727 | u_offset, v_offset); | 720 | u_offset, v_offset); |
728 | break; | 721 | break; |
729 | case V4L2_PIX_FMT_UYVY: | 722 | case V4L2_PIX_FMT_UYVY: |
diff --git a/drivers/gpu/ipu-v3/ipu-dmfc.c b/drivers/gpu/ipu-v3/ipu-dmfc.c index 042c3958e2a0..837b1ec22800 100644 --- a/drivers/gpu/ipu-v3/ipu-dmfc.c +++ b/drivers/gpu/ipu-v3/ipu-dmfc.c | |||
@@ -350,11 +350,13 @@ out: | |||
350 | } | 350 | } |
351 | EXPORT_SYMBOL_GPL(ipu_dmfc_alloc_bandwidth); | 351 | EXPORT_SYMBOL_GPL(ipu_dmfc_alloc_bandwidth); |
352 | 352 | ||
353 | int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width) | 353 | void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width) |
354 | { | 354 | { |
355 | struct ipu_dmfc_priv *priv = dmfc->priv; | 355 | struct ipu_dmfc_priv *priv = dmfc->priv; |
356 | u32 dmfc_gen1; | 356 | u32 dmfc_gen1; |
357 | 357 | ||
358 | mutex_lock(&priv->mutex); | ||
359 | |||
358 | dmfc_gen1 = readl(priv->base + DMFC_GENERAL1); | 360 | dmfc_gen1 = readl(priv->base + DMFC_GENERAL1); |
359 | 361 | ||
360 | if ((dmfc->slots * 64 * 4) / width > dmfc->data->max_fifo_lines) | 362 | if ((dmfc->slots * 64 * 4) / width > dmfc->data->max_fifo_lines) |
@@ -364,9 +366,9 @@ int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width) | |||
364 | 366 | ||
365 | writel(dmfc_gen1, priv->base + DMFC_GENERAL1); | 367 | writel(dmfc_gen1, priv->base + DMFC_GENERAL1); |
366 | 368 | ||
367 | return 0; | 369 | mutex_unlock(&priv->mutex); |
368 | } | 370 | } |
369 | EXPORT_SYMBOL_GPL(ipu_dmfc_init_channel); | 371 | EXPORT_SYMBOL_GPL(ipu_dmfc_config_wait4eot); |
370 | 372 | ||
371 | struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipu_channel) | 373 | struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipu_channel) |
372 | { | 374 | { |