diff options
Diffstat (limited to 'drivers/gpu/drm')
85 files changed, 814 insertions, 329 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 992f00b65be4..e055d5be1c3c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1820,6 +1820,8 @@ struct amdgpu_asic_funcs { | |||
1820 | /* MM block clocks */ | 1820 | /* MM block clocks */ |
1821 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); | 1821 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); |
1822 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); | 1822 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); |
1823 | /* query virtual capabilities */ | ||
1824 | u32 (*get_virtual_caps)(struct amdgpu_device *adev); | ||
1823 | }; | 1825 | }; |
1824 | 1826 | ||
1825 | /* | 1827 | /* |
@@ -1914,8 +1916,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device); | |||
1914 | 1916 | ||
1915 | 1917 | ||
1916 | /* GPU virtualization */ | 1918 | /* GPU virtualization */ |
1919 | #define AMDGPU_VIRT_CAPS_SRIOV_EN (1 << 0) | ||
1920 | #define AMDGPU_VIRT_CAPS_IS_VF (1 << 1) | ||
1917 | struct amdgpu_virtualization { | 1921 | struct amdgpu_virtualization { |
1918 | bool supports_sr_iov; | 1922 | bool supports_sr_iov; |
1923 | bool is_virtual; | ||
1924 | u32 caps; | ||
1919 | }; | 1925 | }; |
1920 | 1926 | ||
1921 | /* | 1927 | /* |
@@ -2204,6 +2210,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
2204 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) | 2210 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) |
2205 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) | 2211 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) |
2206 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) | 2212 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) |
2213 | #define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev))) | ||
2207 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) | 2214 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) |
2208 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) | 2215 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) |
2209 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) | 2216 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) |
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..66482b429458 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 | ||
@@ -1378,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
1378 | return 0; | 1385 | return 0; |
1379 | } | 1386 | } |
1380 | 1387 | ||
1388 | static bool amdgpu_device_is_virtual(void) | ||
1389 | { | ||
1390 | #ifdef CONFIG_X86 | ||
1391 | return boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
1392 | #else | ||
1393 | return false; | ||
1394 | #endif | ||
1395 | } | ||
1396 | |||
1381 | /** | 1397 | /** |
1382 | * amdgpu_device_init - initialize the driver | 1398 | * amdgpu_device_init - initialize the driver |
1383 | * | 1399 | * |
@@ -1512,9 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1512 | adev->virtualization.supports_sr_iov = | 1528 | adev->virtualization.supports_sr_iov = |
1513 | amdgpu_atombios_has_gpu_virtualization_table(adev); | 1529 | amdgpu_atombios_has_gpu_virtualization_table(adev); |
1514 | 1530 | ||
1531 | /* Check if we are executing in a virtualized environment */ | ||
1532 | adev->virtualization.is_virtual = amdgpu_device_is_virtual(); | ||
1533 | adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev); | ||
1534 | |||
1515 | /* Post card if necessary */ | 1535 | /* Post card if necessary */ |
1516 | if (!amdgpu_card_posted(adev) || | 1536 | if (!amdgpu_card_posted(adev) || |
1517 | adev->virtualization.supports_sr_iov) { | 1537 | (adev->virtualization.is_virtual && |
1538 | !adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) { | ||
1518 | if (!adev->bios) { | 1539 | if (!adev->bios) { |
1519 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1540 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
1520 | return -EINVAL; | 1541 | return -EINVAL; |
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/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.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 07bc795a4ca9..910431808542 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c | |||
@@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, | |||
962 | return true; | 962 | return true; |
963 | } | 963 | } |
964 | 964 | ||
965 | static u32 cik_get_virtual_caps(struct amdgpu_device *adev) | ||
966 | { | ||
967 | /* CIK does not support SR-IOV */ | ||
968 | return 0; | ||
969 | } | ||
970 | |||
965 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { | 971 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { |
966 | {mmGRBM_STATUS, false}, | 972 | {mmGRBM_STATUS, false}, |
967 | {mmGB_ADDR_CONFIG, false}, | 973 | {mmGB_ADDR_CONFIG, false}, |
@@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = | |||
2007 | .get_xclk = &cik_get_xclk, | 2013 | .get_xclk = &cik_get_xclk, |
2008 | .set_uvd_clocks = &cik_set_uvd_clocks, | 2014 | .set_uvd_clocks = &cik_set_uvd_clocks, |
2009 | .set_vce_clocks = &cik_set_vce_clocks, | 2015 | .set_vce_clocks = &cik_set_vce_clocks, |
2016 | .get_virtual_caps = &cik_get_virtual_caps, | ||
2010 | /* these should be moved to their own ip modules */ | 2017 | /* these should be moved to their own ip modules */ |
2011 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, | 2018 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, |
2012 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, | 2019 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, |
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..fc8ff4d3ccf8 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 | } |
@@ -4816,7 +4833,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev, | |||
4816 | case 2: | 4833 | case 2: |
4817 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { | 4834 | for (i = 0; i < adev->gfx.num_compute_rings; i++) { |
4818 | ring = &adev->gfx.compute_ring[i]; | 4835 | ring = &adev->gfx.compute_ring[i]; |
4819 | if ((ring->me == me_id) & (ring->pipe == pipe_id)) | 4836 | if ((ring->me == me_id) && (ring->pipe == pipe_id)) |
4820 | amdgpu_fence_process(ring); | 4837 | amdgpu_fence_process(ring); |
4821 | } | 4838 | } |
4822 | break; | 4839 | break; |
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/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 2c88d0b66cf3..a65c96029476 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
@@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, | |||
421 | return true; | 421 | return true; |
422 | } | 422 | } |
423 | 423 | ||
424 | static u32 vi_get_virtual_caps(struct amdgpu_device *adev) | ||
425 | { | ||
426 | u32 caps = 0; | ||
427 | u32 reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER); | ||
428 | |||
429 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE)) | ||
430 | caps |= AMDGPU_VIRT_CAPS_SRIOV_EN; | ||
431 | |||
432 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER)) | ||
433 | caps |= AMDGPU_VIRT_CAPS_IS_VF; | ||
434 | |||
435 | return caps; | ||
436 | } | ||
437 | |||
424 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { | 438 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { |
425 | {mmGB_MACROTILE_MODE7, true}, | 439 | {mmGB_MACROTILE_MODE7, true}, |
426 | }; | 440 | }; |
@@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs = | |||
1118 | .get_xclk = &vi_get_xclk, | 1132 | .get_xclk = &vi_get_xclk, |
1119 | .set_uvd_clocks = &vi_set_uvd_clocks, | 1133 | .set_uvd_clocks = &vi_set_uvd_clocks, |
1120 | .set_vce_clocks = &vi_set_vce_clocks, | 1134 | .set_vce_clocks = &vi_set_vce_clocks, |
1135 | .get_virtual_caps = &vi_get_virtual_caps, | ||
1121 | /* these should be moved to their own ip modules */ | 1136 | /* these should be moved to their own ip modules */ |
1122 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, | 1137 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, |
1123 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, | 1138 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index ac005796b71c..7708d90b9da9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c | |||
@@ -242,13 +242,19 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, | |||
242 | pqm_uninit(&p->pqm); | 242 | pqm_uninit(&p->pqm); |
243 | 243 | ||
244 | /* Iterate over all process device data structure and check | 244 | /* Iterate over all process device data structure and check |
245 | * if we should reset all wavefronts */ | 245 | * if we should delete debug managers and reset all wavefronts |
246 | list_for_each_entry(pdd, &p->per_device_data, per_device_list) | 246 | */ |
247 | list_for_each_entry(pdd, &p->per_device_data, per_device_list) { | ||
248 | if ((pdd->dev->dbgmgr) && | ||
249 | (pdd->dev->dbgmgr->pasid == p->pasid)) | ||
250 | kfd_dbgmgr_destroy(pdd->dev->dbgmgr); | ||
251 | |||
247 | if (pdd->reset_wavefronts) { | 252 | if (pdd->reset_wavefronts) { |
248 | pr_warn("amdkfd: Resetting all wave fronts\n"); | 253 | pr_warn("amdkfd: Resetting all wave fronts\n"); |
249 | dbgdev_wave_reset_wavefronts(pdd->dev, p); | 254 | dbgdev_wave_reset_wavefronts(pdd->dev, p); |
250 | pdd->reset_wavefronts = false; | 255 | pdd->reset_wavefronts = false; |
251 | } | 256 | } |
257 | } | ||
252 | 258 | ||
253 | mutex_unlock(&p->mutex); | 259 | mutex_unlock(&p->mutex); |
254 | 260 | ||
@@ -404,42 +410,52 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) | |||
404 | 410 | ||
405 | idx = srcu_read_lock(&kfd_processes_srcu); | 411 | idx = srcu_read_lock(&kfd_processes_srcu); |
406 | 412 | ||
413 | /* | ||
414 | * Look for the process that matches the pasid. If there is no such | ||
415 | * process, we either released it in amdkfd's own notifier, or there | ||
416 | * is a bug. Unfortunately, there is no way to tell... | ||
417 | */ | ||
407 | hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) | 418 | hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) |
408 | if (p->pasid == pasid) | 419 | if (p->pasid == pasid) { |
409 | break; | ||
410 | 420 | ||
411 | srcu_read_unlock(&kfd_processes_srcu, idx); | 421 | srcu_read_unlock(&kfd_processes_srcu, idx); |
412 | 422 | ||
413 | BUG_ON(p->pasid != pasid); | 423 | pr_debug("Unbinding process %d from IOMMU\n", pasid); |
414 | 424 | ||
415 | mutex_lock(&p->mutex); | 425 | mutex_lock(&p->mutex); |
416 | 426 | ||
417 | if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) | 427 | if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) |
418 | kfd_dbgmgr_destroy(dev->dbgmgr); | 428 | kfd_dbgmgr_destroy(dev->dbgmgr); |
419 | 429 | ||
420 | pqm_uninit(&p->pqm); | 430 | pqm_uninit(&p->pqm); |
421 | 431 | ||
422 | pdd = kfd_get_process_device_data(dev, p); | 432 | pdd = kfd_get_process_device_data(dev, p); |
423 | 433 | ||
424 | if (!pdd) { | 434 | if (!pdd) { |
425 | mutex_unlock(&p->mutex); | 435 | mutex_unlock(&p->mutex); |
426 | return; | 436 | return; |
427 | } | 437 | } |
428 | 438 | ||
429 | if (pdd->reset_wavefronts) { | 439 | if (pdd->reset_wavefronts) { |
430 | dbgdev_wave_reset_wavefronts(pdd->dev, p); | 440 | dbgdev_wave_reset_wavefronts(pdd->dev, p); |
431 | pdd->reset_wavefronts = false; | 441 | pdd->reset_wavefronts = false; |
432 | } | 442 | } |
433 | 443 | ||
434 | /* | 444 | /* |
435 | * Just mark pdd as unbound, because we still need it to call | 445 | * Just mark pdd as unbound, because we still need it |
436 | * amd_iommu_unbind_pasid() in when the process exits. | 446 | * to call amd_iommu_unbind_pasid() in when the |
437 | * We don't call amd_iommu_unbind_pasid() here | 447 | * process exits. |
438 | * because the IOMMU called us. | 448 | * We don't call amd_iommu_unbind_pasid() here |
439 | */ | 449 | * because the IOMMU called us. |
440 | pdd->bound = false; | 450 | */ |
451 | pdd->bound = false; | ||
441 | 452 | ||
442 | mutex_unlock(&p->mutex); | 453 | mutex_unlock(&p->mutex); |
454 | |||
455 | return; | ||
456 | } | ||
457 | |||
458 | srcu_read_unlock(&kfd_processes_srcu, idx); | ||
443 | } | 459 | } |
444 | 460 | ||
445 | struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p) | 461 | struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 74909e72a009..884c96f50c3d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -666,7 +666,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
666 | dev->node_props.simd_count); | 666 | dev->node_props.simd_count); |
667 | 667 | ||
668 | if (dev->mem_bank_count < dev->node_props.mem_banks_count) { | 668 | if (dev->mem_bank_count < dev->node_props.mem_banks_count) { |
669 | pr_warn("kfd: mem_banks_count truncated from %d to %d\n", | 669 | pr_info_once("kfd: mem_banks_count truncated from %d to %d\n", |
670 | dev->node_props.mem_banks_count, | 670 | dev->node_props.mem_banks_count, |
671 | dev->mem_bank_count); | 671 | dev->mem_bank_count); |
672 | sysfs_show_32bit_prop(buffer, "mem_banks_count", | 672 | sysfs_show_32bit_prop(buffer, "mem_banks_count", |
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/hwmgr_ppt.h b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h index 347fef127ce9..2930a3355948 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h | |||
@@ -39,6 +39,7 @@ struct phm_ppt_v1_clock_voltage_dependency_record { | |||
39 | uint8_t phases; | 39 | uint8_t phases; |
40 | uint8_t cks_enable; | 40 | uint8_t cks_enable; |
41 | uint8_t cks_voffset; | 41 | uint8_t cks_voffset; |
42 | uint32_t sclk_offset; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record; | 45 | typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c index aa6be033f21b..1400bc420881 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c | |||
@@ -999,7 +999,7 @@ static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, | |||
999 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), | 999 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), |
1000 | (dep_table->entries[i].vddc - | 1000 | (dep_table->entries[i].vddc - |
1001 | (uint16_t)data->vddc_vddci_delta)); | 1001 | (uint16_t)data->vddc_vddci_delta)); |
1002 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; | 1002 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) | 1005 | if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) |
@@ -3520,10 +3520,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
3520 | ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state; | 3520 | ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state; |
3521 | ATOM_Tonga_POWERPLAYTABLE *powerplay_table = | 3521 | ATOM_Tonga_POWERPLAYTABLE *powerplay_table = |
3522 | (ATOM_Tonga_POWERPLAYTABLE *)pp_table; | 3522 | (ATOM_Tonga_POWERPLAYTABLE *)pp_table; |
3523 | ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = | 3523 | PPTable_Generic_SubTable_Header *sclk_dep_table = |
3524 | (ATOM_Tonga_SCLK_Dependency_Table *) | 3524 | (PPTable_Generic_SubTable_Header *) |
3525 | (((unsigned long)powerplay_table) + | 3525 | (((unsigned long)powerplay_table) + |
3526 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); | 3526 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); |
3527 | |||
3527 | ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = | 3528 | ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = |
3528 | (ATOM_Tonga_MCLK_Dependency_Table *) | 3529 | (ATOM_Tonga_MCLK_Dependency_Table *) |
3529 | (((unsigned long)powerplay_table) + | 3530 | (((unsigned long)powerplay_table) + |
@@ -3575,7 +3576,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
3575 | /* Performance levels are arranged from low to high. */ | 3576 | /* Performance levels are arranged from low to high. */ |
3576 | performance_level->memory_clock = mclk_dep_table->entries | 3577 | performance_level->memory_clock = mclk_dep_table->entries |
3577 | [state_entry->ucMemoryClockIndexLow].ulMclk; | 3578 | [state_entry->ucMemoryClockIndexLow].ulMclk; |
3578 | performance_level->engine_clock = sclk_dep_table->entries | 3579 | if (sclk_dep_table->ucRevId == 0) |
3580 | performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3581 | [state_entry->ucEngineClockIndexLow].ulSclk; | ||
3582 | else if (sclk_dep_table->ucRevId == 1) | ||
3583 | performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3579 | [state_entry->ucEngineClockIndexLow].ulSclk; | 3584 | [state_entry->ucEngineClockIndexLow].ulSclk; |
3580 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, | 3585 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, |
3581 | state_entry->ucPCIEGenLow); | 3586 | state_entry->ucPCIEGenLow); |
@@ -3586,8 +3591,14 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, | |||
3586 | [polaris10_power_state->performance_level_count++]); | 3591 | [polaris10_power_state->performance_level_count++]); |
3587 | performance_level->memory_clock = mclk_dep_table->entries | 3592 | performance_level->memory_clock = mclk_dep_table->entries |
3588 | [state_entry->ucMemoryClockIndexHigh].ulMclk; | 3593 | [state_entry->ucMemoryClockIndexHigh].ulMclk; |
3589 | performance_level->engine_clock = sclk_dep_table->entries | 3594 | |
3595 | if (sclk_dep_table->ucRevId == 0) | ||
3596 | performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3590 | [state_entry->ucEngineClockIndexHigh].ulSclk; | 3597 | [state_entry->ucEngineClockIndexHigh].ulSclk; |
3598 | else if (sclk_dep_table->ucRevId == 1) | ||
3599 | performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries | ||
3600 | [state_entry->ucEngineClockIndexHigh].ulSclk; | ||
3601 | |||
3591 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, | 3602 | performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, |
3592 | state_entry->ucPCIEGenHigh); | 3603 | state_entry->ucPCIEGenHigh); |
3593 | performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, | 3604 | performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, |
@@ -3645,7 +3656,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, | |||
3645 | switch (state->classification.ui_label) { | 3656 | switch (state->classification.ui_label) { |
3646 | case PP_StateUILabel_Performance: | 3657 | case PP_StateUILabel_Performance: |
3647 | data->use_pcie_performance_levels = true; | 3658 | data->use_pcie_performance_levels = true; |
3648 | |||
3649 | for (i = 0; i < ps->performance_level_count; i++) { | 3659 | for (i = 0; i < ps->performance_level_count; i++) { |
3650 | if (data->pcie_gen_performance.max < | 3660 | if (data->pcie_gen_performance.max < |
3651 | ps->performance_levels[i].pcie_gen) | 3661 | ps->performance_levels[i].pcie_gen) |
@@ -3661,7 +3671,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, | |||
3661 | ps->performance_levels[i].pcie_lane) | 3671 | ps->performance_levels[i].pcie_lane) |
3662 | data->pcie_lane_performance.max = | 3672 | data->pcie_lane_performance.max = |
3663 | ps->performance_levels[i].pcie_lane; | 3673 | ps->performance_levels[i].pcie_lane; |
3664 | |||
3665 | if (data->pcie_lane_performance.min > | 3674 | if (data->pcie_lane_performance.min > |
3666 | ps->performance_levels[i].pcie_lane) | 3675 | ps->performance_levels[i].pcie_lane) |
3667 | data->pcie_lane_performance.min = | 3676 | data->pcie_lane_performance.min = |
@@ -4187,12 +4196,9 @@ int polaris10_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate) | |||
4187 | { | 4196 | { |
4188 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); | 4197 | struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); |
4189 | uint32_t mm_boot_level_offset, mm_boot_level_value; | 4198 | uint32_t mm_boot_level_offset, mm_boot_level_value; |
4190 | struct phm_ppt_v1_information *table_info = | ||
4191 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | ||
4192 | 4199 | ||
4193 | if (!bgate) { | 4200 | if (!bgate) { |
4194 | data->smc_state_table.SamuBootLevel = | 4201 | data->smc_state_table.SamuBootLevel = 0; |
4195 | (uint8_t) (table_info->mm_dep_table->count - 1); | ||
4196 | mm_boot_level_offset = data->dpm_table_start + | 4202 | mm_boot_level_offset = data->dpm_table_start + |
4197 | offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); | 4203 | offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); |
4198 | mm_boot_level_offset /= 4; | 4204 | mm_boot_level_offset /= 4; |
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_pptable.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h index 1b44f4e9b8f5..f127198aafc4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h | |||
@@ -197,6 +197,22 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Table { | |||
197 | ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ | 197 | ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ |
198 | } ATOM_Tonga_SCLK_Dependency_Table; | 198 | } ATOM_Tonga_SCLK_Dependency_Table; |
199 | 199 | ||
200 | typedef struct _ATOM_Polaris_SCLK_Dependency_Record { | ||
201 | UCHAR ucVddInd; /* Base voltage */ | ||
202 | USHORT usVddcOffset; /* Offset relative to base voltage */ | ||
203 | ULONG ulSclk; | ||
204 | USHORT usEdcCurrent; | ||
205 | UCHAR ucReliabilityTemperature; | ||
206 | UCHAR ucCKSVOffsetandDisable; /* Bits 0~6: Voltage offset for CKS, Bit 7: Disable/enable for the SCLK level. */ | ||
207 | ULONG ulSclkOffset; | ||
208 | } ATOM_Polaris_SCLK_Dependency_Record; | ||
209 | |||
210 | typedef struct _ATOM_Polaris_SCLK_Dependency_Table { | ||
211 | UCHAR ucRevId; | ||
212 | UCHAR ucNumEntries; /* Number of entries. */ | ||
213 | ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ | ||
214 | } ATOM_Polaris_SCLK_Dependency_Table; | ||
215 | |||
200 | typedef struct _ATOM_Tonga_PCIE_Record { | 216 | typedef struct _ATOM_Tonga_PCIE_Record { |
201 | UCHAR ucPCIEGenSpeed; | 217 | UCHAR ucPCIEGenSpeed; |
202 | UCHAR usPCIELaneWidth; | 218 | UCHAR usPCIELaneWidth; |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c index 10e3630ee39d..671fdb4d615a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c | |||
@@ -408,41 +408,78 @@ static int get_mclk_voltage_dependency_table( | |||
408 | static int get_sclk_voltage_dependency_table( | 408 | static int get_sclk_voltage_dependency_table( |
409 | struct pp_hwmgr *hwmgr, | 409 | struct pp_hwmgr *hwmgr, |
410 | phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, | 410 | phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, |
411 | const ATOM_Tonga_SCLK_Dependency_Table * sclk_dep_table | 411 | const PPTable_Generic_SubTable_Header *sclk_dep_table |
412 | ) | 412 | ) |
413 | { | 413 | { |
414 | uint32_t table_size, i; | 414 | uint32_t table_size, i; |
415 | phm_ppt_v1_clock_voltage_dependency_table *sclk_table; | 415 | phm_ppt_v1_clock_voltage_dependency_table *sclk_table; |
416 | 416 | ||
417 | PP_ASSERT_WITH_CODE((0 != sclk_dep_table->ucNumEntries), | 417 | if (sclk_dep_table->ucRevId < 1) { |
418 | "Invalid PowerPlay Table!", return -1); | 418 | const ATOM_Tonga_SCLK_Dependency_Table *tonga_table = |
419 | (ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table; | ||
419 | 420 | ||
420 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) | 421 | PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries), |
421 | * sclk_dep_table->ucNumEntries; | 422 | "Invalid PowerPlay Table!", return -1); |
422 | 423 | ||
423 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) | 424 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) |
424 | kzalloc(table_size, GFP_KERNEL); | 425 | * tonga_table->ucNumEntries; |
425 | 426 | ||
426 | if (NULL == sclk_table) | 427 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) |
427 | return -ENOMEM; | 428 | kzalloc(table_size, GFP_KERNEL); |
428 | 429 | ||
429 | memset(sclk_table, 0x00, table_size); | 430 | if (NULL == sclk_table) |
430 | 431 | return -ENOMEM; | |
431 | sclk_table->count = (uint32_t)sclk_dep_table->ucNumEntries; | 432 | |
432 | 433 | memset(sclk_table, 0x00, table_size); | |
433 | for (i = 0; i < sclk_dep_table->ucNumEntries; i++) { | 434 | |
434 | sclk_table->entries[i].vddInd = | 435 | sclk_table->count = (uint32_t)tonga_table->ucNumEntries; |
435 | sclk_dep_table->entries[i].ucVddInd; | 436 | |
436 | sclk_table->entries[i].vdd_offset = | 437 | for (i = 0; i < tonga_table->ucNumEntries; i++) { |
437 | sclk_dep_table->entries[i].usVddcOffset; | 438 | sclk_table->entries[i].vddInd = |
438 | sclk_table->entries[i].clk = | 439 | tonga_table->entries[i].ucVddInd; |
439 | sclk_dep_table->entries[i].ulSclk; | 440 | sclk_table->entries[i].vdd_offset = |
440 | sclk_table->entries[i].cks_enable = | 441 | tonga_table->entries[i].usVddcOffset; |
441 | (((sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; | 442 | sclk_table->entries[i].clk = |
442 | sclk_table->entries[i].cks_voffset = | 443 | tonga_table->entries[i].ulSclk; |
443 | (sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | 444 | sclk_table->entries[i].cks_enable = |
444 | } | 445 | (((tonga_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; |
446 | sclk_table->entries[i].cks_voffset = | ||
447 | (tonga_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | ||
448 | } | ||
449 | } else { | ||
450 | const ATOM_Polaris_SCLK_Dependency_Table *polaris_table = | ||
451 | (ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table; | ||
452 | |||
453 | PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries), | ||
454 | "Invalid PowerPlay Table!", return -1); | ||
455 | |||
456 | table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) | ||
457 | * polaris_table->ucNumEntries; | ||
458 | |||
459 | sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) | ||
460 | kzalloc(table_size, GFP_KERNEL); | ||
445 | 461 | ||
462 | if (NULL == sclk_table) | ||
463 | return -ENOMEM; | ||
464 | |||
465 | memset(sclk_table, 0x00, table_size); | ||
466 | |||
467 | sclk_table->count = (uint32_t)polaris_table->ucNumEntries; | ||
468 | |||
469 | for (i = 0; i < polaris_table->ucNumEntries; i++) { | ||
470 | sclk_table->entries[i].vddInd = | ||
471 | polaris_table->entries[i].ucVddInd; | ||
472 | sclk_table->entries[i].vdd_offset = | ||
473 | polaris_table->entries[i].usVddcOffset; | ||
474 | sclk_table->entries[i].clk = | ||
475 | polaris_table->entries[i].ulSclk; | ||
476 | sclk_table->entries[i].cks_enable = | ||
477 | (((polaris_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; | ||
478 | sclk_table->entries[i].cks_voffset = | ||
479 | (polaris_table->entries[i].ucCKSVOffsetandDisable & 0x7F); | ||
480 | sclk_table->entries[i].sclk_offset = polaris_table->entries[i].ulSclkOffset; | ||
481 | } | ||
482 | } | ||
446 | *pp_tonga_sclk_dep_table = sclk_table; | 483 | *pp_tonga_sclk_dep_table = sclk_table; |
447 | 484 | ||
448 | return 0; | 485 | return 0; |
@@ -708,8 +745,8 @@ static int init_clock_voltage_dependency( | |||
708 | const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = | 745 | const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = |
709 | (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) + | 746 | (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) + |
710 | le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); | 747 | le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); |
711 | const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = | 748 | const PPTable_Generic_SubTable_Header *sclk_dep_table = |
712 | (const ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long) powerplay_table) + | 749 | (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) + |
713 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); | 750 | le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); |
714 | const ATOM_Tonga_Hard_Limit_Table *pHardLimits = | 751 | const ATOM_Tonga_Hard_Limit_Table *pHardLimits = |
715 | (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) + | 752 | (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) + |
@@ -1040,48 +1077,44 @@ int tonga_pp_tables_uninitialize(struct pp_hwmgr *hwmgr) | |||
1040 | struct phm_ppt_v1_information *pp_table_information = | 1077 | struct phm_ppt_v1_information *pp_table_information = |
1041 | (struct phm_ppt_v1_information *)(hwmgr->pptable); | 1078 | (struct phm_ppt_v1_information *)(hwmgr->pptable); |
1042 | 1079 | ||
1043 | if (NULL != hwmgr->soft_pp_table) { | 1080 | if (NULL != hwmgr->soft_pp_table) |
1044 | kfree(hwmgr->soft_pp_table); | ||
1045 | hwmgr->soft_pp_table = NULL; | 1081 | hwmgr->soft_pp_table = NULL; |
1046 | } | ||
1047 | 1082 | ||
1048 | if (NULL != pp_table_information->vdd_dep_on_sclk) | 1083 | kfree(pp_table_information->vdd_dep_on_sclk); |
1049 | pp_table_information->vdd_dep_on_sclk = NULL; | 1084 | pp_table_information->vdd_dep_on_sclk = NULL; |
1050 | 1085 | ||
1051 | if (NULL != pp_table_information->vdd_dep_on_mclk) | 1086 | kfree(pp_table_information->vdd_dep_on_mclk); |
1052 | pp_table_information->vdd_dep_on_mclk = NULL; | 1087 | pp_table_information->vdd_dep_on_mclk = NULL; |
1053 | 1088 | ||
1054 | if (NULL != pp_table_information->valid_mclk_values) | 1089 | kfree(pp_table_information->valid_mclk_values); |
1055 | pp_table_information->valid_mclk_values = NULL; | 1090 | pp_table_information->valid_mclk_values = NULL; |
1056 | 1091 | ||
1057 | if (NULL != pp_table_information->valid_sclk_values) | 1092 | kfree(pp_table_information->valid_sclk_values); |
1058 | pp_table_information->valid_sclk_values = NULL; | 1093 | pp_table_information->valid_sclk_values = NULL; |
1059 | 1094 | ||
1060 | if (NULL != pp_table_information->vddc_lookup_table) | 1095 | kfree(pp_table_information->vddc_lookup_table); |
1061 | pp_table_information->vddc_lookup_table = NULL; | 1096 | pp_table_information->vddc_lookup_table = NULL; |
1062 | 1097 | ||
1063 | if (NULL != pp_table_information->vddgfx_lookup_table) | 1098 | kfree(pp_table_information->vddgfx_lookup_table); |
1064 | pp_table_information->vddgfx_lookup_table = NULL; | 1099 | pp_table_information->vddgfx_lookup_table = NULL; |
1065 | 1100 | ||
1066 | if (NULL != pp_table_information->mm_dep_table) | 1101 | kfree(pp_table_information->mm_dep_table); |
1067 | pp_table_information->mm_dep_table = NULL; | 1102 | pp_table_information->mm_dep_table = NULL; |
1068 | 1103 | ||
1069 | if (NULL != pp_table_information->cac_dtp_table) | 1104 | kfree(pp_table_information->cac_dtp_table); |
1070 | pp_table_information->cac_dtp_table = NULL; | 1105 | pp_table_information->cac_dtp_table = NULL; |
1071 | 1106 | ||
1072 | if (NULL != hwmgr->dyn_state.cac_dtp_table) | 1107 | kfree(hwmgr->dyn_state.cac_dtp_table); |
1073 | hwmgr->dyn_state.cac_dtp_table = NULL; | 1108 | hwmgr->dyn_state.cac_dtp_table = NULL; |
1074 | 1109 | ||
1075 | if (NULL != pp_table_information->ppm_parameter_table) | 1110 | kfree(pp_table_information->ppm_parameter_table); |
1076 | pp_table_information->ppm_parameter_table = NULL; | 1111 | pp_table_information->ppm_parameter_table = NULL; |
1077 | 1112 | ||
1078 | if (NULL != pp_table_information->pcie_table) | 1113 | kfree(pp_table_information->pcie_table); |
1079 | pp_table_information->pcie_table = NULL; | 1114 | pp_table_information->pcie_table = NULL; |
1080 | 1115 | ||
1081 | if (NULL != hwmgr->pptable) { | 1116 | kfree(hwmgr->pptable); |
1082 | kfree(hwmgr->pptable); | 1117 | hwmgr->pptable = NULL; |
1083 | hwmgr->pptable = NULL; | ||
1084 | } | ||
1085 | 1118 | ||
1086 | return result; | 1119 | return result; |
1087 | } | 1120 | } |
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/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a6e42433ef0e..26feb2f8453f 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -528,11 +528,11 @@ drm_crtc_helper_disable(struct drm_crtc *crtc) | |||
528 | int drm_crtc_helper_set_config(struct drm_mode_set *set) | 528 | int drm_crtc_helper_set_config(struct drm_mode_set *set) |
529 | { | 529 | { |
530 | struct drm_device *dev; | 530 | struct drm_device *dev; |
531 | struct drm_crtc *new_crtc; | 531 | struct drm_crtc **save_encoder_crtcs, *new_crtc; |
532 | struct drm_encoder *save_encoders, *new_encoder, *encoder; | 532 | struct drm_encoder **save_connector_encoders, *new_encoder, *encoder; |
533 | bool mode_changed = false; /* if true do a full mode set */ | 533 | bool mode_changed = false; /* if true do a full mode set */ |
534 | bool fb_changed = false; /* if true and !mode_changed just do a flip */ | 534 | bool fb_changed = false; /* if true and !mode_changed just do a flip */ |
535 | struct drm_connector *save_connectors, *connector; | 535 | struct drm_connector *connector; |
536 | int count = 0, ro, fail = 0; | 536 | int count = 0, ro, fail = 0; |
537 | const struct drm_crtc_helper_funcs *crtc_funcs; | 537 | const struct drm_crtc_helper_funcs *crtc_funcs; |
538 | struct drm_mode_set save_set; | 538 | struct drm_mode_set save_set; |
@@ -574,15 +574,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
574 | * Allocate space for the backup of all (non-pointer) encoder and | 574 | * Allocate space for the backup of all (non-pointer) encoder and |
575 | * connector data. | 575 | * connector data. |
576 | */ | 576 | */ |
577 | save_encoders = kzalloc(dev->mode_config.num_encoder * | 577 | save_encoder_crtcs = kzalloc(dev->mode_config.num_encoder * |
578 | sizeof(struct drm_encoder), GFP_KERNEL); | 578 | sizeof(struct drm_crtc *), GFP_KERNEL); |
579 | if (!save_encoders) | 579 | if (!save_encoder_crtcs) |
580 | return -ENOMEM; | 580 | return -ENOMEM; |
581 | 581 | ||
582 | save_connectors = kzalloc(dev->mode_config.num_connector * | 582 | save_connector_encoders = kzalloc(dev->mode_config.num_connector * |
583 | sizeof(struct drm_connector), GFP_KERNEL); | 583 | sizeof(struct drm_encoder *), GFP_KERNEL); |
584 | if (!save_connectors) { | 584 | if (!save_connector_encoders) { |
585 | kfree(save_encoders); | 585 | kfree(save_encoder_crtcs); |
586 | return -ENOMEM; | 586 | return -ENOMEM; |
587 | } | 587 | } |
588 | 588 | ||
@@ -593,12 +593,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
593 | */ | 593 | */ |
594 | count = 0; | 594 | count = 0; |
595 | drm_for_each_encoder(encoder, dev) { | 595 | drm_for_each_encoder(encoder, dev) { |
596 | save_encoders[count++] = *encoder; | 596 | save_encoder_crtcs[count++] = encoder->crtc; |
597 | } | 597 | } |
598 | 598 | ||
599 | count = 0; | 599 | count = 0; |
600 | drm_for_each_connector(connector, dev) { | 600 | drm_for_each_connector(connector, dev) { |
601 | save_connectors[count++] = *connector; | 601 | save_connector_encoders[count++] = connector->encoder; |
602 | } | 602 | } |
603 | 603 | ||
604 | save_set.crtc = set->crtc; | 604 | save_set.crtc = set->crtc; |
@@ -631,8 +631,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
631 | mode_changed = true; | 631 | mode_changed = true; |
632 | } | 632 | } |
633 | 633 | ||
634 | /* take a reference on all connectors in set */ | 634 | /* take a reference on all unbound connectors in set, reuse the |
635 | * already taken reference for bound connectors | ||
636 | */ | ||
635 | for (ro = 0; ro < set->num_connectors; ro++) { | 637 | for (ro = 0; ro < set->num_connectors; ro++) { |
638 | if (set->connectors[ro]->encoder) | ||
639 | continue; | ||
636 | drm_connector_reference(set->connectors[ro]); | 640 | drm_connector_reference(set->connectors[ro]); |
637 | } | 641 | } |
638 | 642 | ||
@@ -754,30 +758,28 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
754 | } | 758 | } |
755 | } | 759 | } |
756 | 760 | ||
757 | /* after fail drop reference on all connectors in save set */ | 761 | kfree(save_connector_encoders); |
758 | count = 0; | 762 | kfree(save_encoder_crtcs); |
759 | drm_for_each_connector(connector, dev) { | ||
760 | drm_connector_unreference(&save_connectors[count++]); | ||
761 | } | ||
762 | |||
763 | kfree(save_connectors); | ||
764 | kfree(save_encoders); | ||
765 | return 0; | 763 | return 0; |
766 | 764 | ||
767 | fail: | 765 | fail: |
768 | /* Restore all previous data. */ | 766 | /* Restore all previous data. */ |
769 | count = 0; | 767 | count = 0; |
770 | drm_for_each_encoder(encoder, dev) { | 768 | drm_for_each_encoder(encoder, dev) { |
771 | *encoder = save_encoders[count++]; | 769 | encoder->crtc = save_encoder_crtcs[count++]; |
772 | } | 770 | } |
773 | 771 | ||
774 | count = 0; | 772 | count = 0; |
775 | drm_for_each_connector(connector, dev) { | 773 | drm_for_each_connector(connector, dev) { |
776 | *connector = save_connectors[count++]; | 774 | connector->encoder = save_connector_encoders[count++]; |
777 | } | 775 | } |
778 | 776 | ||
779 | /* after fail drop reference on all connectors in set */ | 777 | /* after fail drop reference on all unbound connectors in set, let |
778 | * bound connectors keep their reference | ||
779 | */ | ||
780 | for (ro = 0; ro < set->num_connectors; ro++) { | 780 | for (ro = 0; ro < set->num_connectors; ro++) { |
781 | if (set->connectors[ro]->encoder) | ||
782 | continue; | ||
781 | drm_connector_unreference(set->connectors[ro]); | 783 | drm_connector_unreference(set->connectors[ro]); |
782 | } | 784 | } |
783 | 785 | ||
@@ -787,8 +789,8 @@ fail: | |||
787 | save_set.y, save_set.fb)) | 789 | save_set.y, save_set.fb)) |
788 | DRM_ERROR("failed to restore config after modeset failure\n"); | 790 | DRM_ERROR("failed to restore config after modeset failure\n"); |
789 | 791 | ||
790 | kfree(save_connectors); | 792 | kfree(save_connector_encoders); |
791 | kfree(save_encoders); | 793 | kfree(save_encoder_crtcs); |
792 | return ret; | 794 | return ret; |
793 | } | 795 | } |
794 | EXPORT_SYMBOL(drm_crtc_helper_set_config); | 796 | EXPORT_SYMBOL(drm_crtc_helper_set_config); |
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index a13edf5de2d6..6537908050d7 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
@@ -2927,11 +2927,9 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) | |||
2927 | drm_dp_port_teardown_pdt(port, port->pdt); | 2927 | drm_dp_port_teardown_pdt(port, port->pdt); |
2928 | 2928 | ||
2929 | if (!port->input && port->vcpi.vcpi > 0) { | 2929 | if (!port->input && port->vcpi.vcpi > 0) { |
2930 | if (mgr->mst_state) { | 2930 | drm_dp_mst_reset_vcpi_slots(mgr, port); |
2931 | drm_dp_mst_reset_vcpi_slots(mgr, port); | 2931 | drm_dp_update_payload_part1(mgr); |
2932 | drm_dp_update_payload_part1(mgr); | 2932 | drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); |
2933 | drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); | ||
2934 | } | ||
2935 | } | 2933 | } |
2936 | 2934 | ||
2937 | kref_put(&port->kref, drm_dp_free_mst_port); | 2935 | kref_put(&port->kref, drm_dp_free_mst_port); |
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index 522cfd447892..16353ee81651 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c | |||
@@ -225,6 +225,7 @@ struct iommu_domain *etnaviv_iommu_domain_alloc(struct etnaviv_gpu *gpu) | |||
225 | 225 | ||
226 | etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING; | 226 | etnaviv_domain->domain.type = __IOMMU_DOMAIN_PAGING; |
227 | etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops; | 227 | etnaviv_domain->domain.ops = &etnaviv_iommu_ops.ops; |
228 | etnaviv_domain->domain.pgsize_bitmap = SZ_4K; | ||
228 | etnaviv_domain->domain.geometry.aperture_start = GPU_MEM_START; | 229 | etnaviv_domain->domain.geometry.aperture_start = GPU_MEM_START; |
229 | etnaviv_domain->domain.geometry.aperture_end = GPU_MEM_START + PT_ENTRIES * SZ_4K - 1; | 230 | etnaviv_domain->domain.geometry.aperture_end = GPU_MEM_START + PT_ENTRIES * SZ_4K - 1; |
230 | 231 | ||
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/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5faacc6e548d..7c334e902266 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -3481,6 +3481,7 @@ int intel_bios_init(struct drm_i915_private *dev_priv); | |||
3481 | bool intel_bios_is_valid_vbt(const void *buf, size_t size); | 3481 | bool intel_bios_is_valid_vbt(const void *buf, size_t size); |
3482 | bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); | 3482 | bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); |
3483 | bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); | 3483 | bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); |
3484 | bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port); | ||
3484 | bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); | 3485 | bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); |
3485 | bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port); | 3486 | bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port); |
3486 | bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port); | 3487 | bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b235b6e88ead..b9022fa053d6 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -139,6 +139,11 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | |||
139 | else | 139 | else |
140 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; | 140 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; |
141 | 141 | ||
142 | panel_fixed_mode->width_mm = (dvo_timing->himage_hi << 8) | | ||
143 | dvo_timing->himage_lo; | ||
144 | panel_fixed_mode->height_mm = (dvo_timing->vimage_hi << 8) | | ||
145 | dvo_timing->vimage_lo; | ||
146 | |||
142 | /* Some VBTs have bogus h/vtotal values */ | 147 | /* Some VBTs have bogus h/vtotal values */ |
143 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | 148 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) |
144 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | 149 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; |
@@ -1187,7 +1192,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
1187 | } | 1192 | } |
1188 | if (bdb->version < 106) { | 1193 | if (bdb->version < 106) { |
1189 | expected_size = 22; | 1194 | expected_size = 22; |
1190 | } else if (bdb->version < 109) { | 1195 | } else if (bdb->version < 111) { |
1191 | expected_size = 27; | 1196 | expected_size = 27; |
1192 | } else if (bdb->version < 195) { | 1197 | } else if (bdb->version < 195) { |
1193 | BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33); | 1198 | BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33); |
@@ -1546,6 +1551,45 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin) | |||
1546 | } | 1551 | } |
1547 | 1552 | ||
1548 | /** | 1553 | /** |
1554 | * intel_bios_is_port_present - is the specified digital port present | ||
1555 | * @dev_priv: i915 device instance | ||
1556 | * @port: port to check | ||
1557 | * | ||
1558 | * Return true if the device in %port is present. | ||
1559 | */ | ||
1560 | bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port) | ||
1561 | { | ||
1562 | static const struct { | ||
1563 | u16 dp, hdmi; | ||
1564 | } port_mapping[] = { | ||
1565 | [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, | ||
1566 | [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, | ||
1567 | [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, | ||
1568 | [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, | ||
1569 | }; | ||
1570 | int i; | ||
1571 | |||
1572 | /* FIXME maybe deal with port A as well? */ | ||
1573 | if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping)) | ||
1574 | return false; | ||
1575 | |||
1576 | if (!dev_priv->vbt.child_dev_num) | ||
1577 | return false; | ||
1578 | |||
1579 | for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { | ||
1580 | const union child_device_config *p_child = | ||
1581 | &dev_priv->vbt.child_dev[i]; | ||
1582 | if ((p_child->common.dvo_port == port_mapping[port].dp || | ||
1583 | p_child->common.dvo_port == port_mapping[port].hdmi) && | ||
1584 | (p_child->common.device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING | | ||
1585 | DEVICE_TYPE_DISPLAYPORT_OUTPUT))) | ||
1586 | return true; | ||
1587 | } | ||
1588 | |||
1589 | return false; | ||
1590 | } | ||
1591 | |||
1592 | /** | ||
1549 | * intel_bios_is_port_edp - is the device in given port eDP | 1593 | * intel_bios_is_port_edp - is the device in given port eDP |
1550 | * @dev_priv: i915 device instance | 1594 | * @dev_priv: i915 device instance |
1551 | * @port: port to check | 1595 | * @port: port to check |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2113f401f0ba..56a1637c864f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -8275,12 +8275,14 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
8275 | { | 8275 | { |
8276 | struct drm_i915_private *dev_priv = dev->dev_private; | 8276 | struct drm_i915_private *dev_priv = dev->dev_private; |
8277 | struct intel_encoder *encoder; | 8277 | struct intel_encoder *encoder; |
8278 | int i; | ||
8278 | u32 val, final; | 8279 | u32 val, final; |
8279 | bool has_lvds = false; | 8280 | bool has_lvds = false; |
8280 | bool has_cpu_edp = false; | 8281 | bool has_cpu_edp = false; |
8281 | bool has_panel = false; | 8282 | bool has_panel = false; |
8282 | bool has_ck505 = false; | 8283 | bool has_ck505 = false; |
8283 | bool can_ssc = false; | 8284 | bool can_ssc = false; |
8285 | bool using_ssc_source = false; | ||
8284 | 8286 | ||
8285 | /* We need to take the global config into account */ | 8287 | /* We need to take the global config into account */ |
8286 | for_each_intel_encoder(dev, encoder) { | 8288 | for_each_intel_encoder(dev, encoder) { |
@@ -8307,8 +8309,22 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
8307 | can_ssc = true; | 8309 | can_ssc = true; |
8308 | } | 8310 | } |
8309 | 8311 | ||
8310 | DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n", | 8312 | /* Check if any DPLLs are using the SSC source */ |
8311 | has_panel, has_lvds, has_ck505); | 8313 | for (i = 0; i < dev_priv->num_shared_dpll; i++) { |
8314 | u32 temp = I915_READ(PCH_DPLL(i)); | ||
8315 | |||
8316 | if (!(temp & DPLL_VCO_ENABLE)) | ||
8317 | continue; | ||
8318 | |||
8319 | if ((temp & PLL_REF_INPUT_MASK) == | ||
8320 | PLLB_REF_INPUT_SPREADSPECTRUMIN) { | ||
8321 | using_ssc_source = true; | ||
8322 | break; | ||
8323 | } | ||
8324 | } | ||
8325 | |||
8326 | DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n", | ||
8327 | has_panel, has_lvds, has_ck505, using_ssc_source); | ||
8312 | 8328 | ||
8313 | /* Ironlake: try to setup display ref clock before DPLL | 8329 | /* Ironlake: try to setup display ref clock before DPLL |
8314 | * enabling. This is only under driver's control after | 8330 | * enabling. This is only under driver's control after |
@@ -8345,9 +8361,9 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
8345 | final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | 8361 | final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; |
8346 | } else | 8362 | } else |
8347 | final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | 8363 | final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; |
8348 | } else { | 8364 | } else if (using_ssc_source) { |
8349 | final |= DREF_SSC_SOURCE_DISABLE; | 8365 | final |= DREF_SSC_SOURCE_ENABLE; |
8350 | final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | 8366 | final |= DREF_SSC1_ENABLE; |
8351 | } | 8367 | } |
8352 | 8368 | ||
8353 | if (final == val) | 8369 | if (final == val) |
@@ -8393,7 +8409,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
8393 | POSTING_READ(PCH_DREF_CONTROL); | 8409 | POSTING_READ(PCH_DREF_CONTROL); |
8394 | udelay(200); | 8410 | udelay(200); |
8395 | } else { | 8411 | } else { |
8396 | DRM_DEBUG_KMS("Disabling SSC entirely\n"); | 8412 | DRM_DEBUG_KMS("Disabling CPU source output\n"); |
8397 | 8413 | ||
8398 | val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | 8414 | val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; |
8399 | 8415 | ||
@@ -8404,16 +8420,20 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) | |||
8404 | POSTING_READ(PCH_DREF_CONTROL); | 8420 | POSTING_READ(PCH_DREF_CONTROL); |
8405 | udelay(200); | 8421 | udelay(200); |
8406 | 8422 | ||
8407 | /* Turn off the SSC source */ | 8423 | if (!using_ssc_source) { |
8408 | val &= ~DREF_SSC_SOURCE_MASK; | 8424 | DRM_DEBUG_KMS("Disabling SSC source\n"); |
8409 | val |= DREF_SSC_SOURCE_DISABLE; | ||
8410 | 8425 | ||
8411 | /* Turn off SSC1 */ | 8426 | /* Turn off the SSC source */ |
8412 | val &= ~DREF_SSC1_ENABLE; | 8427 | val &= ~DREF_SSC_SOURCE_MASK; |
8428 | val |= DREF_SSC_SOURCE_DISABLE; | ||
8413 | 8429 | ||
8414 | I915_WRITE(PCH_DREF_CONTROL, val); | 8430 | /* Turn off SSC1 */ |
8415 | POSTING_READ(PCH_DREF_CONTROL); | 8431 | val &= ~DREF_SSC1_ENABLE; |
8416 | udelay(200); | 8432 | |
8433 | I915_WRITE(PCH_DREF_CONTROL, val); | ||
8434 | POSTING_READ(PCH_DREF_CONTROL); | ||
8435 | udelay(200); | ||
8436 | } | ||
8417 | } | 8437 | } |
8418 | 8438 | ||
8419 | BUG_ON(val != final); | 8439 | BUG_ON(val != final); |
@@ -14554,6 +14574,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
14554 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | 14574 | if (I915_READ(PCH_DP_D) & DP_DETECTED) |
14555 | intel_dp_init(dev, PCH_DP_D, PORT_D); | 14575 | intel_dp_init(dev, PCH_DP_D, PORT_D); |
14556 | } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { | 14576 | } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { |
14577 | bool has_edp, has_port; | ||
14578 | |||
14557 | /* | 14579 | /* |
14558 | * The DP_DETECTED bit is the latched state of the DDC | 14580 | * The DP_DETECTED bit is the latched state of the DDC |
14559 | * SDA pin at boot. However since eDP doesn't require DDC | 14581 | * SDA pin at boot. However since eDP doesn't require DDC |
@@ -14562,27 +14584,37 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
14562 | * Thus we can't rely on the DP_DETECTED bit alone to detect | 14584 | * Thus we can't rely on the DP_DETECTED bit alone to detect |
14563 | * eDP ports. Consult the VBT as well as DP_DETECTED to | 14585 | * eDP ports. Consult the VBT as well as DP_DETECTED to |
14564 | * detect eDP ports. | 14586 | * detect eDP ports. |
14587 | * | ||
14588 | * Sadly the straps seem to be missing sometimes even for HDMI | ||
14589 | * ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap | ||
14590 | * and VBT for the presence of the port. Additionally we can't | ||
14591 | * trust the port type the VBT declares as we've seen at least | ||
14592 | * HDMI ports that the VBT claim are DP or eDP. | ||
14565 | */ | 14593 | */ |
14566 | if (I915_READ(VLV_HDMIB) & SDVO_DETECTED && | 14594 | has_edp = intel_dp_is_edp(dev, PORT_B); |
14567 | !intel_dp_is_edp(dev, PORT_B)) | 14595 | has_port = intel_bios_is_port_present(dev_priv, PORT_B); |
14596 | if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port) | ||
14597 | has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B); | ||
14598 | if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp) | ||
14568 | intel_hdmi_init(dev, VLV_HDMIB, PORT_B); | 14599 | intel_hdmi_init(dev, VLV_HDMIB, PORT_B); |
14569 | if (I915_READ(VLV_DP_B) & DP_DETECTED || | ||
14570 | intel_dp_is_edp(dev, PORT_B)) | ||
14571 | intel_dp_init(dev, VLV_DP_B, PORT_B); | ||
14572 | 14600 | ||
14573 | if (I915_READ(VLV_HDMIC) & SDVO_DETECTED && | 14601 | has_edp = intel_dp_is_edp(dev, PORT_C); |
14574 | !intel_dp_is_edp(dev, PORT_C)) | 14602 | has_port = intel_bios_is_port_present(dev_priv, PORT_C); |
14603 | if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port) | ||
14604 | has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C); | ||
14605 | if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp) | ||
14575 | intel_hdmi_init(dev, VLV_HDMIC, PORT_C); | 14606 | intel_hdmi_init(dev, VLV_HDMIC, PORT_C); |
14576 | if (I915_READ(VLV_DP_C) & DP_DETECTED || | ||
14577 | intel_dp_is_edp(dev, PORT_C)) | ||
14578 | intel_dp_init(dev, VLV_DP_C, PORT_C); | ||
14579 | 14607 | ||
14580 | if (IS_CHERRYVIEW(dev)) { | 14608 | if (IS_CHERRYVIEW(dev)) { |
14581 | /* eDP not supported on port D, so don't check VBT */ | 14609 | /* |
14582 | if (I915_READ(CHV_HDMID) & SDVO_DETECTED) | 14610 | * eDP not supported on port D, |
14583 | intel_hdmi_init(dev, CHV_HDMID, PORT_D); | 14611 | * so no need to worry about it |
14584 | if (I915_READ(CHV_DP_D) & DP_DETECTED) | 14612 | */ |
14613 | has_port = intel_bios_is_port_present(dev_priv, PORT_D); | ||
14614 | if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port) | ||
14585 | intel_dp_init(dev, CHV_DP_D, PORT_D); | 14615 | intel_dp_init(dev, CHV_DP_D, PORT_D); |
14616 | if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port) | ||
14617 | intel_hdmi_init(dev, CHV_HDMID, PORT_D); | ||
14586 | } | 14618 | } |
14587 | 14619 | ||
14588 | intel_dsi_init(dev); | 14620 | intel_dsi_init(dev); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f192f58708c2..ffe5f8430957 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -5725,8 +5725,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
5725 | if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { | 5725 | if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) { |
5726 | fixed_mode = drm_mode_duplicate(dev, | 5726 | fixed_mode = drm_mode_duplicate(dev, |
5727 | dev_priv->vbt.lfp_lvds_vbt_mode); | 5727 | dev_priv->vbt.lfp_lvds_vbt_mode); |
5728 | if (fixed_mode) | 5728 | if (fixed_mode) { |
5729 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; | 5729 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; |
5730 | connector->display_info.width_mm = fixed_mode->width_mm; | ||
5731 | connector->display_info.height_mm = fixed_mode->height_mm; | ||
5732 | } | ||
5730 | } | 5733 | } |
5731 | mutex_unlock(&dev->mode_config.mutex); | 5734 | mutex_unlock(&dev->mode_config.mutex); |
5732 | 5735 | ||
@@ -5923,9 +5926,9 @@ fail: | |||
5923 | return false; | 5926 | return false; |
5924 | } | 5927 | } |
5925 | 5928 | ||
5926 | void | 5929 | bool intel_dp_init(struct drm_device *dev, |
5927 | intel_dp_init(struct drm_device *dev, | 5930 | i915_reg_t output_reg, |
5928 | i915_reg_t output_reg, enum port port) | 5931 | enum port port) |
5929 | { | 5932 | { |
5930 | struct drm_i915_private *dev_priv = dev->dev_private; | 5933 | struct drm_i915_private *dev_priv = dev->dev_private; |
5931 | struct intel_digital_port *intel_dig_port; | 5934 | struct intel_digital_port *intel_dig_port; |
@@ -5935,7 +5938,7 @@ intel_dp_init(struct drm_device *dev, | |||
5935 | 5938 | ||
5936 | intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); | 5939 | intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); |
5937 | if (!intel_dig_port) | 5940 | if (!intel_dig_port) |
5938 | return; | 5941 | return false; |
5939 | 5942 | ||
5940 | intel_connector = intel_connector_alloc(); | 5943 | intel_connector = intel_connector_alloc(); |
5941 | if (!intel_connector) | 5944 | if (!intel_connector) |
@@ -5992,7 +5995,7 @@ intel_dp_init(struct drm_device *dev, | |||
5992 | if (!intel_dp_init_connector(intel_dig_port, intel_connector)) | 5995 | if (!intel_dp_init_connector(intel_dig_port, intel_connector)) |
5993 | goto err_init_connector; | 5996 | goto err_init_connector; |
5994 | 5997 | ||
5995 | return; | 5998 | return true; |
5996 | 5999 | ||
5997 | err_init_connector: | 6000 | err_init_connector: |
5998 | drm_encoder_cleanup(encoder); | 6001 | drm_encoder_cleanup(encoder); |
@@ -6000,8 +6003,7 @@ err_encoder_init: | |||
6000 | kfree(intel_connector); | 6003 | kfree(intel_connector); |
6001 | err_connector_alloc: | 6004 | err_connector_alloc: |
6002 | kfree(intel_dig_port); | 6005 | kfree(intel_dig_port); |
6003 | 6006 | return false; | |
6004 | return; | ||
6005 | } | 6007 | } |
6006 | 6008 | ||
6007 | void intel_dp_mst_suspend(struct drm_device *dev) | 6009 | void intel_dp_mst_suspend(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 3ac705936b04..baf6f5584cbd 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c | |||
@@ -366,6 +366,9 @@ ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | |||
366 | DPLL_ID_PCH_PLL_B); | 366 | DPLL_ID_PCH_PLL_B); |
367 | } | 367 | } |
368 | 368 | ||
369 | if (!pll) | ||
370 | return NULL; | ||
371 | |||
369 | /* reference the pll */ | 372 | /* reference the pll */ |
370 | intel_reference_shared_dpll(pll, crtc_state); | 373 | intel_reference_shared_dpll(pll, crtc_state); |
371 | 374 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a28b4aac1e02..4a24b0067a3a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -1284,7 +1284,7 @@ void intel_csr_ucode_suspend(struct drm_i915_private *); | |||
1284 | void intel_csr_ucode_resume(struct drm_i915_private *); | 1284 | void intel_csr_ucode_resume(struct drm_i915_private *); |
1285 | 1285 | ||
1286 | /* intel_dp.c */ | 1286 | /* intel_dp.c */ |
1287 | void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port); | 1287 | bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port); |
1288 | bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, | 1288 | bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, |
1289 | struct intel_connector *intel_connector); | 1289 | struct intel_connector *intel_connector); |
1290 | void intel_dp_set_link_params(struct intel_dp *intel_dp, | 1290 | void intel_dp_set_link_params(struct intel_dp *intel_dp, |
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 366ad6c67ce4..4756ef639648 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c | |||
@@ -1545,6 +1545,9 @@ void intel_dsi_init(struct drm_device *dev) | |||
1545 | goto err; | 1545 | goto err; |
1546 | } | 1546 | } |
1547 | 1547 | ||
1548 | connector->display_info.width_mm = fixed_mode->width_mm; | ||
1549 | connector->display_info.height_mm = fixed_mode->height_mm; | ||
1550 | |||
1548 | intel_panel_init(&intel_connector->panel, fixed_mode, NULL); | 1551 | intel_panel_init(&intel_connector->panel, fixed_mode, NULL); |
1549 | 1552 | ||
1550 | intel_dsi_add_properties(intel_connector); | 1553 | intel_dsi_add_properties(intel_connector); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 2c3bd9c2573e..a8844702d11b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -2142,6 +2142,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, | |||
2142 | enum port port = intel_dig_port->port; | 2142 | enum port port = intel_dig_port->port; |
2143 | uint8_t alternate_ddc_pin; | 2143 | uint8_t alternate_ddc_pin; |
2144 | 2144 | ||
2145 | DRM_DEBUG_KMS("Adding HDMI connector on port %c\n", | ||
2146 | port_name(port)); | ||
2147 | |||
2145 | if (WARN(intel_dig_port->max_lanes < 4, | 2148 | if (WARN(intel_dig_port->max_lanes < 4, |
2146 | "Not enough lanes (%d) for HDMI on port %c\n", | 2149 | "Not enough lanes (%d) for HDMI on port %c\n", |
2147 | intel_dig_port->max_lanes, port_name(port))) | 2150 | intel_dig_port->max_lanes, port_name(port))) |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index bc53c0dd34d0..96281e628d2a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -1082,6 +1082,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
1082 | fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode); | 1082 | fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode); |
1083 | if (fixed_mode) { | 1083 | if (fixed_mode) { |
1084 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; | 1084 | fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; |
1085 | connector->display_info.width_mm = fixed_mode->width_mm; | ||
1086 | connector->display_info.height_mm = fixed_mode->height_mm; | ||
1085 | goto out; | 1087 | goto out; |
1086 | } | 1088 | } |
1087 | } | 1089 | } |
diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h index c15051de8023..44fb0b35eed3 100644 --- a/drivers/gpu/drm/i915/intel_vbt_defs.h +++ b/drivers/gpu/drm/i915/intel_vbt_defs.h | |||
@@ -403,9 +403,10 @@ struct lvds_dvo_timing { | |||
403 | u8 vsync_off:4; | 403 | u8 vsync_off:4; |
404 | u8 rsvd0:6; | 404 | u8 rsvd0:6; |
405 | u8 hsync_off_hi:2; | 405 | u8 hsync_off_hi:2; |
406 | u8 h_image; | 406 | u8 himage_lo; |
407 | u8 v_image; | 407 | u8 vimage_lo; |
408 | u8 max_hv; | 408 | u8 vimage_hi:4; |
409 | u8 himage_hi:4; | ||
409 | u8 h_border; | 410 | u8 h_border; |
410 | u8 v_border; | 411 | u8 v_border; |
411 | u8 rsvd1:3; | 412 | u8 rsvd1:3; |
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/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c index 18fab3973ce5..62ad0300cfa5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c | |||
@@ -1614,7 +1614,7 @@ nvkm_device_pci_func = { | |||
1614 | .fini = nvkm_device_pci_fini, | 1614 | .fini = nvkm_device_pci_fini, |
1615 | .resource_addr = nvkm_device_pci_resource_addr, | 1615 | .resource_addr = nvkm_device_pci_resource_addr, |
1616 | .resource_size = nvkm_device_pci_resource_size, | 1616 | .resource_size = nvkm_device_pci_resource_size, |
1617 | .cpu_coherent = !IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64), | 1617 | .cpu_coherent = !IS_ENABLED(CONFIG_ARM), |
1618 | }; | 1618 | }; |
1619 | 1619 | ||
1620 | int | 1620 | int |
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/iccsense/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c index 323c79abe468..41bd5d0f7692 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c | |||
@@ -276,6 +276,8 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev) | |||
276 | struct pwr_rail_t *r = &stbl.rail[i]; | 276 | struct pwr_rail_t *r = &stbl.rail[i]; |
277 | struct nvkm_iccsense_rail *rail; | 277 | struct nvkm_iccsense_rail *rail; |
278 | struct nvkm_iccsense_sensor *sensor; | 278 | struct nvkm_iccsense_sensor *sensor; |
279 | int (*read)(struct nvkm_iccsense *, | ||
280 | struct nvkm_iccsense_rail *); | ||
279 | 281 | ||
280 | if (!r->mode || r->resistor_mohm == 0) | 282 | if (!r->mode || r->resistor_mohm == 0) |
281 | continue; | 283 | continue; |
@@ -284,31 +286,31 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev) | |||
284 | if (!sensor) | 286 | if (!sensor) |
285 | continue; | 287 | continue; |
286 | 288 | ||
287 | rail = kmalloc(sizeof(*rail), GFP_KERNEL); | ||
288 | if (!rail) | ||
289 | return -ENOMEM; | ||
290 | |||
291 | switch (sensor->type) { | 289 | switch (sensor->type) { |
292 | case NVBIOS_EXTDEV_INA209: | 290 | case NVBIOS_EXTDEV_INA209: |
293 | if (r->rail != 0) | 291 | if (r->rail != 0) |
294 | continue; | 292 | continue; |
295 | rail->read = nvkm_iccsense_ina209_read; | 293 | read = nvkm_iccsense_ina209_read; |
296 | break; | 294 | break; |
297 | case NVBIOS_EXTDEV_INA219: | 295 | case NVBIOS_EXTDEV_INA219: |
298 | if (r->rail != 0) | 296 | if (r->rail != 0) |
299 | continue; | 297 | continue; |
300 | rail->read = nvkm_iccsense_ina219_read; | 298 | read = nvkm_iccsense_ina219_read; |
301 | break; | 299 | break; |
302 | case NVBIOS_EXTDEV_INA3221: | 300 | case NVBIOS_EXTDEV_INA3221: |
303 | if (r->rail >= 3) | 301 | if (r->rail >= 3) |
304 | continue; | 302 | continue; |
305 | rail->read = nvkm_iccsense_ina3221_read; | 303 | read = nvkm_iccsense_ina3221_read; |
306 | break; | 304 | break; |
307 | default: | 305 | default: |
308 | continue; | 306 | continue; |
309 | } | 307 | } |
310 | 308 | ||
309 | rail = kmalloc(sizeof(*rail), GFP_KERNEL); | ||
310 | if (!rail) | ||
311 | return -ENOMEM; | ||
311 | sensor->rail_mask |= 1 << r->rail; | 312 | sensor->rail_mask |= 1 << r->rail; |
313 | rail->read = read; | ||
312 | rail->sensor = sensor; | 314 | rail->sensor = sensor; |
313 | rail->idx = r->rail; | 315 | rail->idx = r->rail; |
314 | rail->mohm = r->resistor_mohm; | 316 | rail->mohm = r->resistor_mohm; |
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/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 9ed8272e54ae..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; |
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index e129245eb8a9..9255c0e1e4a7 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c | |||
@@ -120,7 +120,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) | |||
120 | 120 | ||
121 | static int hdmi_init_regulator(void) | 121 | static int hdmi_init_regulator(void) |
122 | { | 122 | { |
123 | int r; | ||
124 | struct regulator *reg; | 123 | struct regulator *reg; |
125 | 124 | ||
126 | if (hdmi.vdda_reg != NULL) | 125 | if (hdmi.vdda_reg != NULL) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2e216e2ea78c..259cd6e6d71c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -589,7 +589,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
589 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev)) | 589 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev)) |
590 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 590 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
591 | /* use frac fb div on RS780/RS880 */ | 591 | /* use frac fb div on RS780/RS880 */ |
592 | if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) | 592 | if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) |
593 | && !radeon_crtc->ss_enabled) | ||
593 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 594 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
594 | if (ASIC_IS_DCE32(rdev) && mode->clock > 165000) | 595 | if (ASIC_IS_DCE32(rdev) && mode->clock > 165000) |
595 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 596 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
@@ -626,7 +627,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
626 | if (radeon_crtc->ss.refdiv) { | 627 | if (radeon_crtc->ss.refdiv) { |
627 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; | 628 | radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; |
628 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; | 629 | radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; |
629 | if (ASIC_IS_AVIVO(rdev)) | 630 | if (rdev->family >= CHIP_RV770) |
630 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; | 631 | radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; |
631 | } | 632 | } |
632 | } | 633 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e721e6b2766e..21c44b2293bc 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
630 | /* | 630 | /* |
631 | * GPU helpers function. | 631 | * GPU helpers function. |
632 | */ | 632 | */ |
633 | |||
634 | /** | ||
635 | * radeon_device_is_virtual - check if we are running is a virtual environment | ||
636 | * | ||
637 | * Check if the asic has been passed through to a VM (all asics). | ||
638 | * Used at driver startup. | ||
639 | * Returns true if virtual or false if not. | ||
640 | */ | ||
641 | static bool radeon_device_is_virtual(void) | ||
642 | { | ||
643 | #ifdef CONFIG_X86 | ||
644 | return boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
645 | #else | ||
646 | return false; | ||
647 | #endif | ||
648 | } | ||
649 | |||
633 | /** | 650 | /** |
634 | * radeon_card_posted - check if the hw has already been initialized | 651 | * radeon_card_posted - check if the hw has already been initialized |
635 | * | 652 | * |
@@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
643 | { | 660 | { |
644 | uint32_t reg; | 661 | uint32_t reg; |
645 | 662 | ||
663 | /* for pass through, always force asic_init */ | ||
664 | if (radeon_device_is_virtual()) | ||
665 | return false; | ||
666 | |||
646 | /* required for EFI mode on macbook2,1 which uses an r5xx asic */ | 667 | /* required for EFI mode on macbook2,1 which uses an r5xx asic */ |
647 | if (efi_enabled(EFI_BOOT) && | 668 | if (efi_enabled(EFI_BOOT) && |
648 | (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) && | 669 | (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) && |
@@ -1631,7 +1652,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, | |||
1631 | radeon_agp_suspend(rdev); | 1652 | radeon_agp_suspend(rdev); |
1632 | 1653 | ||
1633 | pci_save_state(dev->pdev); | 1654 | pci_save_state(dev->pdev); |
1634 | if (freeze && rdev->family >= CHIP_R600) { | 1655 | if (freeze && rdev->family >= CHIP_CEDAR) { |
1635 | rdev->asic->asic_reset(rdev, true); | 1656 | rdev->asic->asic_reset(rdev, true); |
1636 | pci_restore_state(dev->pdev); | 1657 | pci_restore_state(dev->pdev); |
1637 | } else if (suspend) { | 1658 | } else if (suspend) { |
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 | /** |