diff options
Diffstat (limited to 'drivers/gpu')
105 files changed, 665 insertions, 411 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 992f00b65be4..01c36b8d6222 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -799,6 +799,7 @@ struct amdgpu_ring { | |||
| 799 | unsigned cond_exe_offs; | 799 | unsigned cond_exe_offs; |
| 800 | u64 cond_exe_gpu_addr; | 800 | u64 cond_exe_gpu_addr; |
| 801 | volatile u32 *cond_exe_cpu_addr; | 801 | volatile u32 *cond_exe_cpu_addr; |
| 802 | int vmid; | ||
| 802 | }; | 803 | }; |
| 803 | 804 | ||
| 804 | /* | 805 | /* |
| @@ -936,7 +937,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
| 936 | unsigned vm_id, uint64_t pd_addr, | 937 | unsigned vm_id, uint64_t pd_addr, |
| 937 | uint32_t gds_base, uint32_t gds_size, | 938 | uint32_t gds_base, uint32_t gds_size, |
| 938 | uint32_t gws_base, uint32_t gws_size, | 939 | uint32_t gws_base, uint32_t gws_size, |
| 939 | uint32_t oa_base, uint32_t oa_size); | 940 | uint32_t oa_base, uint32_t oa_size, |
| 941 | bool vmid_switch); | ||
| 940 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); | 942 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); |
| 941 | uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); | 943 | uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); |
| 942 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | 944 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 199f76baf22c..8943099eb135 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
| @@ -696,6 +696,17 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type) | |||
| 696 | return result; | 696 | return result; |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode_id type) | ||
| 700 | { | ||
| 701 | CGS_FUNC_ADEV; | ||
| 702 | if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) { | ||
| 703 | release_firmware(adev->pm.fw); | ||
| 704 | return 0; | ||
| 705 | } | ||
| 706 | /* cannot release other firmware because they are not created by cgs */ | ||
| 707 | return -EINVAL; | ||
| 708 | } | ||
| 709 | |||
| 699 | static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | 710 | static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, |
| 700 | enum cgs_ucode_id type, | 711 | enum cgs_ucode_id type, |
| 701 | struct cgs_firmware_info *info) | 712 | struct cgs_firmware_info *info) |
| @@ -1125,6 +1136,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { | |||
| 1125 | amdgpu_cgs_pm_query_clock_limits, | 1136 | amdgpu_cgs_pm_query_clock_limits, |
| 1126 | amdgpu_cgs_set_camera_voltages, | 1137 | amdgpu_cgs_set_camera_voltages, |
| 1127 | amdgpu_cgs_get_firmware_info, | 1138 | amdgpu_cgs_get_firmware_info, |
| 1139 | amdgpu_cgs_rel_firmware, | ||
| 1128 | amdgpu_cgs_set_powergating_state, | 1140 | amdgpu_cgs_set_powergating_state, |
| 1129 | amdgpu_cgs_set_clockgating_state, | 1141 | amdgpu_cgs_set_clockgating_state, |
| 1130 | amdgpu_cgs_get_active_displays_info, | 1142 | amdgpu_cgs_get_active_displays_info, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index bb8b149786d7..964f31404f17 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -827,8 +827,10 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | |||
| 827 | */ | 827 | */ |
| 828 | static void amdgpu_atombios_fini(struct amdgpu_device *adev) | 828 | static void amdgpu_atombios_fini(struct amdgpu_device *adev) |
| 829 | { | 829 | { |
| 830 | if (adev->mode_info.atom_context) | 830 | if (adev->mode_info.atom_context) { |
| 831 | kfree(adev->mode_info.atom_context->scratch); | 831 | kfree(adev->mode_info.atom_context->scratch); |
| 832 | kfree(adev->mode_info.atom_context->iio); | ||
| 833 | } | ||
| 832 | kfree(adev->mode_info.atom_context); | 834 | kfree(adev->mode_info.atom_context); |
| 833 | adev->mode_info.atom_context = NULL; | 835 | adev->mode_info.atom_context = NULL; |
| 834 | kfree(adev->mode_info.atom_card_info); | 836 | kfree(adev->mode_info.atom_card_info); |
| @@ -1325,6 +1327,11 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
| 1325 | adev->ip_block_status[i].valid = false; | 1327 | adev->ip_block_status[i].valid = false; |
| 1326 | } | 1328 | } |
| 1327 | 1329 | ||
| 1330 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | ||
| 1331 | if (adev->ip_blocks[i].funcs->late_fini) | ||
| 1332 | adev->ip_blocks[i].funcs->late_fini((void *)adev); | ||
| 1333 | } | ||
| 1334 | |||
| 1328 | return 0; | 1335 | return 0; |
| 1329 | } | 1336 | } |
| 1330 | 1337 | ||
| @@ -1513,8 +1520,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
| 1513 | amdgpu_atombios_has_gpu_virtualization_table(adev); | 1520 | amdgpu_atombios_has_gpu_virtualization_table(adev); |
| 1514 | 1521 | ||
| 1515 | /* Post card if necessary */ | 1522 | /* Post card if necessary */ |
| 1516 | if (!amdgpu_card_posted(adev) || | 1523 | if (!amdgpu_card_posted(adev)) { |
| 1517 | adev->virtualization.supports_sr_iov) { | ||
| 1518 | if (!adev->bios) { | 1524 | if (!adev->bios) { |
| 1519 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1525 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
| 1520 | return -EINVAL; | 1526 | return -EINVAL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 34e35423b78e..7a0b1e50f293 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
| @@ -122,6 +122,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
| 122 | bool skip_preamble, need_ctx_switch; | 122 | bool skip_preamble, need_ctx_switch; |
| 123 | unsigned patch_offset = ~0; | 123 | unsigned patch_offset = ~0; |
| 124 | struct amdgpu_vm *vm; | 124 | struct amdgpu_vm *vm; |
| 125 | int vmid = 0, old_vmid = ring->vmid; | ||
| 125 | struct fence *hwf; | 126 | struct fence *hwf; |
| 126 | uint64_t ctx; | 127 | uint64_t ctx; |
| 127 | 128 | ||
| @@ -135,9 +136,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
| 135 | if (job) { | 136 | if (job) { |
| 136 | vm = job->vm; | 137 | vm = job->vm; |
| 137 | ctx = job->ctx; | 138 | ctx = job->ctx; |
| 139 | vmid = job->vm_id; | ||
| 138 | } else { | 140 | } else { |
| 139 | vm = NULL; | 141 | vm = NULL; |
| 140 | ctx = 0; | 142 | ctx = 0; |
| 143 | vmid = 0; | ||
| 141 | } | 144 | } |
| 142 | 145 | ||
| 143 | if (!ring->ready) { | 146 | if (!ring->ready) { |
| @@ -163,7 +166,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
| 163 | r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, | 166 | r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, |
| 164 | job->gds_base, job->gds_size, | 167 | job->gds_base, job->gds_size, |
| 165 | job->gws_base, job->gws_size, | 168 | job->gws_base, job->gws_size, |
| 166 | job->oa_base, job->oa_size); | 169 | job->oa_base, job->oa_size, |
| 170 | (ring->current_ctx == ctx) && (old_vmid != vmid)); | ||
| 167 | if (r) { | 171 | if (r) { |
| 168 | amdgpu_ring_undo(ring); | 172 | amdgpu_ring_undo(ring); |
| 169 | return r; | 173 | return r; |
| @@ -180,7 +184,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
| 180 | need_ctx_switch = ring->current_ctx != ctx; | 184 | need_ctx_switch = ring->current_ctx != ctx; |
| 181 | for (i = 0; i < num_ibs; ++i) { | 185 | for (i = 0; i < num_ibs; ++i) { |
| 182 | ib = &ibs[i]; | 186 | ib = &ibs[i]; |
| 183 | |||
| 184 | /* drop preamble IBs if we don't have a context switch */ | 187 | /* drop preamble IBs if we don't have a context switch */ |
| 185 | if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble) | 188 | if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble) |
| 186 | continue; | 189 | continue; |
| @@ -188,6 +191,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
| 188 | amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, | 191 | amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, |
| 189 | need_ctx_switch); | 192 | need_ctx_switch); |
| 190 | need_ctx_switch = false; | 193 | need_ctx_switch = false; |
| 194 | ring->vmid = vmid; | ||
| 191 | } | 195 | } |
| 192 | 196 | ||
| 193 | if (ring->funcs->emit_hdp_invalidate) | 197 | if (ring->funcs->emit_hdp_invalidate) |
| @@ -198,6 +202,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
| 198 | dev_err(adev->dev, "failed to emit fence (%d)\n", r); | 202 | dev_err(adev->dev, "failed to emit fence (%d)\n", r); |
| 199 | if (job && job->vm_id) | 203 | if (job && job->vm_id) |
| 200 | amdgpu_vm_reset_id(adev, job->vm_id); | 204 | amdgpu_vm_reset_id(adev, job->vm_id); |
| 205 | ring->vmid = old_vmid; | ||
| 201 | amdgpu_ring_undo(ring); | 206 | amdgpu_ring_undo(ring); |
| 202 | return r; | 207 | return r; |
| 203 | } | 208 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 6bd961fb43dc..82256558e0f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | |||
| @@ -183,13 +183,6 @@ static int amdgpu_pp_sw_fini(void *handle) | |||
| 183 | if (ret) | 183 | if (ret) |
| 184 | return ret; | 184 | return ret; |
| 185 | 185 | ||
| 186 | #ifdef CONFIG_DRM_AMD_POWERPLAY | ||
| 187 | if (adev->pp_enabled) { | ||
| 188 | amdgpu_pm_sysfs_fini(adev); | ||
| 189 | amd_powerplay_fini(adev->powerplay.pp_handle); | ||
| 190 | } | ||
| 191 | #endif | ||
| 192 | |||
| 193 | return ret; | 186 | return ret; |
| 194 | } | 187 | } |
| 195 | 188 | ||
| @@ -223,6 +216,22 @@ static int amdgpu_pp_hw_fini(void *handle) | |||
| 223 | return ret; | 216 | return ret; |
| 224 | } | 217 | } |
| 225 | 218 | ||
| 219 | static void amdgpu_pp_late_fini(void *handle) | ||
| 220 | { | ||
| 221 | #ifdef CONFIG_DRM_AMD_POWERPLAY | ||
| 222 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 223 | |||
| 224 | if (adev->pp_enabled) { | ||
| 225 | amdgpu_pm_sysfs_fini(adev); | ||
| 226 | amd_powerplay_fini(adev->powerplay.pp_handle); | ||
| 227 | } | ||
| 228 | |||
| 229 | if (adev->powerplay.ip_funcs->late_fini) | ||
| 230 | adev->powerplay.ip_funcs->late_fini( | ||
| 231 | adev->powerplay.pp_handle); | ||
| 232 | #endif | ||
| 233 | } | ||
| 234 | |||
| 226 | static int amdgpu_pp_suspend(void *handle) | 235 | static int amdgpu_pp_suspend(void *handle) |
| 227 | { | 236 | { |
| 228 | int ret = 0; | 237 | int ret = 0; |
| @@ -311,6 +320,7 @@ const struct amd_ip_funcs amdgpu_pp_ip_funcs = { | |||
| 311 | .sw_fini = amdgpu_pp_sw_fini, | 320 | .sw_fini = amdgpu_pp_sw_fini, |
| 312 | .hw_init = amdgpu_pp_hw_init, | 321 | .hw_init = amdgpu_pp_hw_init, |
| 313 | .hw_fini = amdgpu_pp_hw_fini, | 322 | .hw_fini = amdgpu_pp_hw_fini, |
| 323 | .late_fini = amdgpu_pp_late_fini, | ||
| 314 | .suspend = amdgpu_pp_suspend, | 324 | .suspend = amdgpu_pp_suspend, |
| 315 | .resume = amdgpu_pp_resume, | 325 | .resume = amdgpu_pp_resume, |
| 316 | .is_idle = amdgpu_pp_is_idle, | 326 | .is_idle = amdgpu_pp_is_idle, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 3b02272db678..870f9494252c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
| @@ -343,6 +343,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) | |||
| 343 | ring->ring = NULL; | 343 | ring->ring = NULL; |
| 344 | ring->ring_obj = NULL; | 344 | ring->ring_obj = NULL; |
| 345 | 345 | ||
| 346 | amdgpu_wb_free(ring->adev, ring->cond_exe_offs); | ||
| 346 | amdgpu_wb_free(ring->adev, ring->fence_offs); | 347 | amdgpu_wb_free(ring->adev, ring->fence_offs); |
| 347 | amdgpu_wb_free(ring->adev, ring->rptr_offs); | 348 | amdgpu_wb_free(ring->adev, ring->rptr_offs); |
| 348 | amdgpu_wb_free(ring->adev, ring->wptr_offs); | 349 | amdgpu_wb_free(ring->adev, ring->wptr_offs); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 8bf84efafb04..48618ee324eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | |||
| @@ -115,6 +115,7 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev, | |||
| 115 | return r; | 115 | return r; |
| 116 | } | 116 | } |
| 117 | r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); | 117 | r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); |
| 118 | memset(sa_manager->cpu_ptr, 0, sa_manager->size); | ||
| 118 | amdgpu_bo_unreserve(sa_manager->bo); | 119 | amdgpu_bo_unreserve(sa_manager->bo); |
| 119 | return r; | 120 | return r; |
| 120 | } | 121 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 01abfc21b4a2..e19520c4b4b6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
| @@ -253,19 +253,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | |||
| 253 | { | 253 | { |
| 254 | int r; | 254 | int r; |
| 255 | 255 | ||
| 256 | if (adev->uvd.vcpu_bo == NULL) | 256 | kfree(adev->uvd.saved_bo); |
| 257 | return 0; | ||
| 258 | 257 | ||
| 259 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); | 258 | amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); |
| 260 | 259 | ||
| 261 | r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); | 260 | if (adev->uvd.vcpu_bo) { |
| 262 | if (!r) { | 261 | r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); |
| 263 | amdgpu_bo_kunmap(adev->uvd.vcpu_bo); | 262 | if (!r) { |
| 264 | amdgpu_bo_unpin(adev->uvd.vcpu_bo); | 263 | amdgpu_bo_kunmap(adev->uvd.vcpu_bo); |
| 265 | amdgpu_bo_unreserve(adev->uvd.vcpu_bo); | 264 | amdgpu_bo_unpin(adev->uvd.vcpu_bo); |
| 266 | } | 265 | amdgpu_bo_unreserve(adev->uvd.vcpu_bo); |
| 266 | } | ||
| 267 | 267 | ||
| 268 | amdgpu_bo_unref(&adev->uvd.vcpu_bo); | 268 | amdgpu_bo_unref(&adev->uvd.vcpu_bo); |
| 269 | } | ||
| 269 | 270 | ||
| 270 | amdgpu_ring_fini(&adev->uvd.ring); | 271 | amdgpu_ring_fini(&adev->uvd.ring); |
| 271 | 272 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 9f36ed30ba11..62a4c127620f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
| @@ -298,7 +298,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
| 298 | unsigned vm_id, uint64_t pd_addr, | 298 | unsigned vm_id, uint64_t pd_addr, |
| 299 | uint32_t gds_base, uint32_t gds_size, | 299 | uint32_t gds_base, uint32_t gds_size, |
| 300 | uint32_t gws_base, uint32_t gws_size, | 300 | uint32_t gws_base, uint32_t gws_size, |
| 301 | uint32_t oa_base, uint32_t oa_size) | 301 | uint32_t oa_base, uint32_t oa_size, |
| 302 | bool vmid_switch) | ||
| 302 | { | 303 | { |
| 303 | struct amdgpu_device *adev = ring->adev; | 304 | struct amdgpu_device *adev = ring->adev; |
| 304 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; | 305 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; |
| @@ -312,8 +313,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
| 312 | int r; | 313 | int r; |
| 313 | 314 | ||
| 314 | if (ring->funcs->emit_pipeline_sync && ( | 315 | if (ring->funcs->emit_pipeline_sync && ( |
| 315 | pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || | 316 | pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || vmid_switch)) |
| 316 | ring->type == AMDGPU_RING_TYPE_COMPUTE)) | ||
| 317 | amdgpu_ring_emit_pipeline_sync(ring); | 317 | amdgpu_ring_emit_pipeline_sync(ring); |
| 318 | 318 | ||
| 319 | if (ring->funcs->emit_vm_flush && | 319 | if (ring->funcs->emit_vm_flush && |
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index ea407db1fbcf..5ec1f1e9c983 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
| @@ -6221,6 +6221,9 @@ static int ci_dpm_sw_fini(void *handle) | |||
| 6221 | ci_dpm_fini(adev); | 6221 | ci_dpm_fini(adev); |
| 6222 | mutex_unlock(&adev->pm.mutex); | 6222 | mutex_unlock(&adev->pm.mutex); |
| 6223 | 6223 | ||
| 6224 | release_firmware(adev->pm.fw); | ||
| 6225 | adev->pm.fw = NULL; | ||
| 6226 | |||
| 6224 | return 0; | 6227 | return 0; |
| 6225 | } | 6228 | } |
| 6226 | 6229 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 518dca43b133..9dc4e24e31e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
| @@ -66,6 +66,16 @@ MODULE_FIRMWARE("radeon/mullins_sdma1.bin"); | |||
| 66 | 66 | ||
| 67 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); | 67 | u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev); |
| 68 | 68 | ||
| 69 | |||
| 70 | static void cik_sdma_free_microcode(struct amdgpu_device *adev) | ||
| 71 | { | ||
| 72 | int i; | ||
| 73 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 74 | release_firmware(adev->sdma.instance[i].fw); | ||
| 75 | adev->sdma.instance[i].fw = NULL; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 69 | /* | 79 | /* |
| 70 | * sDMA - System DMA | 80 | * sDMA - System DMA |
| 71 | * Starting with CIK, the GPU has new asynchronous | 81 | * Starting with CIK, the GPU has new asynchronous |
| @@ -419,6 +429,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) | |||
| 419 | /* Initialize the ring buffer's read and write pointers */ | 429 | /* Initialize the ring buffer's read and write pointers */ |
| 420 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 430 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 421 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 431 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 432 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
| 433 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
| 422 | 434 | ||
| 423 | /* set the wb address whether it's enabled or not */ | 435 | /* set the wb address whether it's enabled or not */ |
| 424 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 436 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -446,7 +458,12 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) | |||
| 446 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 458 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 447 | 459 | ||
| 448 | ring->ready = true; | 460 | ring->ready = true; |
| 461 | } | ||
| 462 | |||
| 463 | cik_sdma_enable(adev, true); | ||
| 449 | 464 | ||
| 465 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 466 | ring = &adev->sdma.instance[i].ring; | ||
| 450 | r = amdgpu_ring_test_ring(ring); | 467 | r = amdgpu_ring_test_ring(ring); |
| 451 | if (r) { | 468 | if (r) { |
| 452 | ring->ready = false; | 469 | ring->ready = false; |
| @@ -529,8 +546,8 @@ static int cik_sdma_start(struct amdgpu_device *adev) | |||
| 529 | if (r) | 546 | if (r) |
| 530 | return r; | 547 | return r; |
| 531 | 548 | ||
| 532 | /* unhalt the MEs */ | 549 | /* halt the engine before programing */ |
| 533 | cik_sdma_enable(adev, true); | 550 | cik_sdma_enable(adev, false); |
| 534 | 551 | ||
| 535 | /* start the gfx rings and rlc compute queues */ | 552 | /* start the gfx rings and rlc compute queues */ |
| 536 | r = cik_sdma_gfx_resume(adev); | 553 | r = cik_sdma_gfx_resume(adev); |
| @@ -998,6 +1015,7 @@ static int cik_sdma_sw_fini(void *handle) | |||
| 998 | for (i = 0; i < adev->sdma.num_instances; i++) | 1015 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 999 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1016 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1000 | 1017 | ||
| 1018 | cik_sdma_free_microcode(adev); | ||
| 1001 | return 0; | 1019 | return 0; |
| 1002 | } | 1020 | } |
| 1003 | 1021 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c index 245cabf06575..ed03b75175d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c | |||
| @@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle) | |||
| 72 | 72 | ||
| 73 | static int fiji_dpm_sw_fini(void *handle) | 73 | static int fiji_dpm_sw_fini(void *handle) |
| 74 | { | 74 | { |
| 75 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 76 | |||
| 77 | release_firmware(adev->pm.fw); | ||
| 78 | adev->pm.fw = NULL; | ||
| 79 | |||
| 75 | return 0; | 80 | return 0; |
| 76 | } | 81 | } |
| 77 | 82 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 7f18a53ab53a..8c6ad1e72f02 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
| @@ -991,6 +991,22 @@ out: | |||
| 991 | return err; | 991 | return err; |
| 992 | } | 992 | } |
| 993 | 993 | ||
| 994 | static void gfx_v7_0_free_microcode(struct amdgpu_device *adev) | ||
| 995 | { | ||
| 996 | release_firmware(adev->gfx.pfp_fw); | ||
| 997 | adev->gfx.pfp_fw = NULL; | ||
| 998 | release_firmware(adev->gfx.me_fw); | ||
| 999 | adev->gfx.me_fw = NULL; | ||
| 1000 | release_firmware(adev->gfx.ce_fw); | ||
| 1001 | adev->gfx.ce_fw = NULL; | ||
| 1002 | release_firmware(adev->gfx.mec_fw); | ||
| 1003 | adev->gfx.mec_fw = NULL; | ||
| 1004 | release_firmware(adev->gfx.mec2_fw); | ||
| 1005 | adev->gfx.mec2_fw = NULL; | ||
| 1006 | release_firmware(adev->gfx.rlc_fw); | ||
| 1007 | adev->gfx.rlc_fw = NULL; | ||
| 1008 | } | ||
| 1009 | |||
| 994 | /** | 1010 | /** |
| 995 | * gfx_v7_0_tiling_mode_table_init - init the hw tiling table | 1011 | * gfx_v7_0_tiling_mode_table_init - init the hw tiling table |
| 996 | * | 1012 | * |
| @@ -4489,6 +4505,7 @@ static int gfx_v7_0_sw_fini(void *handle) | |||
| 4489 | gfx_v7_0_cp_compute_fini(adev); | 4505 | gfx_v7_0_cp_compute_fini(adev); |
| 4490 | gfx_v7_0_rlc_fini(adev); | 4506 | gfx_v7_0_rlc_fini(adev); |
| 4491 | gfx_v7_0_mec_fini(adev); | 4507 | gfx_v7_0_mec_fini(adev); |
| 4508 | gfx_v7_0_free_microcode(adev); | ||
| 4492 | 4509 | ||
| 4493 | return 0; | 4510 | return 0; |
| 4494 | } | 4511 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index f19bab68fd83..9f6f8669edc3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
| @@ -836,6 +836,26 @@ err1: | |||
| 836 | return r; | 836 | return r; |
| 837 | } | 837 | } |
| 838 | 838 | ||
| 839 | |||
| 840 | static void gfx_v8_0_free_microcode(struct amdgpu_device *adev) { | ||
| 841 | release_firmware(adev->gfx.pfp_fw); | ||
| 842 | adev->gfx.pfp_fw = NULL; | ||
| 843 | release_firmware(adev->gfx.me_fw); | ||
| 844 | adev->gfx.me_fw = NULL; | ||
| 845 | release_firmware(adev->gfx.ce_fw); | ||
| 846 | adev->gfx.ce_fw = NULL; | ||
| 847 | release_firmware(adev->gfx.rlc_fw); | ||
| 848 | adev->gfx.rlc_fw = NULL; | ||
| 849 | release_firmware(adev->gfx.mec_fw); | ||
| 850 | adev->gfx.mec_fw = NULL; | ||
| 851 | if ((adev->asic_type != CHIP_STONEY) && | ||
| 852 | (adev->asic_type != CHIP_TOPAZ)) | ||
| 853 | release_firmware(adev->gfx.mec2_fw); | ||
| 854 | adev->gfx.mec2_fw = NULL; | ||
| 855 | |||
| 856 | kfree(adev->gfx.rlc.register_list_format); | ||
| 857 | } | ||
| 858 | |||
| 839 | static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | 859 | static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) |
| 840 | { | 860 | { |
| 841 | const char *chip_name; | 861 | const char *chip_name; |
| @@ -1983,7 +2003,7 @@ static int gfx_v8_0_sw_fini(void *handle) | |||
| 1983 | 2003 | ||
| 1984 | gfx_v8_0_rlc_fini(adev); | 2004 | gfx_v8_0_rlc_fini(adev); |
| 1985 | 2005 | ||
| 1986 | kfree(adev->gfx.rlc.register_list_format); | 2006 | gfx_v8_0_free_microcode(adev); |
| 1987 | 2007 | ||
| 1988 | return 0; | 2008 | return 0; |
| 1989 | } | 2009 | } |
| @@ -3974,11 +3994,15 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) | |||
| 3974 | amdgpu_ring_write(ring, 0x3a00161a); | 3994 | amdgpu_ring_write(ring, 0x3a00161a); |
| 3975 | amdgpu_ring_write(ring, 0x0000002e); | 3995 | amdgpu_ring_write(ring, 0x0000002e); |
| 3976 | break; | 3996 | break; |
| 3977 | case CHIP_TOPAZ: | ||
| 3978 | case CHIP_CARRIZO: | 3997 | case CHIP_CARRIZO: |
| 3979 | amdgpu_ring_write(ring, 0x00000002); | 3998 | amdgpu_ring_write(ring, 0x00000002); |
| 3980 | amdgpu_ring_write(ring, 0x00000000); | 3999 | amdgpu_ring_write(ring, 0x00000000); |
| 3981 | break; | 4000 | break; |
| 4001 | case CHIP_TOPAZ: | ||
| 4002 | amdgpu_ring_write(ring, adev->gfx.config.num_rbs == 1 ? | ||
| 4003 | 0x00000000 : 0x00000002); | ||
| 4004 | amdgpu_ring_write(ring, 0x00000000); | ||
| 4005 | break; | ||
| 3982 | case CHIP_STONEY: | 4006 | case CHIP_STONEY: |
| 3983 | amdgpu_ring_write(ring, 0x00000000); | 4007 | amdgpu_ring_write(ring, 0x00000000); |
| 3984 | amdgpu_ring_write(ring, 0x00000000); | 4008 | amdgpu_ring_write(ring, 0x00000000); |
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c index 460bc8ad37e6..825ccd63f2dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_dpm.c | |||
| @@ -72,6 +72,11 @@ static int iceland_dpm_sw_init(void *handle) | |||
| 72 | 72 | ||
| 73 | static int iceland_dpm_sw_fini(void *handle) | 73 | static int iceland_dpm_sw_fini(void *handle) |
| 74 | { | 74 | { |
| 75 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 76 | |||
| 77 | release_firmware(adev->pm.fw); | ||
| 78 | adev->pm.fw = NULL; | ||
| 79 | |||
| 75 | return 0; | 80 | return 0; |
| 76 | } | 81 | } |
| 77 | 82 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index f4c3130d3fdb..b556bd0a8797 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
| @@ -105,6 +105,15 @@ static void sdma_v2_4_init_golden_registers(struct amdgpu_device *adev) | |||
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static void sdma_v2_4_free_microcode(struct amdgpu_device *adev) | ||
| 109 | { | ||
| 110 | int i; | ||
| 111 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 112 | release_firmware(adev->sdma.instance[i].fw); | ||
| 113 | adev->sdma.instance[i].fw = NULL; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 108 | /** | 117 | /** |
| 109 | * sdma_v2_4_init_microcode - load ucode images from disk | 118 | * sdma_v2_4_init_microcode - load ucode images from disk |
| 110 | * | 119 | * |
| @@ -461,6 +470,8 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) | |||
| 461 | /* Initialize the ring buffer's read and write pointers */ | 470 | /* Initialize the ring buffer's read and write pointers */ |
| 462 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 471 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 463 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 472 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 473 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
| 474 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
| 464 | 475 | ||
| 465 | /* set the wb address whether it's enabled or not */ | 476 | /* set the wb address whether it's enabled or not */ |
| 466 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 477 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -489,7 +500,11 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) | |||
| 489 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 500 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 490 | 501 | ||
| 491 | ring->ready = true; | 502 | ring->ready = true; |
| 503 | } | ||
| 492 | 504 | ||
| 505 | sdma_v2_4_enable(adev, true); | ||
| 506 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 507 | ring = &adev->sdma.instance[i].ring; | ||
| 493 | r = amdgpu_ring_test_ring(ring); | 508 | r = amdgpu_ring_test_ring(ring); |
| 494 | if (r) { | 509 | if (r) { |
| 495 | ring->ready = false; | 510 | ring->ready = false; |
| @@ -580,8 +595,8 @@ static int sdma_v2_4_start(struct amdgpu_device *adev) | |||
| 580 | return -EINVAL; | 595 | return -EINVAL; |
| 581 | } | 596 | } |
| 582 | 597 | ||
| 583 | /* unhalt the MEs */ | 598 | /* halt the engine before programing */ |
| 584 | sdma_v2_4_enable(adev, true); | 599 | sdma_v2_4_enable(adev, false); |
| 585 | 600 | ||
| 586 | /* start the gfx rings and rlc compute queues */ | 601 | /* start the gfx rings and rlc compute queues */ |
| 587 | r = sdma_v2_4_gfx_resume(adev); | 602 | r = sdma_v2_4_gfx_resume(adev); |
| @@ -1012,6 +1027,7 @@ static int sdma_v2_4_sw_fini(void *handle) | |||
| 1012 | for (i = 0; i < adev->sdma.num_instances; i++) | 1027 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 1013 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1028 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1014 | 1029 | ||
| 1030 | sdma_v2_4_free_microcode(adev); | ||
| 1015 | return 0; | 1031 | return 0; |
| 1016 | } | 1032 | } |
| 1017 | 1033 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 31d99b0010f7..532ea88da66a 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
| @@ -236,6 +236,15 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev) | |||
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | static void sdma_v3_0_free_microcode(struct amdgpu_device *adev) | ||
| 240 | { | ||
| 241 | int i; | ||
| 242 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 243 | release_firmware(adev->sdma.instance[i].fw); | ||
| 244 | adev->sdma.instance[i].fw = NULL; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 239 | /** | 248 | /** |
| 240 | * sdma_v3_0_init_microcode - load ucode images from disk | 249 | * sdma_v3_0_init_microcode - load ucode images from disk |
| 241 | * | 250 | * |
| @@ -672,6 +681,8 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
| 672 | /* Initialize the ring buffer's read and write pointers */ | 681 | /* Initialize the ring buffer's read and write pointers */ |
| 673 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); | 682 | WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); |
| 674 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); | 683 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); |
| 684 | WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); | ||
| 685 | WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); | ||
| 675 | 686 | ||
| 676 | /* set the wb address whether it's enabled or not */ | 687 | /* set the wb address whether it's enabled or not */ |
| 677 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], | 688 | WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], |
| @@ -711,7 +722,15 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) | |||
| 711 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); | 722 | WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); |
| 712 | 723 | ||
| 713 | ring->ready = true; | 724 | ring->ready = true; |
| 725 | } | ||
| 726 | |||
| 727 | /* unhalt the MEs */ | ||
| 728 | sdma_v3_0_enable(adev, true); | ||
| 729 | /* enable sdma ring preemption */ | ||
| 730 | sdma_v3_0_ctx_switch_enable(adev, true); | ||
| 714 | 731 | ||
| 732 | for (i = 0; i < adev->sdma.num_instances; i++) { | ||
| 733 | ring = &adev->sdma.instance[i].ring; | ||
| 715 | r = amdgpu_ring_test_ring(ring); | 734 | r = amdgpu_ring_test_ring(ring); |
| 716 | if (r) { | 735 | if (r) { |
| 717 | ring->ready = false; | 736 | ring->ready = false; |
| @@ -804,10 +823,9 @@ static int sdma_v3_0_start(struct amdgpu_device *adev) | |||
| 804 | } | 823 | } |
| 805 | } | 824 | } |
| 806 | 825 | ||
| 807 | /* unhalt the MEs */ | 826 | /* disble sdma engine before programing it */ |
| 808 | sdma_v3_0_enable(adev, true); | 827 | sdma_v3_0_ctx_switch_enable(adev, false); |
| 809 | /* enable sdma ring preemption */ | 828 | sdma_v3_0_enable(adev, false); |
| 810 | sdma_v3_0_ctx_switch_enable(adev, true); | ||
| 811 | 829 | ||
| 812 | /* start the gfx rings and rlc compute queues */ | 830 | /* start the gfx rings and rlc compute queues */ |
| 813 | r = sdma_v3_0_gfx_resume(adev); | 831 | r = sdma_v3_0_gfx_resume(adev); |
| @@ -1247,6 +1265,7 @@ static int sdma_v3_0_sw_fini(void *handle) | |||
| 1247 | for (i = 0; i < adev->sdma.num_instances; i++) | 1265 | for (i = 0; i < adev->sdma.num_instances; i++) |
| 1248 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); | 1266 | amdgpu_ring_fini(&adev->sdma.instance[i].ring); |
| 1249 | 1267 | ||
| 1268 | sdma_v3_0_free_microcode(adev); | ||
| 1250 | return 0; | 1269 | return 0; |
| 1251 | } | 1270 | } |
| 1252 | 1271 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c index b7615cefcac4..f06f6f4dc3a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_dpm.c | |||
| @@ -71,6 +71,11 @@ static int tonga_dpm_sw_init(void *handle) | |||
| 71 | 71 | ||
| 72 | static int tonga_dpm_sw_fini(void *handle) | 72 | static int tonga_dpm_sw_fini(void *handle) |
| 73 | { | 73 | { |
| 74 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 75 | |||
| 76 | release_firmware(adev->pm.fw); | ||
| 77 | adev->pm.fw = NULL; | ||
| 78 | |||
| 74 | return 0; | 79 | return 0; |
| 75 | } | 80 | } |
| 76 | 81 | ||
diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 6080951d539d..afce1edbe250 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h | |||
| @@ -157,6 +157,7 @@ struct amd_ip_funcs { | |||
| 157 | int (*hw_init)(void *handle); | 157 | int (*hw_init)(void *handle); |
| 158 | /* tears down the hw state */ | 158 | /* tears down the hw state */ |
| 159 | int (*hw_fini)(void *handle); | 159 | int (*hw_fini)(void *handle); |
| 160 | void (*late_fini)(void *handle); | ||
| 160 | /* handles IP specific hw/sw changes for suspend */ | 161 | /* handles IP specific hw/sw changes for suspend */ |
| 161 | int (*suspend)(void *handle); | 162 | int (*suspend)(void *handle); |
| 162 | /* handles IP specific hw/sw changes for resume */ | 163 | /* handles IP specific hw/sw changes for resume */ |
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h index a461e155a160..7464daf89ca1 100644 --- a/drivers/gpu/drm/amd/include/cgs_common.h +++ b/drivers/gpu/drm/amd/include/cgs_common.h | |||
| @@ -581,6 +581,9 @@ typedef int (*cgs_get_firmware_info)(struct cgs_device *cgs_device, | |||
| 581 | enum cgs_ucode_id type, | 581 | enum cgs_ucode_id type, |
| 582 | struct cgs_firmware_info *info); | 582 | struct cgs_firmware_info *info); |
| 583 | 583 | ||
| 584 | typedef int (*cgs_rel_firmware)(struct cgs_device *cgs_device, | ||
| 585 | enum cgs_ucode_id type); | ||
| 586 | |||
| 584 | typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, | 587 | typedef int(*cgs_set_powergating_state)(struct cgs_device *cgs_device, |
| 585 | enum amd_ip_block_type block_type, | 588 | enum amd_ip_block_type block_type, |
| 586 | enum amd_powergating_state state); | 589 | enum amd_powergating_state state); |
| @@ -645,6 +648,7 @@ struct cgs_ops { | |||
| 645 | cgs_set_camera_voltages_t set_camera_voltages; | 648 | cgs_set_camera_voltages_t set_camera_voltages; |
| 646 | /* Firmware Info */ | 649 | /* Firmware Info */ |
| 647 | cgs_get_firmware_info get_firmware_info; | 650 | cgs_get_firmware_info get_firmware_info; |
| 651 | cgs_rel_firmware rel_firmware; | ||
| 648 | /* cg pg interface*/ | 652 | /* cg pg interface*/ |
| 649 | cgs_set_powergating_state set_powergating_state; | 653 | cgs_set_powergating_state set_powergating_state; |
| 650 | cgs_set_clockgating_state set_clockgating_state; | 654 | cgs_set_clockgating_state set_clockgating_state; |
| @@ -738,6 +742,8 @@ struct cgs_device | |||
| 738 | CGS_CALL(set_camera_voltages,dev,mask,voltages) | 742 | CGS_CALL(set_camera_voltages,dev,mask,voltages) |
| 739 | #define cgs_get_firmware_info(dev, type, info) \ | 743 | #define cgs_get_firmware_info(dev, type, info) \ |
| 740 | CGS_CALL(get_firmware_info, dev, type, info) | 744 | CGS_CALL(get_firmware_info, dev, type, info) |
| 745 | #define cgs_rel_firmware(dev, type) \ | ||
| 746 | CGS_CALL(rel_firmware, dev, type) | ||
| 741 | #define cgs_set_powergating_state(dev, block_type, state) \ | 747 | #define cgs_set_powergating_state(dev, block_type, state) \ |
| 742 | CGS_CALL(set_powergating_state, dev, block_type, state) | 748 | CGS_CALL(set_powergating_state, dev, block_type, state) |
| 743 | #define cgs_set_clockgating_state(dev, block_type, state) \ | 749 | #define cgs_set_clockgating_state(dev, block_type, state) \ |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 8e345bfddb69..e629f8a9fe93 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
| @@ -73,11 +73,14 @@ static int pp_sw_init(void *handle) | |||
| 73 | 73 | ||
| 74 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); | 74 | ret = hwmgr->hwmgr_func->backend_init(hwmgr); |
| 75 | if (ret) | 75 | if (ret) |
| 76 | goto err; | 76 | goto err1; |
| 77 | 77 | ||
| 78 | pr_info("amdgpu: powerplay initialized\n"); | 78 | pr_info("amdgpu: powerplay initialized\n"); |
| 79 | 79 | ||
| 80 | return 0; | 80 | return 0; |
| 81 | err1: | ||
| 82 | if (hwmgr->pptable_func->pptable_fini) | ||
| 83 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
| 81 | err: | 84 | err: |
| 82 | pr_err("amdgpu: powerplay initialization failed\n"); | 85 | pr_err("amdgpu: powerplay initialization failed\n"); |
| 83 | return ret; | 86 | return ret; |
| @@ -100,6 +103,9 @@ static int pp_sw_fini(void *handle) | |||
| 100 | if (hwmgr->hwmgr_func->backend_fini != NULL) | 103 | if (hwmgr->hwmgr_func->backend_fini != NULL) |
| 101 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); | 104 | ret = hwmgr->hwmgr_func->backend_fini(hwmgr); |
| 102 | 105 | ||
| 106 | if (hwmgr->pptable_func->pptable_fini) | ||
| 107 | hwmgr->pptable_func->pptable_fini(hwmgr); | ||
| 108 | |||
| 103 | return ret; | 109 | return ret; |
| 104 | } | 110 | } |
| 105 | 111 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c index 46410e3c7349..fb88e4e5d625 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | |||
| @@ -58,9 +58,6 @@ static void pem_fini(struct pp_eventmgr *eventmgr) | |||
| 58 | pem_unregister_interrupts(eventmgr); | 58 | pem_unregister_interrupts(eventmgr); |
| 59 | 59 | ||
| 60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); | 60 | pem_handle_event(eventmgr, AMD_PP_EVENT_UNINITIALIZE, &event_data); |
| 61 | |||
| 62 | if (eventmgr != NULL) | ||
| 63 | kfree(eventmgr); | ||
| 64 | } | 61 | } |
| 65 | 62 | ||
| 66 | int eventmgr_init(struct pp_instance *handle) | 63 | int eventmgr_init(struct pp_instance *handle) |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 24a16e49b571..586f73276226 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | |||
| @@ -1830,7 +1830,7 @@ static uint16_t fiji_find_closest_vddci(struct pp_hwmgr *hwmgr, uint16_t vddci) | |||
| 1830 | 1830 | ||
| 1831 | PP_ASSERT_WITH_CODE(false, | 1831 | PP_ASSERT_WITH_CODE(false, |
| 1832 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", | 1832 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
| 1833 | return vddci_table->entries[i].value); | 1833 | return vddci_table->entries[i-1].value); |
| 1834 | } | 1834 | } |
| 1835 | 1835 | ||
| 1836 | static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, | 1836 | static int fiji_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 1c48917da3cf..20f20e075588 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |||
| @@ -93,6 +93,13 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr) | |||
| 93 | if (hwmgr == NULL || hwmgr->ps == NULL) | 93 | if (hwmgr == NULL || hwmgr->ps == NULL) |
| 94 | return -EINVAL; | 94 | return -EINVAL; |
| 95 | 95 | ||
| 96 | /* do hwmgr finish*/ | ||
| 97 | kfree(hwmgr->backend); | ||
| 98 | |||
| 99 | kfree(hwmgr->start_thermal_controller.function_list); | ||
| 100 | |||
| 101 | kfree(hwmgr->set_temperature_range.function_list); | ||
| 102 | |||
| 96 | kfree(hwmgr->ps); | 103 | kfree(hwmgr->ps); |
| 97 | kfree(hwmgr); | 104 | kfree(hwmgr); |
| 98 | return 0; | 105 | return 0; |
| @@ -462,7 +469,7 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u | |||
| 462 | 469 | ||
| 463 | PP_ASSERT_WITH_CODE(false, | 470 | PP_ASSERT_WITH_CODE(false, |
| 464 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", | 471 | "VDDCI is larger than max VDDCI in VDDCI Voltage Table!", |
| 465 | return vddci_table->entries[i].value); | 472 | return vddci_table->entries[i-1].value); |
| 466 | } | 473 | } |
| 467 | 474 | ||
| 468 | int phm_find_boot_level(void *table, | 475 | int phm_find_boot_level(void *table, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c index 0b99ab3ba0c5..ae96f14b827c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_powertune.c | |||
| @@ -286,7 +286,7 @@ int polaris10_populate_pm_fuses(struct pp_hwmgr *hwmgr) | |||
| 286 | 286 | ||
| 287 | if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, | 287 | if (polaris10_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, |
| 288 | (uint8_t *)&data->power_tune_table, | 288 | (uint8_t *)&data->power_tune_table, |
| 289 | sizeof(struct SMU74_Discrete_PmFuses), data->sram_end)) | 289 | (sizeof(struct SMU74_Discrete_PmFuses) - 92), data->sram_end)) |
| 290 | PP_ASSERT_WITH_CODE(false, | 290 | PP_ASSERT_WITH_CODE(false, |
| 291 | "Attempt to download PmFuseTable Failed!", | 291 | "Attempt to download PmFuseTable Failed!", |
| 292 | return -EINVAL); | 292 | return -EINVAL); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 16fed487973b..d27e8c40602a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c | |||
| @@ -2847,27 +2847,6 @@ static int tonga_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) | |||
| 2847 | } | 2847 | } |
| 2848 | } | 2848 | } |
| 2849 | 2849 | ||
| 2850 | /* Initialize Vddc DPM table based on allow Vddc values. And populate corresponding std values. */ | ||
| 2851 | for (i = 0; i < allowed_vdd_sclk_table->count; i++) { | ||
| 2852 | data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddc; | ||
| 2853 | /* tonga_hwmgr->dpm_table.VddcTable.dpm_levels[i].param1 = stdVoltageTable->entries[i].Leakage; */ | ||
| 2854 | /* param1 is for corresponding std voltage */ | ||
| 2855 | data->dpm_table.vddc_table.dpm_levels[i].enabled = 1; | ||
| 2856 | } | ||
| 2857 | data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count; | ||
| 2858 | |||
| 2859 | if (NULL != allowed_vdd_mclk_table) { | ||
| 2860 | /* Initialize Vddci DPM table based on allow Mclk values */ | ||
| 2861 | for (i = 0; i < allowed_vdd_mclk_table->count; i++) { | ||
| 2862 | data->dpm_table.vdd_ci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].vddci; | ||
| 2863 | data->dpm_table.vdd_ci_table.dpm_levels[i].enabled = 1; | ||
| 2864 | data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].mvdd; | ||
| 2865 | data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1; | ||
| 2866 | } | ||
| 2867 | data->dpm_table.vdd_ci_table.count = allowed_vdd_mclk_table->count; | ||
| 2868 | data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count; | ||
| 2869 | } | ||
| 2870 | |||
| 2871 | /* setup PCIE gen speed levels*/ | 2850 | /* setup PCIE gen speed levels*/ |
| 2872 | tonga_setup_default_pcie_tables(hwmgr); | 2851 | tonga_setup_default_pcie_tables(hwmgr); |
| 2873 | 2852 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c index 10e3630ee39d..296ec7ef6d45 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c | |||
| @@ -1040,48 +1040,44 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) | |||
| 1040 | struct phm_ppt_v1_information *pp_table_information = | 1040 | struct phm_ppt_v1_information *pp_table_information = |
| 1041 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 1041 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
| 1042 | 1042 | ||
| 1043 | if (NULL != hwmgr->soft_pp_table) { | 1043 | if (NULL != hwmgr->soft_pp_table) |
| 1044 | kfree(hwmgr->soft_pp_table); | ||
| 1045 | hwmgr->soft_pp_table = NULL; | 1044 | hwmgr->soft_pp_table = NULL; |
| 1046 | } | ||
| 1047 | 1045 | ||
| 1048 | if (NULL != pp_table_information->vdd_dep_on_sclk) | 1046 | kfree(pp_table_information->vdd_dep_on_sclk); |
| 1049 | pp_table_information->vdd_dep_on_sclk = NULL; | 1047 | pp_table_information->vdd_dep_on_sclk = NULL; |
| 1050 | 1048 | ||
| 1051 | if (NULL != pp_table_information->vdd_dep_on_mclk) | 1049 | kfree(pp_table_information->vdd_dep_on_mclk); |
| 1052 | pp_table_information->vdd_dep_on_mclk = NULL; | 1050 | pp_table_information->vdd_dep_on_mclk = NULL; |
| 1053 | 1051 | ||
| 1054 | if (NULL != pp_table_information->valid_mclk_values) | 1052 | kfree(pp_table_information->valid_mclk_values); |
| 1055 | pp_table_information->valid_mclk_values = NULL; | 1053 | pp_table_information->valid_mclk_values = NULL; |
| 1056 | 1054 | ||
| 1057 | if (NULL != pp_table_information->valid_sclk_values) | 1055 | kfree(pp_table_information->valid_sclk_values); |
| 1058 | pp_table_information->valid_sclk_values = NULL; | 1056 | pp_table_information->valid_sclk_values = NULL; |
| 1059 | 1057 | ||
| 1060 | if (NULL != pp_table_information->vddc_lookup_table) | 1058 | kfree(pp_table_information->vddc_lookup_table); |
| 1061 | pp_table_information->vddc_lookup_table = NULL; | 1059 | pp_table_information->vddc_lookup_table = NULL; |
| 1062 | 1060 | ||
| 1063 | if (NULL != pp_table_information->vddgfx_lookup_table) | 1061 | kfree(pp_table_information->vddgfx_lookup_table); |
| 1064 | pp_table_information->vddgfx_lookup_table = NULL; | 1062 | pp_table_information->vddgfx_lookup_table = NULL; |
| 1065 | 1063 | ||
| 1066 | if (NULL != pp_table_information->mm_dep_table) | 1064 | kfree(pp_table_information->mm_dep_table); |
| 1067 | pp_table_information->mm_dep_table = NULL; | 1065 | pp_table_information->mm_dep_table = NULL; |
| 1068 | 1066 | ||
| 1069 | if (NULL != pp_table_information->cac_dtp_table) | 1067 | kfree(pp_table_information->cac_dtp_table); |
| 1070 | pp_table_information->cac_dtp_table = NULL; | 1068 | pp_table_information->cac_dtp_table = NULL; |
| 1071 | 1069 | ||
| 1072 | if (NULL != hwmgr->dyn_state.cac_dtp_table) | 1070 | kfree(hwmgr->dyn_state.cac_dtp_table); |
| 1073 | hwmgr->dyn_state.cac_dtp_table = NULL; | 1071 | hwmgr->dyn_state.cac_dtp_table = NULL; |
| 1074 | 1072 | ||
| 1075 | if (NULL != pp_table_information->ppm_parameter_table) | 1073 | kfree(pp_table_information->ppm_parameter_table); |
| 1076 | pp_table_information->ppm_parameter_table = NULL; | 1074 | pp_table_information->ppm_parameter_table = NULL; |
| 1077 | 1075 | ||
| 1078 | if (NULL != pp_table_information->pcie_table) | 1076 | kfree(pp_table_information->pcie_table); |
| 1079 | pp_table_information->pcie_table = NULL; | 1077 | pp_table_information->pcie_table = NULL; |
| 1080 | 1078 | ||
| 1081 | if (NULL != hwmgr->pptable) { | 1079 | kfree(hwmgr->pptable); |
| 1082 | kfree(hwmgr->pptable); | 1080 | hwmgr->pptable = NULL; |
| 1083 | hwmgr->pptable = NULL; | ||
| 1084 | } | ||
| 1085 | 1081 | ||
| 1086 | return result; | 1082 | return result; |
| 1087 | } | 1083 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index 673a75c74e18..8e52a2e82db5 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | |||
| @@ -1006,10 +1006,16 @@ static int fiji_smu_init(struct pp_smumgr *smumgr) | |||
| 1006 | 1006 | ||
| 1007 | static int fiji_smu_fini(struct pp_smumgr *smumgr) | 1007 | static int fiji_smu_fini(struct pp_smumgr *smumgr) |
| 1008 | { | 1008 | { |
| 1009 | struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend); | ||
| 1010 | |||
| 1011 | smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | ||
| 1012 | |||
| 1009 | if (smumgr->backend) { | 1013 | if (smumgr->backend) { |
| 1010 | kfree(smumgr->backend); | 1014 | kfree(smumgr->backend); |
| 1011 | smumgr->backend = NULL; | 1015 | smumgr->backend = NULL; |
| 1012 | } | 1016 | } |
| 1017 | |||
| 1018 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
| 1013 | return 0; | 1019 | return 0; |
| 1014 | } | 1020 | } |
| 1015 | 1021 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index de618ead9db8..043b6ac09d5f 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | |||
| @@ -469,6 +469,7 @@ int polaris10_smu_fini(struct pp_smumgr *smumgr) | |||
| 469 | kfree(smumgr->backend); | 469 | kfree(smumgr->backend); |
| 470 | smumgr->backend = NULL; | 470 | smumgr->backend = NULL; |
| 471 | } | 471 | } |
| 472 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
| 472 | return 0; | 473 | return 0; |
| 473 | } | 474 | } |
| 474 | 475 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c index c483baf6b4fb..0728c1e3d97a 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c | |||
| @@ -81,6 +81,7 @@ int smum_init(struct amd_pp_init *pp_init, struct pp_instance *handle) | |||
| 81 | 81 | ||
| 82 | int smum_fini(struct pp_smumgr *smumgr) | 82 | int smum_fini(struct pp_smumgr *smumgr) |
| 83 | { | 83 | { |
| 84 | kfree(smumgr->device); | ||
| 84 | kfree(smumgr); | 85 | kfree(smumgr); |
| 85 | return 0; | 86 | return 0; |
| 86 | } | 87 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c index 32820b680d88..b22722eabafc 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c | |||
| @@ -328,10 +328,17 @@ int tonga_write_smc_sram_dword(struct pp_smumgr *smumgr, | |||
| 328 | 328 | ||
| 329 | static int tonga_smu_fini(struct pp_smumgr *smumgr) | 329 | static int tonga_smu_fini(struct pp_smumgr *smumgr) |
| 330 | { | 330 | { |
| 331 | struct tonga_smumgr *priv = (struct tonga_smumgr *)(smumgr->backend); | ||
| 332 | |||
| 333 | smu_free_memory(smumgr->device, (void *)priv->smu_buffer.handle); | ||
| 334 | smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle); | ||
| 335 | |||
| 331 | if (smumgr->backend != NULL) { | 336 | if (smumgr->backend != NULL) { |
| 332 | kfree(smumgr->backend); | 337 | kfree(smumgr->backend); |
| 333 | smumgr->backend = NULL; | 338 | smumgr->backend = NULL; |
| 334 | } | 339 | } |
| 340 | |||
| 341 | cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU); | ||
| 335 | return 0; | 342 | return 0; |
| 336 | } | 343 | } |
| 337 | 344 | ||
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index fef1b04c2aab..0813c2f06931 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c | |||
| @@ -33,8 +33,17 @@ | |||
| 33 | * | 33 | * |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | static void hdlcd_crtc_cleanup(struct drm_crtc *crtc) | ||
| 37 | { | ||
| 38 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | ||
| 39 | |||
| 40 | /* stop the controller on cleanup */ | ||
| 41 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | ||
| 42 | drm_crtc_cleanup(crtc); | ||
| 43 | } | ||
| 44 | |||
| 36 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { | 45 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { |
| 37 | .destroy = drm_crtc_cleanup, | 46 | .destroy = hdlcd_crtc_cleanup, |
| 38 | .set_config = drm_atomic_helper_set_config, | 47 | .set_config = drm_atomic_helper_set_config, |
| 39 | .page_flip = drm_atomic_helper_page_flip, | 48 | .page_flip = drm_atomic_helper_page_flip, |
| 40 | .reset = drm_atomic_helper_crtc_reset, | 49 | .reset = drm_atomic_helper_crtc_reset, |
| @@ -97,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 97 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 106 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 98 | struct drm_display_mode *m = &crtc->state->adjusted_mode; | 107 | struct drm_display_mode *m = &crtc->state->adjusted_mode; |
| 99 | struct videomode vm; | 108 | struct videomode vm; |
| 100 | unsigned int polarities, line_length, err; | 109 | unsigned int polarities, err; |
| 101 | 110 | ||
| 102 | vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay; | 111 | vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay; |
| 103 | vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end; | 112 | vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end; |
| @@ -113,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 113 | if (m->flags & DRM_MODE_FLAG_PVSYNC) | 122 | if (m->flags & DRM_MODE_FLAG_PVSYNC) |
| 114 | polarities |= HDLCD_POLARITY_VSYNC; | 123 | polarities |= HDLCD_POLARITY_VSYNC; |
| 115 | 124 | ||
| 116 | line_length = crtc->primary->state->fb->pitches[0]; | ||
| 117 | |||
| 118 | /* Allow max number of outstanding requests and largest burst size */ | 125 | /* Allow max number of outstanding requests and largest burst size */ |
| 119 | hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS, | 126 | hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS, |
| 120 | HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16); | 127 | HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16); |
| 121 | 128 | ||
| 122 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length); | ||
| 123 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length); | ||
| 124 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1); | ||
| 125 | hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1); | 129 | hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1); |
| 126 | hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1); | 130 | hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1); |
| 127 | hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1); | 131 | hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1); |
| 128 | hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1); | 132 | hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1); |
| 133 | hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1); | ||
| 129 | hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1); | 134 | hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1); |
| 130 | hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1); | 135 | hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1); |
| 131 | hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1); | 136 | hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1); |
| 132 | hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1); | ||
| 133 | hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities); | 137 | hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities); |
| 134 | 138 | ||
| 135 | err = hdlcd_set_pxl_fmt(crtc); | 139 | err = hdlcd_set_pxl_fmt(crtc); |
| @@ -144,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc) | |||
| 144 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 148 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 145 | 149 | ||
| 146 | clk_prepare_enable(hdlcd->clk); | 150 | clk_prepare_enable(hdlcd->clk); |
| 151 | hdlcd_crtc_mode_set_nofb(crtc); | ||
| 147 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); | 152 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); |
| 148 | drm_crtc_vblank_on(crtc); | ||
| 149 | } | 153 | } |
| 150 | 154 | ||
| 151 | static void hdlcd_crtc_disable(struct drm_crtc *crtc) | 155 | static void hdlcd_crtc_disable(struct drm_crtc *crtc) |
| 152 | { | 156 | { |
| 153 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 157 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 154 | 158 | ||
| 155 | if (!crtc->primary->fb) | 159 | if (!crtc->state->active) |
| 156 | return; | 160 | return; |
| 157 | 161 | ||
| 158 | clk_disable_unprepare(hdlcd->clk); | ||
| 159 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | 162 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); |
| 160 | drm_crtc_vblank_off(crtc); | 163 | clk_disable_unprepare(hdlcd->clk); |
| 161 | } | 164 | } |
| 162 | 165 | ||
| 163 | static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, | 166 | static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, |
| @@ -179,20 +182,17 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, | |||
| 179 | static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, | 182 | static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, |
| 180 | struct drm_crtc_state *state) | 183 | struct drm_crtc_state *state) |
| 181 | { | 184 | { |
| 182 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 185 | struct drm_pending_vblank_event *event = crtc->state->event; |
| 183 | unsigned long flags; | ||
| 184 | |||
| 185 | if (crtc->state->event) { | ||
| 186 | struct drm_pending_vblank_event *event = crtc->state->event; | ||
| 187 | 186 | ||
| 187 | if (event) { | ||
| 188 | crtc->state->event = NULL; | 188 | crtc->state->event = NULL; |
| 189 | event->pipe = drm_crtc_index(crtc); | ||
| 190 | |||
| 191 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | ||
| 192 | 189 | ||
| 193 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | 190 | spin_lock_irq(&crtc->dev->event_lock); |
| 194 | list_add_tail(&event->base.link, &hdlcd->event_list); | 191 | if (drm_crtc_vblank_get(crtc) == 0) |
| 195 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | 192 | drm_crtc_arm_vblank_event(crtc, event); |
| 193 | else | ||
| 194 | drm_crtc_send_vblank_event(crtc, event); | ||
| 195 | spin_unlock_irq(&crtc->dev->event_lock); | ||
| 196 | } | 196 | } |
| 197 | } | 197 | } |
| 198 | 198 | ||
| @@ -225,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { | |||
| 225 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, | 225 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, |
| 226 | struct drm_plane_state *state) | 226 | struct drm_plane_state *state) |
| 227 | { | 227 | { |
| 228 | u32 src_w, src_h; | ||
| 229 | |||
| 230 | src_w = state->src_w >> 16; | ||
| 231 | src_h = state->src_h >> 16; | ||
| 232 | |||
| 233 | /* we can't do any scaling of the plane source */ | ||
| 234 | if ((src_w != state->crtc_w) || (src_h != state->crtc_h)) | ||
| 235 | return -EINVAL; | ||
| 236 | |||
| 228 | return 0; | 237 | return 0; |
| 229 | } | 238 | } |
| 230 | 239 | ||
| @@ -233,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane, | |||
| 233 | { | 242 | { |
| 234 | struct hdlcd_drm_private *hdlcd; | 243 | struct hdlcd_drm_private *hdlcd; |
| 235 | struct drm_gem_cma_object *gem; | 244 | struct drm_gem_cma_object *gem; |
| 245 | unsigned int depth, bpp; | ||
| 246 | u32 src_w, src_h, dest_w, dest_h; | ||
| 236 | dma_addr_t scanout_start; | 247 | dma_addr_t scanout_start; |
| 237 | 248 | ||
| 238 | if (!plane->state->crtc || !plane->state->fb) | 249 | if (!plane->state->fb) |
| 239 | return; | 250 | return; |
| 240 | 251 | ||
| 241 | hdlcd = crtc_to_hdlcd_priv(plane->state->crtc); | 252 | drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp); |
| 253 | src_w = plane->state->src_w >> 16; | ||
| 254 | src_h = plane->state->src_h >> 16; | ||
| 255 | dest_w = plane->state->crtc_w; | ||
| 256 | dest_h = plane->state->crtc_h; | ||
| 242 | gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); | 257 | gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); |
| 243 | scanout_start = gem->paddr; | 258 | scanout_start = gem->paddr + plane->state->fb->offsets[0] + |
| 259 | plane->state->crtc_y * plane->state->fb->pitches[0] + | ||
| 260 | plane->state->crtc_x * bpp / 8; | ||
| 261 | |||
| 262 | hdlcd = plane->dev->dev_private; | ||
| 263 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]); | ||
| 264 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, plane->state->fb->pitches[0]); | ||
| 265 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, dest_h - 1); | ||
| 244 | hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start); | 266 | hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start); |
| 245 | } | 267 | } |
| 246 | 268 | ||
| 247 | static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = { | 269 | static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = { |
| 248 | .prepare_fb = NULL, | ||
| 249 | .cleanup_fb = NULL, | ||
| 250 | .atomic_check = hdlcd_plane_atomic_check, | 270 | .atomic_check = hdlcd_plane_atomic_check, |
| 251 | .atomic_update = hdlcd_plane_atomic_update, | 271 | .atomic_update = hdlcd_plane_atomic_update, |
| 252 | }; | 272 | }; |
| @@ -294,16 +314,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) | |||
| 294 | return plane; | 314 | return plane; |
| 295 | } | 315 | } |
| 296 | 316 | ||
| 297 | void hdlcd_crtc_suspend(struct drm_crtc *crtc) | ||
| 298 | { | ||
| 299 | hdlcd_crtc_disable(crtc); | ||
| 300 | } | ||
| 301 | |||
| 302 | void hdlcd_crtc_resume(struct drm_crtc *crtc) | ||
| 303 | { | ||
| 304 | hdlcd_crtc_enable(crtc); | ||
| 305 | } | ||
| 306 | |||
| 307 | int hdlcd_setup_crtc(struct drm_device *drm) | 317 | int hdlcd_setup_crtc(struct drm_device *drm) |
| 308 | { | 318 | { |
| 309 | struct hdlcd_drm_private *hdlcd = drm->dev_private; | 319 | struct hdlcd_drm_private *hdlcd = drm->dev_private; |
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index b987c63ba8d6..a6ca36f0096f 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c | |||
| @@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
| 49 | atomic_set(&hdlcd->dma_end_count, 0); | 49 | atomic_set(&hdlcd->dma_end_count, 0); |
| 50 | #endif | 50 | #endif |
| 51 | 51 | ||
| 52 | INIT_LIST_HEAD(&hdlcd->event_list); | ||
| 53 | |||
| 54 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 52 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 55 | hdlcd->mmio = devm_ioremap_resource(drm->dev, res); | 53 | hdlcd->mmio = devm_ioremap_resource(drm->dev, res); |
| 56 | if (IS_ERR(hdlcd->mmio)) { | 54 | if (IS_ERR(hdlcd->mmio)) { |
| @@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
| 84 | goto setup_fail; | 82 | goto setup_fail; |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | pm_runtime_enable(drm->dev); | ||
| 88 | |||
| 89 | pm_runtime_get_sync(drm->dev); | ||
| 90 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); | 85 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); |
| 91 | pm_runtime_put_sync(drm->dev); | ||
| 92 | if (ret < 0) { | 86 | if (ret < 0) { |
| 93 | DRM_ERROR("failed to install IRQ handler\n"); | 87 | DRM_ERROR("failed to install IRQ handler\n"); |
| 94 | goto irq_fail; | 88 | goto irq_fail; |
| @@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg) | |||
| 164 | atomic_inc(&hdlcd->vsync_count); | 158 | atomic_inc(&hdlcd->vsync_count); |
| 165 | 159 | ||
| 166 | #endif | 160 | #endif |
| 167 | if (irq_status & HDLCD_INTERRUPT_VSYNC) { | 161 | if (irq_status & HDLCD_INTERRUPT_VSYNC) |
| 168 | bool events_sent = false; | ||
| 169 | unsigned long flags; | ||
| 170 | struct drm_pending_vblank_event *e, *t; | ||
| 171 | |||
| 172 | drm_crtc_handle_vblank(&hdlcd->crtc); | 162 | drm_crtc_handle_vblank(&hdlcd->crtc); |
| 173 | 163 | ||
| 174 | spin_lock_irqsave(&drm->event_lock, flags); | ||
| 175 | list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) { | ||
| 176 | list_del(&e->base.link); | ||
| 177 | drm_crtc_send_vblank_event(&hdlcd->crtc, e); | ||
| 178 | events_sent = true; | ||
| 179 | } | ||
| 180 | if (events_sent) | ||
| 181 | drm_crtc_vblank_put(&hdlcd->crtc); | ||
| 182 | spin_unlock_irqrestore(&drm->event_lock, flags); | ||
| 183 | } | ||
| 184 | |||
| 185 | /* acknowledge interrupt(s) */ | 164 | /* acknowledge interrupt(s) */ |
| 186 | hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); | 165 | hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); |
| 187 | 166 | ||
| @@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) | |||
| 275 | static struct drm_info_list hdlcd_debugfs_list[] = { | 254 | static struct drm_info_list hdlcd_debugfs_list[] = { |
| 276 | { "interrupt_count", hdlcd_show_underrun_count, 0 }, | 255 | { "interrupt_count", hdlcd_show_underrun_count, 0 }, |
| 277 | { "clocks", hdlcd_show_pxlclock, 0 }, | 256 | { "clocks", hdlcd_show_pxlclock, 0 }, |
| 257 | { "fb", drm_fb_cma_debugfs_show, 0 }, | ||
| 278 | }; | 258 | }; |
| 279 | 259 | ||
| 280 | static int hdlcd_debugfs_init(struct drm_minor *minor) | 260 | static int hdlcd_debugfs_init(struct drm_minor *minor) |
| @@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 357 | return -ENOMEM; | 337 | return -ENOMEM; |
| 358 | 338 | ||
| 359 | drm->dev_private = hdlcd; | 339 | drm->dev_private = hdlcd; |
| 340 | dev_set_drvdata(dev, drm); | ||
| 341 | |||
| 360 | hdlcd_setup_mode_config(drm); | 342 | hdlcd_setup_mode_config(drm); |
| 361 | ret = hdlcd_load(drm, 0); | 343 | ret = hdlcd_load(drm, 0); |
| 362 | if (ret) | 344 | if (ret) |
| @@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 366 | if (ret) | 348 | if (ret) |
| 367 | goto err_unload; | 349 | goto err_unload; |
| 368 | 350 | ||
| 369 | dev_set_drvdata(dev, drm); | ||
| 370 | |||
| 371 | ret = component_bind_all(dev, drm); | 351 | ret = component_bind_all(dev, drm); |
| 372 | if (ret) { | 352 | if (ret) { |
| 373 | DRM_ERROR("Failed to bind all components\n"); | 353 | DRM_ERROR("Failed to bind all components\n"); |
| 374 | goto err_unregister; | 354 | goto err_unregister; |
| 375 | } | 355 | } |
| 376 | 356 | ||
| 357 | ret = pm_runtime_set_active(dev); | ||
| 358 | if (ret) | ||
| 359 | goto err_pm_active; | ||
| 360 | |||
| 361 | pm_runtime_enable(dev); | ||
| 362 | |||
| 377 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); | 363 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); |
| 378 | if (ret < 0) { | 364 | if (ret < 0) { |
| 379 | DRM_ERROR("failed to initialise vblank\n"); | 365 | DRM_ERROR("failed to initialise vblank\n"); |
| @@ -399,16 +385,16 @@ err_fbdev: | |||
| 399 | drm_mode_config_cleanup(drm); | 385 | drm_mode_config_cleanup(drm); |
| 400 | drm_vblank_cleanup(drm); | 386 | drm_vblank_cleanup(drm); |
| 401 | err_vblank: | 387 | err_vblank: |
| 388 | pm_runtime_disable(drm->dev); | ||
| 389 | err_pm_active: | ||
| 402 | component_unbind_all(dev, drm); | 390 | component_unbind_all(dev, drm); |
| 403 | err_unregister: | 391 | err_unregister: |
| 404 | drm_dev_unregister(drm); | 392 | drm_dev_unregister(drm); |
| 405 | err_unload: | 393 | err_unload: |
| 406 | pm_runtime_get_sync(drm->dev); | ||
| 407 | drm_irq_uninstall(drm); | 394 | drm_irq_uninstall(drm); |
| 408 | pm_runtime_put_sync(drm->dev); | ||
| 409 | pm_runtime_disable(drm->dev); | ||
| 410 | of_reserved_mem_device_release(drm->dev); | 395 | of_reserved_mem_device_release(drm->dev); |
| 411 | err_free: | 396 | err_free: |
| 397 | dev_set_drvdata(dev, NULL); | ||
| 412 | drm_dev_unref(drm); | 398 | drm_dev_unref(drm); |
| 413 | 399 | ||
| 414 | return ret; | 400 | return ret; |
| @@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match); | |||
| 495 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) | 481 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) |
| 496 | { | 482 | { |
| 497 | struct drm_device *drm = dev_get_drvdata(dev); | 483 | struct drm_device *drm = dev_get_drvdata(dev); |
| 498 | struct drm_crtc *crtc; | 484 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 499 | 485 | ||
| 500 | if (pm_runtime_suspended(dev)) | 486 | if (!hdlcd) |
| 501 | return 0; | 487 | return 0; |
| 502 | 488 | ||
| 503 | drm_modeset_lock_all(drm); | 489 | drm_kms_helper_poll_disable(drm); |
| 504 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 490 | |
| 505 | hdlcd_crtc_suspend(crtc); | 491 | hdlcd->state = drm_atomic_helper_suspend(drm); |
| 506 | drm_modeset_unlock_all(drm); | 492 | if (IS_ERR(hdlcd->state)) { |
| 493 | drm_kms_helper_poll_enable(drm); | ||
| 494 | return PTR_ERR(hdlcd->state); | ||
| 495 | } | ||
| 496 | |||
| 507 | return 0; | 497 | return 0; |
| 508 | } | 498 | } |
| 509 | 499 | ||
| 510 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) | 500 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) |
| 511 | { | 501 | { |
| 512 | struct drm_device *drm = dev_get_drvdata(dev); | 502 | struct drm_device *drm = dev_get_drvdata(dev); |
| 513 | struct drm_crtc *crtc; | 503 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 514 | 504 | ||
| 515 | if (!pm_runtime_suspended(dev)) | 505 | if (!hdlcd) |
| 516 | return 0; | 506 | return 0; |
| 517 | 507 | ||
| 518 | drm_modeset_lock_all(drm); | 508 | drm_atomic_helper_resume(drm, hdlcd->state); |
| 519 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 509 | drm_kms_helper_poll_enable(drm); |
| 520 | hdlcd_crtc_resume(crtc); | 510 | pm_runtime_set_active(dev); |
| 521 | drm_modeset_unlock_all(drm); | 511 | |
| 522 | return 0; | 512 | return 0; |
| 523 | } | 513 | } |
| 524 | 514 | ||
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h index aa234784f053..e3950a071152 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.h +++ b/drivers/gpu/drm/arm/hdlcd_drv.h | |||
| @@ -9,10 +9,9 @@ struct hdlcd_drm_private { | |||
| 9 | void __iomem *mmio; | 9 | void __iomem *mmio; |
| 10 | struct clk *clk; | 10 | struct clk *clk; |
| 11 | struct drm_fbdev_cma *fbdev; | 11 | struct drm_fbdev_cma *fbdev; |
| 12 | struct drm_framebuffer *fb; | ||
| 13 | struct list_head event_list; | ||
| 14 | struct drm_crtc crtc; | 12 | struct drm_crtc crtc; |
| 15 | struct drm_plane *plane; | 13 | struct drm_plane *plane; |
| 14 | struct drm_atomic_state *state; | ||
| 16 | #ifdef CONFIG_DEBUG_FS | 15 | #ifdef CONFIG_DEBUG_FS |
| 17 | atomic_t buffer_underrun_count; | 16 | atomic_t buffer_underrun_count; |
| 18 | atomic_t bus_error_count; | 17 | atomic_t bus_error_count; |
| @@ -36,7 +35,5 @@ static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg) | |||
| 36 | 35 | ||
| 37 | int hdlcd_setup_crtc(struct drm_device *dev); | 36 | int hdlcd_setup_crtc(struct drm_device *dev); |
| 38 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); | 37 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); |
| 39 | void hdlcd_crtc_suspend(struct drm_crtc *crtc); | ||
| 40 | void hdlcd_crtc_resume(struct drm_crtc *crtc); | ||
| 41 | 38 | ||
| 42 | #endif /* __HDLCD_DRV_H__ */ | 39 | #endif /* __HDLCD_DRV_H__ */ |
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index cf23a755f777..bd12231ab0cd 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | |||
| @@ -391,12 +391,11 @@ void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) | |||
| 391 | { | 391 | { |
| 392 | struct atmel_hlcdc_crtc_state *state; | 392 | struct atmel_hlcdc_crtc_state *state; |
| 393 | 393 | ||
| 394 | if (crtc->state && crtc->state->mode_blob) | ||
| 395 | drm_property_unreference_blob(crtc->state->mode_blob); | ||
| 396 | |||
| 397 | if (crtc->state) { | 394 | if (crtc->state) { |
| 395 | __drm_atomic_helper_crtc_destroy_state(crtc->state); | ||
| 398 | state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); | 396 | state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); |
| 399 | kfree(state); | 397 | kfree(state); |
| 398 | crtc->state = NULL; | ||
| 400 | } | 399 | } |
| 401 | 400 | ||
| 402 | state = kzalloc(sizeof(*state), GFP_KERNEL); | 401 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
| @@ -415,8 +414,9 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) | |||
| 415 | return NULL; | 414 | return NULL; |
| 416 | 415 | ||
| 417 | state = kmalloc(sizeof(*state), GFP_KERNEL); | 416 | state = kmalloc(sizeof(*state), GFP_KERNEL); |
| 418 | if (state) | 417 | if (!state) |
| 419 | __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); | 418 | return NULL; |
| 419 | __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); | ||
| 420 | 420 | ||
| 421 | cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); | 421 | cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); |
| 422 | state->output_mode = cur->output_mode; | 422 | state->output_mode = cur->output_mode; |
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 3ff1ed7b33db..c204ef32df16 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
| @@ -351,6 +351,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, | |||
| 351 | drm_property_unreference_blob(state->mode_blob); | 351 | drm_property_unreference_blob(state->mode_blob); |
| 352 | state->mode_blob = NULL; | 352 | state->mode_blob = NULL; |
| 353 | 353 | ||
| 354 | memset(&state->mode, 0, sizeof(state->mode)); | ||
| 355 | |||
| 354 | if (blob) { | 356 | if (blob) { |
| 355 | if (blob->length != sizeof(struct drm_mode_modeinfo) || | 357 | if (blob->length != sizeof(struct drm_mode_modeinfo) || |
| 356 | drm_mode_convert_umode(&state->mode, | 358 | drm_mode_convert_umode(&state->mode, |
| @@ -363,7 +365,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, | |||
| 363 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", | 365 | DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", |
| 364 | state->mode.name, state); | 366 | state->mode.name, state); |
| 365 | } else { | 367 | } else { |
| 366 | memset(&state->mode, 0, sizeof(state->mode)); | ||
| 367 | state->enable = false; | 368 | state->enable = false; |
| 368 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", | 369 | DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", |
| 369 | state); | 370 | state); |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d2a6d958ca76..0e3cc66aa8b7 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -2821,8 +2821,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, | |||
| 2821 | goto out; | 2821 | goto out; |
| 2822 | } | 2822 | } |
| 2823 | 2823 | ||
| 2824 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); | ||
| 2825 | |||
| 2826 | /* | 2824 | /* |
| 2827 | * Check whether the primary plane supports the fb pixel format. | 2825 | * Check whether the primary plane supports the fb pixel format. |
| 2828 | * Drivers not implementing the universal planes API use a | 2826 | * Drivers not implementing the universal planes API use a |
| @@ -4841,7 +4839,8 @@ bool drm_property_change_valid_get(struct drm_property *property, | |||
| 4841 | if (value == 0) | 4839 | if (value == 0) |
| 4842 | return true; | 4840 | return true; |
| 4843 | 4841 | ||
| 4844 | return _object_find(property->dev, value, property->values[0]) != NULL; | 4842 | *ref = _object_find(property->dev, value, property->values[0]); |
| 4843 | return *ref != NULL; | ||
| 4845 | } | 4844 | } |
| 4846 | 4845 | ||
| 4847 | for (i = 0; i < property->num_values; i++) | 4846 | for (i = 0; i < property->num_values; i++) |
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 172cafe11c71..5075fae3c4e2 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
| @@ -445,7 +445,7 @@ err_cma_destroy: | |||
| 445 | err_fb_info_destroy: | 445 | err_fb_info_destroy: |
| 446 | drm_fb_helper_release_fbi(helper); | 446 | drm_fb_helper_release_fbi(helper); |
| 447 | err_gem_free_object: | 447 | err_gem_free_object: |
| 448 | dev->driver->gem_free_object(&obj->base); | 448 | drm_gem_object_unreference_unlocked(&obj->base); |
| 449 | return ret; | 449 | return ret; |
| 450 | } | 450 | } |
| 451 | EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); | 451 | EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); |
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index e1ab008b3f08..1d6c335584ec 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c | |||
| @@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, | |||
| 121 | return cma_obj; | 121 | return cma_obj; |
| 122 | 122 | ||
| 123 | error: | 123 | error: |
| 124 | drm->driver->gem_free_object(&cma_obj->base); | 124 | drm_gem_object_unreference_unlocked(&cma_obj->base); |
| 125 | return ERR_PTR(ret); | 125 | return ERR_PTR(ret); |
| 126 | } | 126 | } |
| 127 | EXPORT_SYMBOL_GPL(drm_gem_cma_create); | 127 | EXPORT_SYMBOL_GPL(drm_gem_cma_create); |
| @@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, | |||
| 162 | * and handle has the id what user can see. | 162 | * and handle has the id what user can see. |
| 163 | */ | 163 | */ |
| 164 | ret = drm_gem_handle_create(file_priv, gem_obj, handle); | 164 | ret = drm_gem_handle_create(file_priv, gem_obj, handle); |
| 165 | if (ret) | ||
| 166 | goto err_handle_create; | ||
| 167 | |||
| 168 | /* drop reference from allocate - handle holds it now. */ | 165 | /* drop reference from allocate - handle holds it now. */ |
| 169 | drm_gem_object_unreference_unlocked(gem_obj); | 166 | drm_gem_object_unreference_unlocked(gem_obj); |
| 167 | if (ret) | ||
| 168 | return ERR_PTR(ret); | ||
| 170 | 169 | ||
| 171 | return cma_obj; | 170 | return cma_obj; |
| 172 | |||
| 173 | err_handle_create: | ||
| 174 | drm->driver->gem_free_object(gem_obj); | ||
| 175 | |||
| 176 | return ERR_PTR(ret); | ||
| 177 | } | 171 | } |
| 178 | 172 | ||
| 179 | /** | 173 | /** |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 7def3d58da18..e5e6f504d8cc 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
| @@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out, | |||
| 1518 | if (out->status != MODE_OK) | 1518 | if (out->status != MODE_OK) |
| 1519 | goto out; | 1519 | goto out; |
| 1520 | 1520 | ||
| 1521 | drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V); | ||
| 1522 | |||
| 1521 | ret = 0; | 1523 | ret = 0; |
| 1522 | 1524 | ||
| 1523 | out: | 1525 | out: |
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 0ec1ad961e0d..dc723f7ead7d 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | |||
| @@ -42,9 +42,10 @@ static const struct regmap_config fsl_dcu_regmap_config = { | |||
| 42 | .reg_bits = 32, | 42 | .reg_bits = 32, |
| 43 | .reg_stride = 4, | 43 | .reg_stride = 4, |
| 44 | .val_bits = 32, | 44 | .val_bits = 32, |
| 45 | .cache_type = REGCACHE_RBTREE, | 45 | .cache_type = REGCACHE_FLAT, |
| 46 | 46 | ||
| 47 | .volatile_reg = fsl_dcu_drm_is_volatile_reg, | 47 | .volatile_reg = fsl_dcu_drm_is_volatile_reg, |
| 48 | .max_register = 0x11fc, | ||
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | static int fsl_dcu_drm_irq_init(struct drm_device *dev) | 51 | static int fsl_dcu_drm_irq_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 1f14b602882b..82656654fb21 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c | |||
| @@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) | |||
| 97 | return NULL; | 97 | return NULL; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format, | 100 | int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, |
| 101 | int hsync_pin, int vsync_pin) | 101 | int hsync_pin, int vsync_pin, u32 bus_flags) |
| 102 | { | 102 | { |
| 103 | struct imx_drm_crtc_helper_funcs *helper; | 103 | struct imx_drm_crtc_helper_funcs *helper; |
| 104 | struct imx_drm_crtc *imx_crtc; | 104 | struct imx_drm_crtc *imx_crtc; |
| @@ -110,14 +110,17 @@ int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format, | |||
| 110 | helper = &imx_crtc->imx_drm_helper_funcs; | 110 | helper = &imx_crtc->imx_drm_helper_funcs; |
| 111 | if (helper->set_interface_pix_fmt) | 111 | if (helper->set_interface_pix_fmt) |
| 112 | return helper->set_interface_pix_fmt(encoder->crtc, | 112 | return helper->set_interface_pix_fmt(encoder->crtc, |
| 113 | bus_format, hsync_pin, vsync_pin); | 113 | bus_format, hsync_pin, vsync_pin, |
| 114 | bus_flags); | ||
| 114 | return 0; | 115 | return 0; |
| 115 | } | 116 | } |
| 116 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins); | 117 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_config); |
| 117 | 118 | ||
| 118 | int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) | 119 | int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) |
| 119 | { | 120 | { |
| 120 | return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3); | 121 | return imx_drm_set_bus_config(encoder, bus_format, 2, 3, |
| 122 | DRM_BUS_FLAG_DE_HIGH | | ||
| 123 | DRM_BUS_FLAG_PIXDATA_NEGEDGE); | ||
| 121 | } | 124 | } |
| 122 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); | 125 | EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); |
| 123 | 126 | ||
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h index b0241b9d1334..74320a1723b7 100644 --- a/drivers/gpu/drm/imx/imx-drm.h +++ b/drivers/gpu/drm/imx/imx-drm.h | |||
| @@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs { | |||
| 19 | int (*enable_vblank)(struct drm_crtc *crtc); | 19 | int (*enable_vblank)(struct drm_crtc *crtc); |
| 20 | void (*disable_vblank)(struct drm_crtc *crtc); | 20 | void (*disable_vblank)(struct drm_crtc *crtc); |
| 21 | int (*set_interface_pix_fmt)(struct drm_crtc *crtc, | 21 | int (*set_interface_pix_fmt)(struct drm_crtc *crtc, |
| 22 | u32 bus_format, int hsync_pin, int vsync_pin); | 22 | u32 bus_format, int hsync_pin, int vsync_pin, |
| 23 | u32 bus_flags); | ||
| 23 | const struct drm_crtc_helper_funcs *crtc_helper_funcs; | 24 | const struct drm_crtc_helper_funcs *crtc_helper_funcs; |
| 24 | const struct drm_crtc_funcs *crtc_funcs; | 25 | const struct drm_crtc_funcs *crtc_funcs; |
| 25 | }; | 26 | }; |
| @@ -41,8 +42,8 @@ void imx_drm_mode_config_init(struct drm_device *drm); | |||
| 41 | 42 | ||
| 42 | struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); | 43 | struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); |
| 43 | 44 | ||
| 44 | int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, | 45 | int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format, |
| 45 | u32 bus_format, int hsync_pin, int vsync_pin); | 46 | int hsync_pin, int vsync_pin, u32 bus_flags); |
| 46 | int imx_drm_set_bus_format(struct drm_encoder *encoder, | 47 | int imx_drm_set_bus_format(struct drm_encoder *encoder, |
| 47 | u32 bus_format); | 48 | u32 bus_format); |
| 48 | 49 | ||
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index a58eee59550a..beff793bb717 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | 25 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
| 26 | #include <linux/of_device.h> | 26 | #include <linux/of_device.h> |
| 27 | #include <linux/of_graph.h> | 27 | #include <linux/of_graph.h> |
| 28 | #include <video/of_display_timing.h> | ||
| 28 | #include <video/of_videomode.h> | 29 | #include <video/of_videomode.h> |
| 29 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
| 30 | #include <linux/videodev2.h> | 31 | #include <linux/videodev2.h> |
| @@ -59,6 +60,7 @@ struct imx_ldb_channel { | |||
| 59 | struct drm_encoder encoder; | 60 | struct drm_encoder encoder; |
| 60 | struct drm_panel *panel; | 61 | struct drm_panel *panel; |
| 61 | struct device_node *child; | 62 | struct device_node *child; |
| 63 | struct i2c_adapter *ddc; | ||
| 62 | int chno; | 64 | int chno; |
| 63 | void *edid; | 65 | void *edid; |
| 64 | int edid_len; | 66 | int edid_len; |
| @@ -107,6 +109,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) | |||
| 107 | return num_modes; | 109 | return num_modes; |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 112 | if (!imx_ldb_ch->edid && imx_ldb_ch->ddc) | ||
| 113 | imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc); | ||
| 114 | |||
| 110 | if (imx_ldb_ch->edid) { | 115 | if (imx_ldb_ch->edid) { |
| 111 | drm_mode_connector_update_edid_property(connector, | 116 | drm_mode_connector_update_edid_property(connector, |
| 112 | imx_ldb_ch->edid); | 117 | imx_ldb_ch->edid); |
| @@ -553,7 +558,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 553 | 558 | ||
| 554 | for_each_child_of_node(np, child) { | 559 | for_each_child_of_node(np, child) { |
| 555 | struct imx_ldb_channel *channel; | 560 | struct imx_ldb_channel *channel; |
| 556 | struct device_node *port; | 561 | struct device_node *ddc_node; |
| 562 | struct device_node *ep; | ||
| 557 | 563 | ||
| 558 | ret = of_property_read_u32(child, "reg", &i); | 564 | ret = of_property_read_u32(child, "reg", &i); |
| 559 | if (ret || i < 0 || i > 1) | 565 | if (ret || i < 0 || i > 1) |
| @@ -576,33 +582,54 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 576 | * The output port is port@4 with an external 4-port mux or | 582 | * The output port is port@4 with an external 4-port mux or |
| 577 | * port@2 with the internal 2-port mux. | 583 | * port@2 with the internal 2-port mux. |
| 578 | */ | 584 | */ |
| 579 | port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2); | 585 | ep = of_graph_get_endpoint_by_regs(child, |
| 580 | if (port) { | 586 | imx_ldb->lvds_mux ? 4 : 2, |
| 581 | struct device_node *endpoint, *remote; | 587 | -1); |
| 582 | 588 | if (ep) { | |
| 583 | endpoint = of_get_child_by_name(port, "endpoint"); | 589 | struct device_node *remote; |
| 584 | if (endpoint) { | 590 | |
| 585 | remote = of_graph_get_remote_port_parent(endpoint); | 591 | remote = of_graph_get_remote_port_parent(ep); |
| 586 | if (remote) | 592 | of_node_put(ep); |
| 587 | channel->panel = of_drm_find_panel(remote); | 593 | if (remote) |
| 588 | else | 594 | channel->panel = of_drm_find_panel(remote); |
| 589 | return -EPROBE_DEFER; | 595 | else |
| 590 | if (!channel->panel) { | 596 | return -EPROBE_DEFER; |
| 591 | dev_err(dev, "panel not found: %s\n", | 597 | of_node_put(remote); |
| 592 | remote->full_name); | 598 | if (!channel->panel) { |
| 593 | return -EPROBE_DEFER; | 599 | dev_err(dev, "panel not found: %s\n", |
| 594 | } | 600 | remote->full_name); |
| 601 | return -EPROBE_DEFER; | ||
| 595 | } | 602 | } |
| 596 | } | 603 | } |
| 597 | 604 | ||
| 598 | edidp = of_get_property(child, "edid", &channel->edid_len); | 605 | ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0); |
| 599 | if (edidp) { | 606 | if (ddc_node) { |
| 600 | channel->edid = kmemdup(edidp, channel->edid_len, | 607 | channel->ddc = of_find_i2c_adapter_by_node(ddc_node); |
| 601 | GFP_KERNEL); | 608 | of_node_put(ddc_node); |
| 602 | } else if (!channel->panel) { | 609 | if (!channel->ddc) { |
| 603 | ret = of_get_drm_display_mode(child, &channel->mode, 0); | 610 | dev_warn(dev, "failed to get ddc i2c adapter\n"); |
| 604 | if (!ret) | 611 | return -EPROBE_DEFER; |
| 605 | channel->mode_valid = 1; | 612 | } |
| 613 | } | ||
| 614 | |||
| 615 | if (!channel->ddc) { | ||
| 616 | /* if no DDC available, fallback to hardcoded EDID */ | ||
| 617 | dev_dbg(dev, "no ddc available\n"); | ||
| 618 | |||
| 619 | edidp = of_get_property(child, "edid", | ||
| 620 | &channel->edid_len); | ||
| 621 | if (edidp) { | ||
| 622 | channel->edid = kmemdup(edidp, | ||
| 623 | channel->edid_len, | ||
| 624 | GFP_KERNEL); | ||
| 625 | } else if (!channel->panel) { | ||
| 626 | /* fallback to display-timings node */ | ||
| 627 | ret = of_get_drm_display_mode(child, | ||
| 628 | &channel->mode, | ||
| 629 | OF_USE_NATIVE_MODE); | ||
| 630 | if (!ret) | ||
| 631 | channel->mode_valid = 1; | ||
| 632 | } | ||
| 606 | } | 633 | } |
| 607 | 634 | ||
| 608 | channel->bus_format = of_get_bus_format(dev, child); | 635 | channel->bus_format = of_get_bus_format(dev, child); |
| @@ -647,6 +674,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, | |||
| 647 | channel->encoder.funcs->destroy(&channel->encoder); | 674 | channel->encoder.funcs->destroy(&channel->encoder); |
| 648 | 675 | ||
| 649 | kfree(channel->edid); | 676 | kfree(channel->edid); |
| 677 | i2c_put_adapter(channel->ddc); | ||
| 650 | } | 678 | } |
| 651 | } | 679 | } |
| 652 | 680 | ||
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index ae7a9fb3b8a2..baf788121287 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c | |||
| @@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder) | |||
| 294 | 294 | ||
| 295 | switch (tve->mode) { | 295 | switch (tve->mode) { |
| 296 | case TVE_MODE_VGA: | 296 | case TVE_MODE_VGA: |
| 297 | imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24, | 297 | imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24, |
| 298 | tve->hsync_pin, tve->vsync_pin); | 298 | tve->hsync_pin, tve->vsync_pin, |
| 299 | DRM_BUS_FLAG_DE_HIGH | | ||
| 300 | DRM_BUS_FLAG_PIXDATA_NEGEDGE); | ||
| 299 | break; | 301 | break; |
| 300 | case TVE_MODE_TVOUT: | 302 | case TVE_MODE_TVOUT: |
| 301 | imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); | 303 | imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); |
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index b2c30b8d9816..fc040417e1e8 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c | |||
| @@ -66,6 +66,7 @@ struct ipu_crtc { | |||
| 66 | struct ipu_flip_work *flip_work; | 66 | struct ipu_flip_work *flip_work; |
| 67 | int irq; | 67 | int irq; |
| 68 | u32 bus_format; | 68 | u32 bus_format; |
| 69 | u32 bus_flags; | ||
| 69 | int di_hsync_pin; | 70 | int di_hsync_pin; |
| 70 | int di_vsync_pin; | 71 | int di_vsync_pin; |
| 71 | }; | 72 | }; |
| @@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, | |||
| 271 | else | 272 | else |
| 272 | sig_cfg.clkflags = 0; | 273 | sig_cfg.clkflags = 0; |
| 273 | 274 | ||
| 274 | sig_cfg.enable_pol = 1; | 275 | sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW); |
| 275 | sig_cfg.clk_pol = 0; | 276 | /* Default to driving pixel data on negative clock edges */ |
| 277 | sig_cfg.clk_pol = !!(ipu_crtc->bus_flags & | ||
| 278 | DRM_BUS_FLAG_PIXDATA_POSEDGE); | ||
| 276 | sig_cfg.bus_format = ipu_crtc->bus_format; | 279 | sig_cfg.bus_format = ipu_crtc->bus_format; |
| 277 | sig_cfg.v_to_h_sync = 0; | 280 | sig_cfg.v_to_h_sync = 0; |
| 278 | sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; | 281 | sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; |
| @@ -396,11 +399,12 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) | |||
| 396 | } | 399 | } |
| 397 | 400 | ||
| 398 | static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, | 401 | static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, |
| 399 | u32 bus_format, int hsync_pin, int vsync_pin) | 402 | u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags) |
| 400 | { | 403 | { |
| 401 | struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); | 404 | struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); |
| 402 | 405 | ||
| 403 | ipu_crtc->bus_format = bus_format; | 406 | ipu_crtc->bus_format = bus_format; |
| 407 | ipu_crtc->bus_flags = bus_flags; | ||
| 404 | ipu_crtc->di_hsync_pin = hsync_pin; | 408 | ipu_crtc->di_hsync_pin = hsync_pin; |
| 405 | ipu_crtc->di_vsync_pin = vsync_pin; | 409 | ipu_crtc->di_vsync_pin = vsync_pin; |
| 406 | 410 | ||
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 681ec6eb77d9..a4bb44118d33 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c | |||
| @@ -38,6 +38,8 @@ static const uint32_t ipu_plane_formats[] = { | |||
| 38 | DRM_FORMAT_RGBX8888, | 38 | DRM_FORMAT_RGBX8888, |
| 39 | DRM_FORMAT_BGRA8888, | 39 | DRM_FORMAT_BGRA8888, |
| 40 | DRM_FORMAT_BGRA8888, | 40 | DRM_FORMAT_BGRA8888, |
| 41 | DRM_FORMAT_UYVY, | ||
| 42 | DRM_FORMAT_VYUY, | ||
| 41 | DRM_FORMAT_YUYV, | 43 | DRM_FORMAT_YUYV, |
| 42 | DRM_FORMAT_YVYU, | 44 | DRM_FORMAT_YVYU, |
| 43 | DRM_FORMAT_YUV420, | 45 | DRM_FORMAT_YUV420, |
| @@ -428,7 +430,6 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 428 | if (crtc != plane->crtc) | 430 | if (crtc != plane->crtc) |
| 429 | dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n", | 431 | dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n", |
| 430 | plane->crtc, crtc); | 432 | plane->crtc, crtc); |
| 431 | plane->crtc = crtc; | ||
| 432 | 433 | ||
| 433 | if (!ipu_plane->enabled) | 434 | if (!ipu_plane->enabled) |
| 434 | ipu_plane_enable(ipu_plane); | 435 | ipu_plane_enable(ipu_plane); |
| @@ -461,7 +462,7 @@ static void ipu_plane_destroy(struct drm_plane *plane) | |||
| 461 | kfree(ipu_plane); | 462 | kfree(ipu_plane); |
| 462 | } | 463 | } |
| 463 | 464 | ||
| 464 | static struct drm_plane_funcs ipu_plane_funcs = { | 465 | static const struct drm_plane_funcs ipu_plane_funcs = { |
| 465 | .update_plane = ipu_update_plane, | 466 | .update_plane = ipu_update_plane, |
| 466 | .disable_plane = ipu_disable_plane, | 467 | .disable_plane = ipu_disable_plane, |
| 467 | .destroy = ipu_plane_destroy, | 468 | .destroy = ipu_plane_destroy, |
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 363e2c7741e2..2d1fd02cd3d6 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c | |||
| @@ -35,7 +35,6 @@ struct imx_parallel_display { | |||
| 35 | void *edid; | 35 | void *edid; |
| 36 | int edid_len; | 36 | int edid_len; |
| 37 | u32 bus_format; | 37 | u32 bus_format; |
| 38 | int mode_valid; | ||
| 39 | struct drm_display_mode mode; | 38 | struct drm_display_mode mode; |
| 40 | struct drm_panel *panel; | 39 | struct drm_panel *panel; |
| 41 | }; | 40 | }; |
| @@ -68,17 +67,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) | |||
| 68 | num_modes = drm_add_edid_modes(connector, imxpd->edid); | 67 | num_modes = drm_add_edid_modes(connector, imxpd->edid); |
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | if (imxpd->mode_valid) { | ||
| 72 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | ||
| 73 | |||
| 74 | if (!mode) | ||
| 75 | return -EINVAL; | ||
| 76 | drm_mode_copy(mode, &imxpd->mode); | ||
| 77 | mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, | ||
| 78 | drm_mode_probed_add(connector, mode); | ||
| 79 | num_modes++; | ||
| 80 | } | ||
| 81 | |||
| 82 | if (np) { | 70 | if (np) { |
| 83 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | 71 | struct drm_display_mode *mode = drm_mode_create(connector->dev); |
| 84 | 72 | ||
| @@ -115,8 +103,8 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 115 | static void imx_pd_encoder_prepare(struct drm_encoder *encoder) | 103 | static void imx_pd_encoder_prepare(struct drm_encoder *encoder) |
| 116 | { | 104 | { |
| 117 | struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); | 105 | struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); |
| 118 | 106 | imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3, | |
| 119 | imx_drm_set_bus_format(encoder, imxpd->bus_format); | 107 | imxpd->connector.display_info.bus_flags); |
| 120 | } | 108 | } |
| 121 | 109 | ||
| 122 | static void imx_pd_encoder_commit(struct drm_encoder *encoder) | 110 | static void imx_pd_encoder_commit(struct drm_encoder *encoder) |
| @@ -203,7 +191,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) | |||
| 203 | { | 191 | { |
| 204 | struct drm_device *drm = data; | 192 | struct drm_device *drm = data; |
| 205 | struct device_node *np = dev->of_node; | 193 | struct device_node *np = dev->of_node; |
| 206 | struct device_node *port; | 194 | struct device_node *ep; |
| 207 | const u8 *edidp; | 195 | const u8 *edidp; |
| 208 | struct imx_parallel_display *imxpd; | 196 | struct imx_parallel_display *imxpd; |
| 209 | int ret; | 197 | int ret; |
| @@ -230,18 +218,18 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) | |||
| 230 | } | 218 | } |
| 231 | 219 | ||
| 232 | /* port@1 is the output port */ | 220 | /* port@1 is the output port */ |
| 233 | port = of_graph_get_port_by_id(np, 1); | 221 | ep = of_graph_get_endpoint_by_regs(np, 1, -1); |
| 234 | if (port) { | 222 | if (ep) { |
| 235 | struct device_node *endpoint, *remote; | 223 | struct device_node *remote; |
| 236 | 224 | ||
| 237 | endpoint = of_get_child_by_name(port, "endpoint"); | 225 | remote = of_graph_get_remote_port_parent(ep); |
| 238 | if (endpoint) { | 226 | of_node_put(ep); |
| 239 | remote = of_graph_get_remote_port_parent(endpoint); | 227 | if (remote) { |
| 240 | if (remote) | 228 | imxpd->panel = of_drm_find_panel(remote); |
| 241 | imxpd->panel = of_drm_find_panel(remote); | 229 | of_node_put(remote); |
| 242 | if (!imxpd->panel) | ||
| 243 | return -EPROBE_DEFER; | ||
| 244 | } | 230 | } |
| 231 | if (!imxpd->panel) | ||
| 232 | return -EPROBE_DEFER; | ||
| 245 | } | 233 | } |
| 246 | 234 | ||
| 247 | imxpd->dev = dev; | 235 | imxpd->dev = dev; |
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index d05ca7901315..0186e500d2a5 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c | |||
| @@ -432,11 +432,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, | |||
| 432 | unsigned long pll_rate; | 432 | unsigned long pll_rate; |
| 433 | unsigned int factor; | 433 | unsigned int factor; |
| 434 | 434 | ||
| 435 | if (!dpi) { | ||
| 436 | dev_err(dpi->dev, "invalid argument\n"); | ||
| 437 | return -EINVAL; | ||
| 438 | } | ||
| 439 | |||
| 440 | pix_rate = 1000UL * mode->clock; | 435 | pix_rate = 1000UL * mode->clock; |
| 441 | if (mode->clock <= 74000) | 436 | if (mode->clock <= 74000) |
| 442 | factor = 8 * 3; | 437 | factor = 8 * 3; |
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 2d808e59fefd..769559124562 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c | |||
| @@ -695,10 +695,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi) | |||
| 695 | { | 695 | { |
| 696 | drm_encoder_cleanup(&dsi->encoder); | 696 | drm_encoder_cleanup(&dsi->encoder); |
| 697 | /* Skip connector cleanup if creation was delegated to the bridge */ | 697 | /* Skip connector cleanup if creation was delegated to the bridge */ |
| 698 | if (dsi->conn.dev) { | 698 | if (dsi->conn.dev) |
| 699 | drm_connector_unregister(&dsi->conn); | ||
| 700 | drm_connector_cleanup(&dsi->conn); | 699 | drm_connector_cleanup(&dsi->conn); |
| 701 | } | ||
| 702 | } | 700 | } |
| 703 | 701 | ||
| 704 | static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp) | 702 | static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp) |
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 14e64e08909e..d347dca17267 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
| @@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) | |||
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | fvv = pllreffreq * testn / testm; | 185 | fvv = pllreffreq * (n + 1) / (m + 1); |
| 186 | fvv = (fvv - 800000) / 50000; | 186 | fvv = (fvv - 800000) / 50000; |
| 187 | 187 | ||
| 188 | if (fvv > 15) | 188 | if (fvv > 15) |
| @@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) | |||
| 202 | WREG_DAC(MGA1064_PIX_PLLC_M, m); | 202 | WREG_DAC(MGA1064_PIX_PLLC_M, m); |
| 203 | WREG_DAC(MGA1064_PIX_PLLC_N, n); | 203 | WREG_DAC(MGA1064_PIX_PLLC_N, n); |
| 204 | WREG_DAC(MGA1064_PIX_PLLC_P, p); | 204 | WREG_DAC(MGA1064_PIX_PLLC_P, p); |
| 205 | |||
| 206 | if (mdev->unique_rev_id >= 0x04) { | ||
| 207 | WREG_DAC(0x1a, 0x09); | ||
| 208 | msleep(20); | ||
| 209 | WREG_DAC(0x1a, 0x01); | ||
| 210 | |||
| 211 | } | ||
| 212 | |||
| 205 | return 0; | 213 | return 0; |
| 206 | } | 214 | } |
| 207 | 215 | ||
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index fbe304ee6c80..2aec27dbb5bb 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c | |||
| @@ -408,7 +408,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, | |||
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | adreno_gpu->memptrs = msm_gem_vaddr(adreno_gpu->memptrs_bo); | 410 | adreno_gpu->memptrs = msm_gem_vaddr(adreno_gpu->memptrs_bo); |
| 411 | if (!adreno_gpu->memptrs) { | 411 | if (IS_ERR(adreno_gpu->memptrs)) { |
| 412 | dev_err(drm->dev, "could not vmap memptrs\n"); | 412 | dev_err(drm->dev, "could not vmap memptrs\n"); |
| 413 | return -ENOMEM; | 413 | return -ENOMEM; |
| 414 | } | 414 | } |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index d9759bf3482e..c6cf837c5193 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
| @@ -159,6 +159,10 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, | |||
| 159 | dev->mode_config.fb_base = paddr; | 159 | dev->mode_config.fb_base = paddr; |
| 160 | 160 | ||
| 161 | fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo); | 161 | fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo); |
| 162 | if (IS_ERR(fbi->screen_base)) { | ||
| 163 | ret = PTR_ERR(fbi->screen_base); | ||
| 164 | goto fail_unlock; | ||
| 165 | } | ||
| 162 | fbi->screen_size = fbdev->bo->size; | 166 | fbi->screen_size = fbdev->bo->size; |
| 163 | fbi->fix.smem_start = paddr; | 167 | fbi->fix.smem_start = paddr; |
| 164 | fbi->fix.smem_len = fbdev->bo->size; | 168 | fbi->fix.smem_len = fbdev->bo->size; |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 7daf4054dd2b..69836f5685b1 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
| @@ -398,6 +398,8 @@ void *msm_gem_vaddr_locked(struct drm_gem_object *obj) | |||
| 398 | return ERR_CAST(pages); | 398 | return ERR_CAST(pages); |
| 399 | msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, | 399 | msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, |
| 400 | VM_MAP, pgprot_writecombine(PAGE_KERNEL)); | 400 | VM_MAP, pgprot_writecombine(PAGE_KERNEL)); |
| 401 | if (msm_obj->vaddr == NULL) | ||
| 402 | return ERR_PTR(-ENOMEM); | ||
| 401 | } | 403 | } |
| 402 | return msm_obj->vaddr; | 404 | return msm_obj->vaddr; |
| 403 | } | 405 | } |
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index b89ca5174863..eb4bb8b2f3a5 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
| @@ -40,12 +40,14 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, | |||
| 40 | 40 | ||
| 41 | submit->dev = dev; | 41 | submit->dev = dev; |
| 42 | submit->gpu = gpu; | 42 | submit->gpu = gpu; |
| 43 | submit->fence = NULL; | ||
| 43 | submit->pid = get_pid(task_pid(current)); | 44 | submit->pid = get_pid(task_pid(current)); |
| 44 | 45 | ||
| 45 | /* initially, until copy_from_user() and bo lookup succeeds: */ | 46 | /* initially, until copy_from_user() and bo lookup succeeds: */ |
| 46 | submit->nr_bos = 0; | 47 | submit->nr_bos = 0; |
| 47 | submit->nr_cmds = 0; | 48 | submit->nr_cmds = 0; |
| 48 | 49 | ||
| 50 | INIT_LIST_HEAD(&submit->node); | ||
| 49 | INIT_LIST_HEAD(&submit->bo_list); | 51 | INIT_LIST_HEAD(&submit->bo_list); |
| 50 | ww_acquire_init(&submit->ticket, &reservation_ww_class); | 52 | ww_acquire_init(&submit->ticket, &reservation_ww_class); |
| 51 | 53 | ||
| @@ -75,6 +77,11 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, | |||
| 75 | void __user *userptr = | 77 | void __user *userptr = |
| 76 | u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); | 78 | u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); |
| 77 | 79 | ||
| 80 | /* make sure we don't have garbage flags, in case we hit | ||
| 81 | * error path before flags is initialized: | ||
| 82 | */ | ||
| 83 | submit->bos[i].flags = 0; | ||
| 84 | |||
| 78 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); | 85 | ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); |
| 79 | if (ret) { | 86 | if (ret) { |
| 80 | ret = -EFAULT; | 87 | ret = -EFAULT; |
diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index b48f73ac6389..0857710c2ff2 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c | |||
| @@ -312,6 +312,9 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) | |||
| 312 | struct msm_gem_object *obj = submit->bos[idx].obj; | 312 | struct msm_gem_object *obj = submit->bos[idx].obj; |
| 313 | const char *buf = msm_gem_vaddr_locked(&obj->base); | 313 | const char *buf = msm_gem_vaddr_locked(&obj->base); |
| 314 | 314 | ||
| 315 | if (IS_ERR(buf)) | ||
| 316 | continue; | ||
| 317 | |||
| 315 | buf += iova - submit->bos[idx].iova; | 318 | buf += iova - submit->bos[idx].iova; |
| 316 | 319 | ||
| 317 | rd_write_section(rd, RD_GPUADDR, | 320 | rd_write_section(rd, RD_GPUADDR, |
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 1f14b908b221..42f5359cf988 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c | |||
| @@ -40,6 +40,10 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) | |||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | ring->start = msm_gem_vaddr_locked(ring->bo); | 42 | ring->start = msm_gem_vaddr_locked(ring->bo); |
| 43 | if (IS_ERR(ring->start)) { | ||
| 44 | ret = PTR_ERR(ring->start); | ||
| 45 | goto fail; | ||
| 46 | } | ||
| 43 | ring->end = ring->start + (size / 4); | 47 | ring->end = ring->start + (size / 4); |
| 44 | ring->cur = ring->start; | 48 | ring->cur = ring->start; |
| 45 | 49 | ||
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h index c612dc1f1eb4..126a85cc81bc 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h | |||
| @@ -16,9 +16,9 @@ enum nvkm_devidx { | |||
| 16 | NVKM_SUBDEV_MC, | 16 | NVKM_SUBDEV_MC, |
| 17 | NVKM_SUBDEV_BUS, | 17 | NVKM_SUBDEV_BUS, |
| 18 | NVKM_SUBDEV_TIMER, | 18 | NVKM_SUBDEV_TIMER, |
| 19 | NVKM_SUBDEV_INSTMEM, | ||
| 19 | NVKM_SUBDEV_FB, | 20 | NVKM_SUBDEV_FB, |
| 20 | NVKM_SUBDEV_LTC, | 21 | NVKM_SUBDEV_LTC, |
| 21 | NVKM_SUBDEV_INSTMEM, | ||
| 22 | NVKM_SUBDEV_MMU, | 22 | NVKM_SUBDEV_MMU, |
| 23 | NVKM_SUBDEV_BAR, | 23 | NVKM_SUBDEV_BAR, |
| 24 | NVKM_SUBDEV_PMU, | 24 | NVKM_SUBDEV_PMU, |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h index db10c11f0595..c5a6ebd5a478 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h | |||
| @@ -25,7 +25,8 @@ u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask, | |||
| 25 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *); | 25 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *); |
| 26 | 26 | ||
| 27 | struct nvbios_ocfg { | 27 | struct nvbios_ocfg { |
| 28 | u16 match; | 28 | u8 proto; |
| 29 | u8 flags; | ||
| 29 | u16 clkcmp[2]; | 30 | u16 clkcmp[2]; |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| @@ -33,7 +34,7 @@ u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx, | |||
| 33 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len); | 34 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len); |
| 34 | u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx, | 35 | u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx, |
| 35 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); | 36 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
| 36 | u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type, | 37 | u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u8 proto, u8 flags, |
| 37 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); | 38 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
| 38 | u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz); | 39 | u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz); |
| 39 | #endif | 40 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 57aaf98a26f9..300ea03be8f0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
| @@ -552,6 +552,7 @@ nouveau_fbcon_init(struct drm_device *dev) | |||
| 552 | if (ret) | 552 | if (ret) |
| 553 | goto fini; | 553 | goto fini; |
| 554 | 554 | ||
| 555 | fbcon->helper.fbdev->pixmap.buf_align = 4; | ||
| 555 | return 0; | 556 | return 0; |
| 556 | 557 | ||
| 557 | fini: | 558 | fini: |
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 0f3e4bb411cc..7d9248b8c664 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c | |||
| @@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 82 | uint32_t fg; | 82 | uint32_t fg; |
| 83 | uint32_t bg; | 83 | uint32_t bg; |
| 84 | uint32_t dsize; | 84 | uint32_t dsize; |
| 85 | uint32_t width; | ||
| 86 | uint32_t *data = (uint32_t *)image->data; | 85 | uint32_t *data = (uint32_t *)image->data; |
| 87 | int ret; | 86 | int ret; |
| 88 | 87 | ||
| @@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 93 | if (ret) | 92 | if (ret) |
| 94 | return ret; | 93 | return ret; |
| 95 | 94 | ||
| 96 | width = ALIGN(image->width, 8); | ||
| 97 | dsize = ALIGN(width * image->height, 32) >> 5; | ||
| 98 | |||
| 99 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 95 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 100 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 96 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| 101 | fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; | 97 | fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; |
| @@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 111 | ((image->dx + image->width) & 0xffff)); | 107 | ((image->dx + image->width) & 0xffff)); |
| 112 | OUT_RING(chan, bg); | 108 | OUT_RING(chan, bg); |
| 113 | OUT_RING(chan, fg); | 109 | OUT_RING(chan, fg); |
| 114 | OUT_RING(chan, (image->height << 16) | width); | 110 | OUT_RING(chan, (image->height << 16) | image->width); |
| 115 | OUT_RING(chan, (image->height << 16) | image->width); | 111 | OUT_RING(chan, (image->height << 16) | image->width); |
| 116 | OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); | 112 | OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); |
| 117 | 113 | ||
| 114 | dsize = ALIGN(image->width * image->height, 32) >> 5; | ||
| 118 | while (dsize) { | 115 | while (dsize) { |
| 119 | int iter_len = dsize > 128 ? 128 : dsize; | 116 | int iter_len = dsize > 128 ? 128 : dsize; |
| 120 | 117 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 33d9ee0fac40..1aeb698e9707 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
| @@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 95 | struct nouveau_fbdev *nfbdev = info->par; | 95 | struct nouveau_fbdev *nfbdev = info->par; |
| 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| 97 | struct nouveau_channel *chan = drm->channel; | 97 | struct nouveau_channel *chan = drm->channel; |
| 98 | uint32_t width, dwords, *data = (uint32_t *)image->data; | 98 | uint32_t dwords, *data = (uint32_t *)image->data; |
| 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| 100 | uint32_t *palette = info->pseudo_palette; | 100 | uint32_t *palette = info->pseudo_palette; |
| 101 | int ret; | 101 | int ret; |
| @@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 107 | if (ret) | 107 | if (ret) |
| 108 | return ret; | 108 | return ret; |
| 109 | 109 | ||
| 110 | width = ALIGN(image->width, 32); | ||
| 111 | dwords = (width * image->height) >> 5; | ||
| 112 | |||
| 113 | BEGIN_NV04(chan, NvSub2D, 0x0814, 2); | 110 | BEGIN_NV04(chan, NvSub2D, 0x0814, 2); |
| 114 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 115 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 128 | OUT_RING(chan, 0); | 125 | OUT_RING(chan, 0); |
| 129 | OUT_RING(chan, image->dy); | 126 | OUT_RING(chan, image->dy); |
| 130 | 127 | ||
| 128 | dwords = ALIGN(image->width * image->height, 32) >> 5; | ||
| 131 | while (dwords) { | 129 | while (dwords) { |
| 132 | int push = dwords > 2047 ? 2047 : dwords; | 130 | int push = dwords > 2047 ? 2047 : dwords; |
| 133 | 131 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index a0913359ac05..839f4c8c1805 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c | |||
| @@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 95 | struct nouveau_fbdev *nfbdev = info->par; | 95 | struct nouveau_fbdev *nfbdev = info->par; |
| 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); | 96 | struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); |
| 97 | struct nouveau_channel *chan = drm->channel; | 97 | struct nouveau_channel *chan = drm->channel; |
| 98 | uint32_t width, dwords, *data = (uint32_t *)image->data; | 98 | uint32_t dwords, *data = (uint32_t *)image->data; |
| 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); | 99 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
| 100 | uint32_t *palette = info->pseudo_palette; | 100 | uint32_t *palette = info->pseudo_palette; |
| 101 | int ret; | 101 | int ret; |
| @@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 107 | if (ret) | 107 | if (ret) |
| 108 | return ret; | 108 | return ret; |
| 109 | 109 | ||
| 110 | width = ALIGN(image->width, 32); | ||
| 111 | dwords = (width * image->height) >> 5; | ||
| 112 | |||
| 113 | BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); | 110 | BEGIN_NVC0(chan, NvSub2D, 0x0814, 2); |
| 114 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 111 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
| 115 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 112 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
| @@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 128 | OUT_RING (chan, 0); | 125 | OUT_RING (chan, 0); |
| 129 | OUT_RING (chan, image->dy); | 126 | OUT_RING (chan, image->dy); |
| 130 | 127 | ||
| 128 | dwords = ALIGN(image->width * image->height, 32) >> 5; | ||
| 131 | while (dwords) { | 129 | while (dwords) { |
| 132 | int push = dwords > 2047 ? 2047 : dwords; | 130 | int push = dwords > 2047 ? 2047 : dwords; |
| 133 | 131 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild index a74c5dd27dc0..e2a64ed14b22 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild | |||
| @@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/disp/piornv50.o | |||
| 18 | nvkm-y += nvkm/engine/disp/sornv50.o | 18 | nvkm-y += nvkm/engine/disp/sornv50.o |
| 19 | nvkm-y += nvkm/engine/disp/sorg94.o | 19 | nvkm-y += nvkm/engine/disp/sorg94.o |
| 20 | nvkm-y += nvkm/engine/disp/sorgf119.o | 20 | nvkm-y += nvkm/engine/disp/sorgf119.o |
| 21 | nvkm-y += nvkm/engine/disp/sorgm107.o | ||
| 21 | nvkm-y += nvkm/engine/disp/sorgm200.o | 22 | nvkm-y += nvkm/engine/disp/sorgm200.o |
| 22 | nvkm-y += nvkm/engine/disp/dport.o | 23 | nvkm-y += nvkm/engine/disp/dport.o |
| 23 | 24 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index f0314664349c..5dd34382f55a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | |||
| @@ -76,6 +76,7 @@ exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl, | |||
| 76 | mask |= 0x0001 << or; | 76 | mask |= 0x0001 << or; |
| 77 | mask |= 0x0100 << head; | 77 | mask |= 0x0100 << head; |
| 78 | 78 | ||
| 79 | |||
| 79 | list_for_each_entry(outp, &disp->base.outp, head) { | 80 | list_for_each_entry(outp, &disp->base.outp, head) { |
| 80 | if ((outp->info.hasht & 0xff) == type && | 81 | if ((outp->info.hasht & 0xff) == type && |
| 81 | (outp->info.hashm & mask) == mask) { | 82 | (outp->info.hashm & mask) == mask) { |
| @@ -155,25 +156,21 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
| 155 | if (!outp) | 156 | if (!outp) |
| 156 | return NULL; | 157 | return NULL; |
| 157 | 158 | ||
| 159 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 158 | switch (outp->info.type) { | 160 | switch (outp->info.type) { |
| 159 | case DCB_OUTPUT_TMDS: | 161 | case DCB_OUTPUT_TMDS: |
| 160 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 161 | if (*conf == 5) | 162 | if (*conf == 5) |
| 162 | *conf |= 0x0100; | 163 | *conf |= 0x0100; |
| 163 | break; | 164 | break; |
| 164 | case DCB_OUTPUT_LVDS: | 165 | case DCB_OUTPUT_LVDS: |
| 165 | *conf = disp->sor.lvdsconf; | 166 | *conf |= disp->sor.lvdsconf; |
| 166 | break; | ||
| 167 | case DCB_OUTPUT_DP: | ||
| 168 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 169 | break; | 167 | break; |
| 170 | case DCB_OUTPUT_ANALOG: | ||
| 171 | default: | 168 | default: |
| 172 | *conf = 0x00ff; | ||
| 173 | break; | 169 | break; |
| 174 | } | 170 | } |
| 175 | 171 | ||
| 176 | data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | 172 | data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, |
| 173 | &ver, &hdr, &cnt, &len, &info2); | ||
| 177 | if (data && id < 0xff) { | 174 | if (data && id < 0xff) { |
| 178 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); | 175 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
| 179 | if (data) { | 176 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c index b6944142d616..f4b9cf8574be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c | |||
| @@ -36,7 +36,7 @@ gm107_disp = { | |||
| 36 | .outp.internal.crt = nv50_dac_output_new, | 36 | .outp.internal.crt = nv50_dac_output_new, |
| 37 | .outp.internal.tmds = nv50_sor_output_new, | 37 | .outp.internal.tmds = nv50_sor_output_new, |
| 38 | .outp.internal.lvds = nv50_sor_output_new, | 38 | .outp.internal.lvds = nv50_sor_output_new, |
| 39 | .outp.internal.dp = gf119_sor_dp_new, | 39 | .outp.internal.dp = gm107_sor_dp_new, |
| 40 | .dac.nr = 3, | 40 | .dac.nr = 3, |
| 41 | .dac.power = nv50_dac_power, | 41 | .dac.power = nv50_dac_power, |
| 42 | .dac.sense = nv50_dac_sense, | 42 | .dac.sense = nv50_dac_sense, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 4226d2153b9c..fcb1b0c46d64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | |||
| @@ -387,22 +387,17 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
| 387 | if (!outp) | 387 | if (!outp) |
| 388 | return NULL; | 388 | return NULL; |
| 389 | 389 | ||
| 390 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 390 | if (outp->info.location == 0) { | 391 | if (outp->info.location == 0) { |
| 391 | switch (outp->info.type) { | 392 | switch (outp->info.type) { |
| 392 | case DCB_OUTPUT_TMDS: | 393 | case DCB_OUTPUT_TMDS: |
| 393 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 394 | if (*conf == 5) | 394 | if (*conf == 5) |
| 395 | *conf |= 0x0100; | 395 | *conf |= 0x0100; |
| 396 | break; | 396 | break; |
| 397 | case DCB_OUTPUT_LVDS: | 397 | case DCB_OUTPUT_LVDS: |
| 398 | *conf = disp->sor.lvdsconf; | 398 | *conf |= disp->sor.lvdsconf; |
| 399 | break; | 399 | break; |
| 400 | case DCB_OUTPUT_DP: | ||
| 401 | *conf = (ctrl & 0x00000f00) >> 8; | ||
| 402 | break; | ||
| 403 | case DCB_OUTPUT_ANALOG: | ||
| 404 | default: | 400 | default: |
| 405 | *conf = 0x00ff; | ||
| 406 | break; | 401 | break; |
| 407 | } | 402 | } |
| 408 | } else { | 403 | } else { |
| @@ -410,7 +405,8 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
| 410 | pclk = pclk / 2; | 405 | pclk = pclk / 2; |
| 411 | } | 406 | } |
| 412 | 407 | ||
| 413 | data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | 408 | data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, |
| 409 | &ver, &hdr, &cnt, &len, &info2); | ||
| 414 | if (data && id < 0xff) { | 410 | if (data && id < 0xff) { |
| 415 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); | 411 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
| 416 | if (data) { | 412 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h index e9067ba4e179..4e983f6d7032 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h | |||
| @@ -62,7 +62,12 @@ int g94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int); | |||
| 62 | int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | 62 | int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, |
| 63 | struct nvkm_output **); | 63 | struct nvkm_output **); |
| 64 | int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool); | 64 | int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool); |
| 65 | int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int); | ||
| 65 | 66 | ||
| 66 | int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | 67 | int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, |
| 67 | struct nvkm_output **); | 68 | struct nvkm_output **); |
| 69 | int gm107_sor_dp_pattern(struct nvkm_output_dp *, int); | ||
| 70 | |||
| 71 | int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, | ||
| 72 | struct nvkm_output **); | ||
| 68 | #endif | 73 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c index b4b41b135643..22706c0a54b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c | |||
| @@ -40,8 +40,7 @@ static int | |||
| 40 | gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | 40 | gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) |
| 41 | { | 41 | { |
| 42 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | 42 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; |
| 43 | const u32 loff = gf119_sor_loff(outp); | 43 | nvkm_mask(device, 0x61c110, 0x0f0f0f0f, 0x01010101 * pattern); |
| 44 | nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern); | ||
| 45 | return 0; | 44 | return 0; |
| 46 | } | 45 | } |
| 47 | 46 | ||
| @@ -64,7 +63,7 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) | |||
| 64 | return 0; | 63 | return 0; |
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | static int | 66 | int |
| 68 | gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp, | 67 | gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp, |
| 69 | int ln, int vs, int pe, int pc) | 68 | int ln, int vs, int pe, int pc) |
| 70 | { | 69 | { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c new file mode 100644 index 000000000000..37790b2617c5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2016 Red Hat Inc. | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * | ||
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 21 | * | ||
| 22 | * Authors: Ben Skeggs <bskeggs@redhat.com> | ||
| 23 | */ | ||
| 24 | #include "nv50.h" | ||
| 25 | #include "outpdp.h" | ||
| 26 | |||
| 27 | int | ||
| 28 | gm107_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | ||
| 29 | { | ||
| 30 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | ||
| 31 | const u32 soff = outp->base.or * 0x800; | ||
| 32 | const u32 data = 0x01010101 * pattern; | ||
| 33 | if (outp->base.info.sorconf.link & 1) | ||
| 34 | nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data); | ||
| 35 | else | ||
| 36 | nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data); | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | static const struct nvkm_output_dp_func | ||
| 41 | gm107_sor_dp_func = { | ||
| 42 | .pattern = gm107_sor_dp_pattern, | ||
| 43 | .lnk_pwr = g94_sor_dp_lnk_pwr, | ||
| 44 | .lnk_ctl = gf119_sor_dp_lnk_ctl, | ||
| 45 | .drv_ctl = gf119_sor_dp_drv_ctl, | ||
| 46 | }; | ||
| 47 | |||
| 48 | int | ||
| 49 | gm107_sor_dp_new(struct nvkm_disp *disp, int index, | ||
| 50 | struct dcb_output *dcbE, struct nvkm_output **poutp) | ||
| 51 | { | ||
| 52 | return nvkm_output_dp_new_(&gm107_sor_dp_func, disp, index, dcbE, poutp); | ||
| 53 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c index 2cfbef9c344f..c44fa7ea672a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c | |||
| @@ -57,19 +57,6 @@ gm200_sor_dp_lane_map(struct nvkm_device *device, u8 lane) | |||
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static int | 59 | static int |
| 60 | gm200_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) | ||
| 61 | { | ||
| 62 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | ||
| 63 | const u32 soff = gm200_sor_soff(outp); | ||
| 64 | const u32 data = 0x01010101 * pattern; | ||
| 65 | if (outp->base.info.sorconf.link & 1) | ||
| 66 | nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data); | ||
| 67 | else | ||
| 68 | nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data); | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static int | ||
| 73 | gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) | 60 | gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) |
| 74 | { | 61 | { |
| 75 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; | 62 | struct nvkm_device *device = outp->base.disp->engine.subdev.device; |
| @@ -129,7 +116,7 @@ gm200_sor_dp_drv_ctl(struct nvkm_output_dp *outp, | |||
| 129 | 116 | ||
| 130 | static const struct nvkm_output_dp_func | 117 | static const struct nvkm_output_dp_func |
| 131 | gm200_sor_dp_func = { | 118 | gm200_sor_dp_func = { |
| 132 | .pattern = gm200_sor_dp_pattern, | 119 | .pattern = gm107_sor_dp_pattern, |
| 133 | .lnk_pwr = gm200_sor_dp_lnk_pwr, | 120 | .lnk_pwr = gm200_sor_dp_lnk_pwr, |
| 134 | .lnk_ctl = gf119_sor_dp_lnk_ctl, | 121 | .lnk_ctl = gf119_sor_dp_lnk_ctl, |
| 135 | .drv_ctl = gm200_sor_dp_drv_ctl, | 122 | .drv_ctl = gm200_sor_dp_drv_ctl, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 9513badb8220..ae9ab5b1ab97 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | |||
| @@ -949,22 +949,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *gr, int gpc) | |||
| 949 | } | 949 | } |
| 950 | 950 | ||
| 951 | static const struct nvkm_enum gf100_mp_warp_error[] = { | 951 | static const struct nvkm_enum gf100_mp_warp_error[] = { |
| 952 | { 0x00, "NO_ERROR" }, | 952 | { 0x01, "STACK_ERROR" }, |
| 953 | { 0x01, "STACK_MISMATCH" }, | 953 | { 0x02, "API_STACK_ERROR" }, |
| 954 | { 0x03, "RET_EMPTY_STACK_ERROR" }, | ||
| 955 | { 0x04, "PC_WRAP" }, | ||
| 954 | { 0x05, "MISALIGNED_PC" }, | 956 | { 0x05, "MISALIGNED_PC" }, |
| 955 | { 0x08, "MISALIGNED_GPR" }, | 957 | { 0x06, "PC_OVERFLOW" }, |
| 956 | { 0x09, "INVALID_OPCODE" }, | 958 | { 0x07, "MISALIGNED_IMMC_ADDR" }, |
| 957 | { 0x0d, "GPR_OUT_OF_BOUNDS" }, | 959 | { 0x08, "MISALIGNED_REG" }, |
| 958 | { 0x0e, "MEM_OUT_OF_BOUNDS" }, | 960 | { 0x09, "ILLEGAL_INSTR_ENCODING" }, |
| 959 | { 0x0f, "UNALIGNED_MEM_ACCESS" }, | 961 | { 0x0a, "ILLEGAL_SPH_INSTR_COMBO" }, |
| 962 | { 0x0b, "ILLEGAL_INSTR_PARAM" }, | ||
| 963 | { 0x0c, "INVALID_CONST_ADDR" }, | ||
| 964 | { 0x0d, "OOR_REG" }, | ||
| 965 | { 0x0e, "OOR_ADDR" }, | ||
| 966 | { 0x0f, "MISALIGNED_ADDR" }, | ||
| 960 | { 0x10, "INVALID_ADDR_SPACE" }, | 967 | { 0x10, "INVALID_ADDR_SPACE" }, |
| 961 | { 0x11, "INVALID_PARAM" }, | 968 | { 0x11, "ILLEGAL_INSTR_PARAM2" }, |
| 969 | { 0x12, "INVALID_CONST_ADDR_LDC" }, | ||
| 970 | { 0x13, "GEOMETRY_SM_ERROR" }, | ||
| 971 | { 0x14, "DIVERGENT" }, | ||
| 972 | { 0x15, "WARP_EXIT" }, | ||
| 962 | {} | 973 | {} |
| 963 | }; | 974 | }; |
| 964 | 975 | ||
| 965 | static const struct nvkm_bitfield gf100_mp_global_error[] = { | 976 | static const struct nvkm_bitfield gf100_mp_global_error[] = { |
| 977 | { 0x00000001, "SM_TO_SM_FAULT" }, | ||
| 978 | { 0x00000002, "L1_ERROR" }, | ||
| 966 | { 0x00000004, "MULTIPLE_WARP_ERRORS" }, | 979 | { 0x00000004, "MULTIPLE_WARP_ERRORS" }, |
| 967 | { 0x00000008, "OUT_OF_STACK_SPACE" }, | 980 | { 0x00000008, "PHYSICAL_STACK_OVERFLOW" }, |
| 981 | { 0x00000010, "BPT_INT" }, | ||
| 982 | { 0x00000020, "BPT_PAUSE" }, | ||
| 983 | { 0x00000040, "SINGLE_STEP_COMPLETE" }, | ||
| 984 | { 0x20000000, "ECC_SEC_ERROR" }, | ||
| 985 | { 0x40000000, "ECC_DED_ERROR" }, | ||
| 986 | { 0x80000000, "TIMEOUT" }, | ||
| 968 | {} | 987 | {} |
| 969 | }; | 988 | }; |
| 970 | 989 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c index a5e92135cd77..9efb1b48cd54 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c | |||
| @@ -141,7 +141,8 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
| 141 | { | 141 | { |
| 142 | u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len); | 142 | u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len); |
| 143 | if (data) { | 143 | if (data) { |
| 144 | info->match = nvbios_rd16(bios, data + 0x00); | 144 | info->proto = nvbios_rd08(bios, data + 0x00); |
| 145 | info->flags = nvbios_rd16(bios, data + 0x01); | ||
| 145 | info->clkcmp[0] = nvbios_rd16(bios, data + 0x02); | 146 | info->clkcmp[0] = nvbios_rd16(bios, data + 0x02); |
| 146 | info->clkcmp[1] = nvbios_rd16(bios, data + 0x04); | 147 | info->clkcmp[1] = nvbios_rd16(bios, data + 0x04); |
| 147 | } | 148 | } |
| @@ -149,12 +150,13 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | u16 | 152 | u16 |
| 152 | nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u16 type, | 153 | nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u8 proto, u8 flags, |
| 153 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info) | 154 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info) |
| 154 | { | 155 | { |
| 155 | u16 data, idx = 0; | 156 | u16 data, idx = 0; |
| 156 | while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) { | 157 | while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) { |
| 157 | if (info->match == type) | 158 | if ((info->proto == proto || info->proto == 0xff) && |
| 159 | (info->flags == flags)) | ||
| 158 | break; | 160 | break; |
| 159 | } | 161 | } |
| 160 | return data; | 162 | return data; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c index e292f5679418..389fb13a1998 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c | |||
| @@ -69,11 +69,11 @@ gm107_ltc_zbc_clear_depth(struct nvkm_ltc *ltc, int i, const u32 depth) | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static void | 71 | static void |
| 72 | gm107_ltc_lts_isr(struct nvkm_ltc *ltc, int c, int s) | 72 | gm107_ltc_intr_lts(struct nvkm_ltc *ltc, int c, int s) |
| 73 | { | 73 | { |
| 74 | struct nvkm_subdev *subdev = <c->subdev; | 74 | struct nvkm_subdev *subdev = <c->subdev; |
| 75 | struct nvkm_device *device = subdev->device; | 75 | struct nvkm_device *device = subdev->device; |
| 76 | u32 base = 0x140000 + (c * 0x2000) + (s * 0x200); | 76 | u32 base = 0x140400 + (c * 0x2000) + (s * 0x200); |
| 77 | u32 stat = nvkm_rd32(device, base + 0x00c); | 77 | u32 stat = nvkm_rd32(device, base + 0x00c); |
| 78 | 78 | ||
| 79 | if (stat) { | 79 | if (stat) { |
| @@ -92,7 +92,7 @@ gm107_ltc_intr(struct nvkm_ltc *ltc) | |||
| 92 | while (mask) { | 92 | while (mask) { |
| 93 | u32 s, c = __ffs(mask); | 93 | u32 s, c = __ffs(mask); |
| 94 | for (s = 0; s < ltc->lts_nr; s++) | 94 | for (s = 0; s < ltc->lts_nr; s++) |
| 95 | gm107_ltc_lts_isr(ltc, c, s); | 95 | gm107_ltc_intr_lts(ltc, c, s); |
| 96 | mask &= ~(1 << c); | 96 | mask &= ~(1 << c); |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c index 2a29bfd5125a..e18e0dc19ec8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c | |||
| @@ -46,7 +46,7 @@ static const struct nvkm_ltc_func | |||
| 46 | gm200_ltc = { | 46 | gm200_ltc = { |
| 47 | .oneinit = gm200_ltc_oneinit, | 47 | .oneinit = gm200_ltc_oneinit, |
| 48 | .init = gm200_ltc_init, | 48 | .init = gm200_ltc_init, |
| 49 | .intr = gm107_ltc_intr, /*XXX: not validated */ | 49 | .intr = gm107_ltc_intr, |
| 50 | .cbc_clear = gm107_ltc_cbc_clear, | 50 | .cbc_clear = gm107_ltc_cbc_clear, |
| 51 | .cbc_wait = gm107_ltc_cbc_wait, | 51 | .cbc_wait = gm107_ltc_cbc_wait, |
| 52 | .zbc = 16, | 52 | .zbc = 16, |
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig index 73241c4eb7aa..336ad4de9981 100644 --- a/drivers/gpu/drm/omapdrm/Kconfig +++ b/drivers/gpu/drm/omapdrm/Kconfig | |||
| @@ -2,6 +2,7 @@ config DRM_OMAP | |||
| 2 | tristate "OMAP DRM" | 2 | tristate "OMAP DRM" |
| 3 | depends on DRM | 3 | depends on DRM |
| 4 | depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM | 4 | depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM |
| 5 | select OMAP2_DSS | ||
| 5 | select DRM_KMS_HELPER | 6 | select DRM_KMS_HELPER |
| 6 | select DRM_KMS_FB_HELPER | 7 | select DRM_KMS_FB_HELPER |
| 7 | select FB_SYS_FILLRECT | 8 | select FB_SYS_FILLRECT |
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c index 225fd8d6ab31..667ca4a24ece 100644 --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/gpio/consumer.h> | ||
| 12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c index 8c246c213e06..9594ff7a2b0c 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | * the Free Software Foundation. | 14 | * the Free Software Foundation. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio/consumer.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c index 2fd5602880a7..671806ca7d6a 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/gpio.h> | 12 | #include <linux/gpio/consumer.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c index e780fd4f8b46..7c2331be8d15 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/gpio.h> | 12 | #include <linux/gpio/consumer.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c index 36485c2137ce..2b118071b5a1 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <linux/backlight.h> | 14 | #include <linux/backlight.h> |
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/fb.h> | 16 | #include <linux/fb.h> |
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio/consumer.h> |
| 18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c index 458f77bc473d..ac680e1de603 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/spi/spi.h> | 15 | #include <linux/spi/spi.h> |
| 16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
| 18 | #include <linux/gpio/consumer.h> | ||
| 18 | 19 | ||
| 19 | #include <video/omapdss.h> | 20 | #include <video/omapdss.h> |
| 20 | #include <video/omap-panel-data.h> | 21 | #include <video/omap-panel-data.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c index 780cb263a318..38d2920a95e6 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
| 17 | #include <linux/fb.h> | 17 | #include <linux/fb.h> |
| 18 | #include <linux/gpio.h> | 18 | #include <linux/gpio/consumer.h> |
| 19 | #include <linux/of_gpio.h> | 19 | #include <linux/of_gpio.h> |
| 20 | 20 | ||
| 21 | #include <video/omapdss.h> | 21 | #include <video/omapdss.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c index 529a017602e4..4363fffc87e3 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
| 13 | #include <linux/gpio.h> | 13 | #include <linux/gpio/consumer.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <linux/of_gpio.h> | 16 | #include <linux/of_gpio.h> |
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c index 31efcca801bd..deb416736aad 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/backlight.h> | 30 | #include <linux/backlight.h> |
| 31 | #include <linux/fb.h> | 31 | #include <linux/fb.h> |
| 32 | #include <linux/gpio.h> | 32 | #include <linux/gpio/consumer.h> |
| 33 | #include <linux/of.h> | 33 | #include <linux/of.h> |
| 34 | #include <linux/of_gpio.h> | 34 | #include <linux/of_gpio.h> |
| 35 | 35 | ||
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c index 03e2beb7b4f0..d93175b03a12 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/spi/spi.h> | 15 | #include <linux/spi/spi.h> |
| 16 | #include <linux/regulator/consumer.h> | 16 | #include <linux/regulator/consumer.h> |
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio/consumer.h> |
| 18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 8730646a0cbb..56c43f355ce3 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c | |||
| @@ -1167,7 +1167,6 @@ static int dsi_regulator_init(struct platform_device *dsidev) | |||
| 1167 | { | 1167 | { |
| 1168 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1168 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
| 1169 | struct regulator *vdds_dsi; | 1169 | struct regulator *vdds_dsi; |
| 1170 | int r; | ||
| 1171 | 1170 | ||
| 1172 | if (dsi->vdds_dsi_reg != NULL) | 1171 | if (dsi->vdds_dsi_reg != NULL) |
| 1173 | return 0; | 1172 | return 0; |
| @@ -1180,15 +1179,6 @@ static int dsi_regulator_init(struct platform_device *dsidev) | |||
| 1180 | return PTR_ERR(vdds_dsi); | 1179 | return PTR_ERR(vdds_dsi); |
| 1181 | } | 1180 | } |
| 1182 | 1181 | ||
| 1183 | if (regulator_can_change_voltage(vdds_dsi)) { | ||
| 1184 | r = regulator_set_voltage(vdds_dsi, 1800000, 1800000); | ||
| 1185 | if (r) { | ||
| 1186 | devm_regulator_put(vdds_dsi); | ||
| 1187 | DSSERR("can't set the DSI regulator voltage\n"); | ||
| 1188 | return r; | ||
| 1189 | } | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | dsi->vdds_dsi_reg = vdds_dsi; | 1182 | dsi->vdds_dsi_reg = vdds_dsi; |
| 1193 | 1183 | ||
| 1194 | return 0; | 1184 | return 0; |
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index f95ff319e68e..3303cfad4838 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
| 31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
| 32 | #include <linux/clk.h> | 32 | #include <linux/clk.h> |
| 33 | #include <linux/pinctrl/consumer.h> | ||
| 33 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
| 34 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
| 35 | #include <linux/gfp.h> | 36 | #include <linux/gfp.h> |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index f892ae157ff3..4d46cdf7a037 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
| 34 | #include <linux/regulator/consumer.h> | 34 | #include <linux/regulator/consumer.h> |
| 35 | #include <linux/component.h> | 35 | #include <linux/component.h> |
| 36 | #include <linux/of.h> | ||
| 36 | #include <video/omapdss.h> | 37 | #include <video/omapdss.h> |
| 37 | #include <sound/omap-hdmi-audio.h> | 38 | #include <sound/omap-hdmi-audio.h> |
| 38 | 39 | ||
| @@ -100,7 +101,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) | |||
| 100 | 101 | ||
| 101 | static int hdmi_init_regulator(void) | 102 | static int hdmi_init_regulator(void) |
| 102 | { | 103 | { |
| 103 | int r; | ||
| 104 | struct regulator *reg; | 104 | struct regulator *reg; |
| 105 | 105 | ||
| 106 | if (hdmi.vdda_reg != NULL) | 106 | if (hdmi.vdda_reg != NULL) |
| @@ -114,15 +114,6 @@ static int hdmi_init_regulator(void) | |||
| 114 | return PTR_ERR(reg); | 114 | return PTR_ERR(reg); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | if (regulator_can_change_voltage(reg)) { | ||
| 118 | r = regulator_set_voltage(reg, 1800000, 1800000); | ||
| 119 | if (r) { | ||
| 120 | devm_regulator_put(reg); | ||
| 121 | DSSWARN("can't set the regulator voltage\n"); | ||
| 122 | return r; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | hdmi.vdda_reg = reg; | 117 | hdmi.vdda_reg = reg; |
| 127 | 118 | ||
| 128 | return 0; | 119 | return 0; |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index fa72e735dad2..ef3afe99e487 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | |||
| @@ -211,7 +211,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) | |||
| 211 | static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) | 211 | static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) |
| 212 | { | 212 | { |
| 213 | DSSDBG("Enter hdmi_core_powerdown_disable\n"); | 213 | DSSDBG("Enter hdmi_core_powerdown_disable\n"); |
| 214 | REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0); | 214 | REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0); |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | static void hdmi_core_swreset_release(struct hdmi_core_data *core) | 217 | static void hdmi_core_swreset_release(struct hdmi_core_data *core) |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index a43f7b10e113..9255c0e1e4a7 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/gpio.h> | 38 | #include <linux/gpio.h> |
| 39 | #include <linux/regulator/consumer.h> | 39 | #include <linux/regulator/consumer.h> |
| 40 | #include <linux/component.h> | 40 | #include <linux/component.h> |
| 41 | #include <linux/of.h> | ||
| 41 | #include <video/omapdss.h> | 42 | #include <video/omapdss.h> |
| 42 | #include <sound/omap-hdmi-audio.h> | 43 | #include <sound/omap-hdmi-audio.h> |
| 43 | 44 | ||
| @@ -119,7 +120,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) | |||
| 119 | 120 | ||
| 120 | static int hdmi_init_regulator(void) | 121 | static int hdmi_init_regulator(void) |
| 121 | { | 122 | { |
| 122 | int r; | ||
| 123 | struct regulator *reg; | 123 | struct regulator *reg; |
| 124 | 124 | ||
| 125 | if (hdmi.vdda_reg != NULL) | 125 | if (hdmi.vdda_reg != NULL) |
| @@ -131,15 +131,6 @@ static int hdmi_init_regulator(void) | |||
| 131 | return PTR_ERR(reg); | 131 | return PTR_ERR(reg); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | if (regulator_can_change_voltage(reg)) { | ||
| 135 | r = regulator_set_voltage(reg, 1800000, 1800000); | ||
| 136 | if (r) { | ||
| 137 | devm_regulator_put(reg); | ||
| 138 | DSSWARN("can't set the regulator voltage\n"); | ||
| 139 | return r; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | hdmi.vdda_reg = reg; | 134 | hdmi.vdda_reg = reg; |
| 144 | 135 | ||
| 145 | return 0; | 136 | return 0; |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c index 6a397520cae5..8ab2093daa12 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | |||
| @@ -51,8 +51,8 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core) | |||
| 51 | { | 51 | { |
| 52 | void __iomem *base = core->base; | 52 | void __iomem *base = core->base; |
| 53 | const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ | 53 | const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ |
| 54 | const unsigned ss_scl_high = 4000; /* ns */ | 54 | const unsigned ss_scl_high = 4600; /* ns */ |
| 55 | const unsigned ss_scl_low = 4700; /* ns */ | 55 | const unsigned ss_scl_low = 5400; /* ns */ |
| 56 | const unsigned fs_scl_high = 600; /* ns */ | 56 | const unsigned fs_scl_high = 600; /* ns */ |
| 57 | const unsigned fs_scl_low = 1300; /* ns */ | 57 | const unsigned fs_scl_low = 1300; /* ns */ |
| 58 | const unsigned sda_hold = 1000; /* ns */ | 58 | const unsigned sda_hold = 1000; /* ns */ |
| @@ -458,7 +458,7 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, | |||
| 458 | 458 | ||
| 459 | c = (ptr[1] >> 6) & 0x3; | 459 | c = (ptr[1] >> 6) & 0x3; |
| 460 | m = (ptr[1] >> 4) & 0x3; | 460 | m = (ptr[1] >> 4) & 0x3; |
| 461 | r = (ptr[1] >> 0) & 0x3; | 461 | r = (ptr[1] >> 0) & 0xf; |
| 462 | 462 | ||
| 463 | itc = (ptr[2] >> 7) & 0x1; | 463 | itc = (ptr[2] >> 7) & 0x1; |
| 464 | ec = (ptr[2] >> 4) & 0x7; | 464 | ec = (ptr[2] >> 4) & 0x7; |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c index 1f5d19c119ce..f98b750fc499 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/seq_file.h> | ||
| 16 | #include <video/omapdss.h> | 17 | #include <video/omapdss.h> |
| 17 | 18 | ||
| 18 | #include "dss.h" | 19 | #include "dss.h" |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c index 06e23a7c432c..f1015e8b8267 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
| 19 | #include <linux/seq_file.h> | ||
| 19 | 20 | ||
| 20 | #include <video/omapdss.h> | 21 | #include <video/omapdss.h> |
| 21 | 22 | ||
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c index 13442b9052d1..055f62fca5dc 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | #include <linux/seq_file.h> | ||
| 17 | #include <video/omapdss.h> | 18 | #include <video/omapdss.h> |
| 18 | 19 | ||
| 19 | #include "dss.h" | 20 | #include "dss.h" |
diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c index 6f5fc14fc015..479bf24050f8 100644 --- a/drivers/gpu/drm/omapdrm/omap_debugfs.c +++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | |||
| 20 | #include <drm/drm_crtc.h> | 22 | #include <drm/drm_crtc.h> |
| 21 | #include <drm/drm_fb_helper.h> | 23 | #include <drm/drm_fb_helper.h> |
| 22 | 24 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index de275a5be1db..4ceed7a9762f 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/platform_device.h> /* platform_device() */ | 28 | #include <linux/platform_device.h> /* platform_device() */ |
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/seq_file.h> | ||
| 30 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 31 | #include <linux/time.h> | 32 | #include <linux/time.h> |
| 32 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index 94ec06d3d737..f84570d1636c 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | |||
| 20 | #include <drm/drm_crtc.h> | 22 | #include <drm/drm_crtc.h> |
| 21 | #include <drm/drm_crtc_helper.h> | 23 | #include <drm/drm_crtc_helper.h> |
| 22 | 24 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index b97afc281778..03698b6c806c 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/seq_file.h> | ||
| 20 | #include <linux/shmem_fs.h> | 21 | #include <linux/shmem_fs.h> |
| 21 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 22 | #include <linux/pfn_t.h> | 23 | #include <linux/pfn_t.h> |
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index 505620c7c2c8..e04deedabd4a 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c | |||
| @@ -51,15 +51,6 @@ static void sti_crtc_disabling(struct drm_crtc *crtc) | |||
| 51 | mixer->status = STI_MIXER_DISABLING; | 51 | mixer->status = STI_MIXER_DISABLING; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | static bool sti_crtc_mode_fixup(struct drm_crtc *crtc, | ||
| 55 | const struct drm_display_mode *mode, | ||
| 56 | struct drm_display_mode *adjusted_mode) | ||
| 57 | { | ||
| 58 | /* accept the provided drm_display_mode, do not fix it up */ | ||
| 59 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | static int | 54 | static int |
| 64 | sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) | 55 | sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) |
| 65 | { | 56 | { |
| @@ -230,7 +221,6 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc, | |||
| 230 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { | 221 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { |
| 231 | .enable = sti_crtc_enable, | 222 | .enable = sti_crtc_enable, |
| 232 | .disable = sti_crtc_disabling, | 223 | .disable = sti_crtc_disabling, |
| 233 | .mode_fixup = sti_crtc_mode_fixup, | ||
| 234 | .mode_set = drm_helper_crtc_mode_set, | 224 | .mode_set = drm_helper_crtc_mode_set, |
| 235 | .mode_set_nofb = sti_crtc_mode_set_nofb, | 225 | .mode_set_nofb = sti_crtc_mode_set_nofb, |
| 236 | .mode_set_base = drm_helper_crtc_mode_set_base, | 226 | .mode_set_base = drm_helper_crtc_mode_set_base, |
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 904d0754ad78..0f18b76c7906 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
| @@ -456,14 +456,6 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, | |||
| 456 | 456 | ||
| 457 | WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); | 457 | WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); |
| 458 | 458 | ||
| 459 | HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | ||
| 460 | vc4_state->mm.start); | ||
| 461 | |||
| 462 | if (debug_dump_regs) { | ||
| 463 | DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); | ||
| 464 | vc4_hvs_dump_state(dev); | ||
| 465 | } | ||
| 466 | |||
| 467 | if (crtc->state->event) { | 459 | if (crtc->state->event) { |
| 468 | unsigned long flags; | 460 | unsigned long flags; |
| 469 | 461 | ||
| @@ -473,8 +465,20 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, | |||
| 473 | 465 | ||
| 474 | spin_lock_irqsave(&dev->event_lock, flags); | 466 | spin_lock_irqsave(&dev->event_lock, flags); |
| 475 | vc4_crtc->event = crtc->state->event; | 467 | vc4_crtc->event = crtc->state->event; |
| 476 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 477 | crtc->state->event = NULL; | 468 | crtc->state->event = NULL; |
| 469 | |||
| 470 | HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | ||
| 471 | vc4_state->mm.start); | ||
| 472 | |||
| 473 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 474 | } else { | ||
| 475 | HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), | ||
| 476 | vc4_state->mm.start); | ||
| 477 | } | ||
| 478 | |||
| 479 | if (debug_dump_regs) { | ||
| 480 | DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); | ||
| 481 | vc4_hvs_dump_state(dev); | ||
| 478 | } | 482 | } |
| 479 | } | 483 | } |
| 480 | 484 | ||
| @@ -500,12 +504,17 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) | |||
| 500 | { | 504 | { |
| 501 | struct drm_crtc *crtc = &vc4_crtc->base; | 505 | struct drm_crtc *crtc = &vc4_crtc->base; |
| 502 | struct drm_device *dev = crtc->dev; | 506 | struct drm_device *dev = crtc->dev; |
| 507 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 508 | struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); | ||
| 509 | u32 chan = vc4_crtc->channel; | ||
| 503 | unsigned long flags; | 510 | unsigned long flags; |
| 504 | 511 | ||
| 505 | spin_lock_irqsave(&dev->event_lock, flags); | 512 | spin_lock_irqsave(&dev->event_lock, flags); |
| 506 | if (vc4_crtc->event) { | 513 | if (vc4_crtc->event && |
| 514 | (vc4_state->mm.start == HVS_READ(SCALER_DISPLACTX(chan)))) { | ||
| 507 | drm_crtc_send_vblank_event(crtc, vc4_crtc->event); | 515 | drm_crtc_send_vblank_event(crtc, vc4_crtc->event); |
| 508 | vc4_crtc->event = NULL; | 516 | vc4_crtc->event = NULL; |
| 517 | drm_crtc_vblank_put(crtc); | ||
| 509 | } | 518 | } |
| 510 | spin_unlock_irqrestore(&dev->event_lock, flags); | 519 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 511 | } | 520 | } |
| @@ -556,6 +565,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) | |||
| 556 | spin_unlock_irqrestore(&dev->event_lock, flags); | 565 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 557 | } | 566 | } |
| 558 | 567 | ||
| 568 | drm_crtc_vblank_put(crtc); | ||
| 559 | drm_framebuffer_unreference(flip_state->fb); | 569 | drm_framebuffer_unreference(flip_state->fb); |
| 560 | kfree(flip_state); | 570 | kfree(flip_state); |
| 561 | 571 | ||
| @@ -598,6 +608,8 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, | |||
| 598 | return ret; | 608 | return ret; |
| 599 | } | 609 | } |
| 600 | 610 | ||
| 611 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | ||
| 612 | |||
| 601 | /* Immediately update the plane's legacy fb pointer, so that later | 613 | /* Immediately update the plane's legacy fb pointer, so that later |
| 602 | * modeset prep sees the state that will be present when the semaphore | 614 | * modeset prep sees the state that will be present when the semaphore |
| 603 | * is released. | 615 | * is released. |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 3446ece21b4a..250ed7e3754c 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
| @@ -66,12 +66,12 @@ static const struct file_operations vc4_drm_fops = { | |||
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | static const struct drm_ioctl_desc vc4_drm_ioctls[] = { | 68 | static const struct drm_ioctl_desc vc4_drm_ioctls[] = { |
| 69 | DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0), | 69 | DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, DRM_RENDER_ALLOW), |
| 70 | DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0), | 70 | DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, DRM_RENDER_ALLOW), |
| 71 | DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0), | 71 | DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, DRM_RENDER_ALLOW), |
| 72 | DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), | 72 | DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, DRM_RENDER_ALLOW), |
| 73 | DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), | 73 | DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, DRM_RENDER_ALLOW), |
| 74 | DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), | 74 | DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, DRM_RENDER_ALLOW), |
| 75 | DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, | 75 | DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, |
| 76 | DRM_ROOT_ONLY), | 76 | DRM_ROOT_ONLY), |
| 77 | }; | 77 | }; |
| @@ -91,7 +91,7 @@ static struct drm_driver vc4_drm_driver = { | |||
| 91 | 91 | ||
| 92 | .enable_vblank = vc4_enable_vblank, | 92 | .enable_vblank = vc4_enable_vblank, |
| 93 | .disable_vblank = vc4_disable_vblank, | 93 | .disable_vblank = vc4_disable_vblank, |
| 94 | .get_vblank_counter = drm_vblank_count, | 94 | .get_vblank_counter = drm_vblank_no_hw_counter, |
| 95 | 95 | ||
| 96 | #if defined(CONFIG_DEBUG_FS) | 96 | #if defined(CONFIG_DEBUG_FS) |
| 97 | .debugfs_init = vc4_debugfs_init, | 97 | .debugfs_init = vc4_debugfs_init, |
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index cb37751bc99f..861a623bc185 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c | |||
| @@ -117,10 +117,18 @@ static int vc4_atomic_commit(struct drm_device *dev, | |||
| 117 | return -ENOMEM; | 117 | return -ENOMEM; |
| 118 | 118 | ||
| 119 | /* Make sure that any outstanding modesets have finished. */ | 119 | /* Make sure that any outstanding modesets have finished. */ |
| 120 | ret = down_interruptible(&vc4->async_modeset); | 120 | if (nonblock) { |
| 121 | if (ret) { | 121 | ret = down_trylock(&vc4->async_modeset); |
| 122 | kfree(c); | 122 | if (ret) { |
| 123 | return ret; | 123 | kfree(c); |
| 124 | return -EBUSY; | ||
| 125 | } | ||
| 126 | } else { | ||
| 127 | ret = down_interruptible(&vc4->async_modeset); | ||
| 128 | if (ret) { | ||
| 129 | kfree(c); | ||
| 130 | return ret; | ||
| 131 | } | ||
| 124 | } | 132 | } |
| 125 | 133 | ||
| 126 | ret = drm_atomic_helper_prepare_planes(dev, state); | 134 | ret = drm_atomic_helper_prepare_planes(dev, state); |
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 6163b95c5411..f99eece4cc97 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h | |||
| @@ -341,6 +341,10 @@ | |||
| 341 | #define SCALER_DISPLACT0 0x00000030 | 341 | #define SCALER_DISPLACT0 0x00000030 |
| 342 | #define SCALER_DISPLACT1 0x00000034 | 342 | #define SCALER_DISPLACT1 0x00000034 |
| 343 | #define SCALER_DISPLACT2 0x00000038 | 343 | #define SCALER_DISPLACT2 0x00000038 |
| 344 | #define SCALER_DISPLACTX(x) (SCALER_DISPLACT0 + \ | ||
| 345 | (x) * (SCALER_DISPLACT1 - \ | ||
| 346 | SCALER_DISPLACT0)) | ||
| 347 | |||
| 344 | #define SCALER_DISPCTRL0 0x00000040 | 348 | #define SCALER_DISPCTRL0 0x00000040 |
| 345 | # define SCALER_DISPCTRLX_ENABLE BIT(31) | 349 | # define SCALER_DISPCTRLX_ENABLE BIT(31) |
| 346 | # define SCALER_DISPCTRLX_RESET BIT(30) | 350 | # define SCALER_DISPCTRLX_RESET BIT(30) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index 6de283c8fa3e..f0374f9b56ca 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 31 | #include <linux/frame.h> | ||
| 31 | #include <asm/hypervisor.h> | 32 | #include <asm/hypervisor.h> |
| 32 | #include "drmP.h" | 33 | #include "drmP.h" |
| 33 | #include "vmwgfx_msg.h" | 34 | #include "vmwgfx_msg.h" |
| @@ -194,7 +195,7 @@ static int vmw_send_msg(struct rpc_channel *channel, const char *msg) | |||
| 194 | 195 | ||
| 195 | return -EINVAL; | 196 | return -EINVAL; |
| 196 | } | 197 | } |
| 197 | 198 | STACK_FRAME_NON_STANDARD(vmw_send_msg); | |
| 198 | 199 | ||
| 199 | 200 | ||
| 200 | /** | 201 | /** |
| @@ -304,6 +305,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, | |||
| 304 | 305 | ||
| 305 | return 0; | 306 | return 0; |
| 306 | } | 307 | } |
| 308 | STACK_FRAME_NON_STANDARD(vmw_recv_msg); | ||
| 307 | 309 | ||
| 308 | 310 | ||
| 309 | /** | 311 | /** |
