diff options
| author | Dave Airlie <airlied@redhat.com> | 2015-08-17 00:13:53 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2015-08-17 00:13:53 -0400 |
| commit | 4eebf60b7452fbd551fd7dece855ba7825a49cbc (patch) | |
| tree | 490b4d194ba09c90e10201ab7fc084a0bda0ed27 /drivers/gpu | |
| parent | 8f9cb50789e76f3e224e8861adf650e55c747af4 (diff) | |
| parent | 2c6625cd545bdd66acff14f3394865d43920a5c7 (diff) | |
Merge tag 'v4.2-rc7' into drm-next
Linux 4.2-rc7
Backmerge master for i915 fixes
Diffstat (limited to 'drivers/gpu')
67 files changed, 833 insertions, 360 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index f3791e0d27d4..baefa635169a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -1130,6 +1130,9 @@ struct amdgpu_gfx { | |||
| 1130 | uint32_t me_feature_version; | 1130 | uint32_t me_feature_version; |
| 1131 | uint32_t ce_feature_version; | 1131 | uint32_t ce_feature_version; |
| 1132 | uint32_t pfp_feature_version; | 1132 | uint32_t pfp_feature_version; |
| 1133 | uint32_t rlc_feature_version; | ||
| 1134 | uint32_t mec_feature_version; | ||
| 1135 | uint32_t mec2_feature_version; | ||
| 1133 | struct amdgpu_ring gfx_ring[AMDGPU_MAX_GFX_RINGS]; | 1136 | struct amdgpu_ring gfx_ring[AMDGPU_MAX_GFX_RINGS]; |
| 1134 | unsigned num_gfx_rings; | 1137 | unsigned num_gfx_rings; |
| 1135 | struct amdgpu_ring compute_ring[AMDGPU_MAX_COMPUTE_RINGS]; | 1138 | struct amdgpu_ring compute_ring[AMDGPU_MAX_COMPUTE_RINGS]; |
| @@ -1614,6 +1617,9 @@ struct amdgpu_uvd { | |||
| 1614 | #define AMDGPU_MAX_VCE_HANDLES 16 | 1617 | #define AMDGPU_MAX_VCE_HANDLES 16 |
| 1615 | #define AMDGPU_VCE_FIRMWARE_OFFSET 256 | 1618 | #define AMDGPU_VCE_FIRMWARE_OFFSET 256 |
| 1616 | 1619 | ||
| 1620 | #define AMDGPU_VCE_HARVEST_VCE0 (1 << 0) | ||
| 1621 | #define AMDGPU_VCE_HARVEST_VCE1 (1 << 1) | ||
| 1622 | |||
| 1617 | struct amdgpu_vce { | 1623 | struct amdgpu_vce { |
| 1618 | struct amdgpu_bo *vcpu_bo; | 1624 | struct amdgpu_bo *vcpu_bo; |
| 1619 | uint64_t gpu_addr; | 1625 | uint64_t gpu_addr; |
| @@ -1626,6 +1632,7 @@ struct amdgpu_vce { | |||
| 1626 | const struct firmware *fw; /* VCE firmware */ | 1632 | const struct firmware *fw; /* VCE firmware */ |
| 1627 | struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; | 1633 | struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; |
| 1628 | struct amdgpu_irq_src irq; | 1634 | struct amdgpu_irq_src irq; |
| 1635 | unsigned harvest_config; | ||
| 1629 | }; | 1636 | }; |
| 1630 | 1637 | ||
| 1631 | /* | 1638 | /* |
| @@ -1635,6 +1642,7 @@ struct amdgpu_sdma { | |||
| 1635 | /* SDMA firmware */ | 1642 | /* SDMA firmware */ |
| 1636 | const struct firmware *fw; | 1643 | const struct firmware *fw; |
| 1637 | uint32_t fw_version; | 1644 | uint32_t fw_version; |
| 1645 | uint32_t feature_version; | ||
| 1638 | 1646 | ||
| 1639 | struct amdgpu_ring ring; | 1647 | struct amdgpu_ring ring; |
| 1640 | }; | 1648 | }; |
| @@ -1862,6 +1870,12 @@ typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t); | |||
| 1862 | typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t); | 1870 | typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t); |
| 1863 | typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t); | 1871 | typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t); |
| 1864 | 1872 | ||
| 1873 | struct amdgpu_ip_block_status { | ||
| 1874 | bool valid; | ||
| 1875 | bool sw; | ||
| 1876 | bool hw; | ||
| 1877 | }; | ||
| 1878 | |||
| 1865 | struct amdgpu_device { | 1879 | struct amdgpu_device { |
| 1866 | struct device *dev; | 1880 | struct device *dev; |
| 1867 | struct drm_device *ddev; | 1881 | struct drm_device *ddev; |
| @@ -2004,7 +2018,7 @@ struct amdgpu_device { | |||
| 2004 | 2018 | ||
| 2005 | const struct amdgpu_ip_block_version *ip_blocks; | 2019 | const struct amdgpu_ip_block_version *ip_blocks; |
| 2006 | int num_ip_blocks; | 2020 | int num_ip_blocks; |
| 2007 | bool *ip_block_enabled; | 2021 | struct amdgpu_ip_block_status *ip_block_status; |
| 2008 | struct mutex mn_lock; | 2022 | struct mutex mn_lock; |
| 2009 | DECLARE_HASHTABLE(mn_hash, 7); | 2023 | DECLARE_HASHTABLE(mn_hash, 7); |
| 2010 | 2024 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d79009b65867..99f158e1baff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
| @@ -1191,8 +1191,9 @@ static int amdgpu_early_init(struct amdgpu_device *adev) | |||
| 1191 | return -EINVAL; | 1191 | return -EINVAL; |
| 1192 | } | 1192 | } |
| 1193 | 1193 | ||
| 1194 | adev->ip_block_enabled = kcalloc(adev->num_ip_blocks, sizeof(bool), GFP_KERNEL); | 1194 | adev->ip_block_status = kcalloc(adev->num_ip_blocks, |
| 1195 | if (adev->ip_block_enabled == NULL) | 1195 | sizeof(struct amdgpu_ip_block_status), GFP_KERNEL); |
| 1196 | if (adev->ip_block_status == NULL) | ||
| 1196 | return -ENOMEM; | 1197 | return -ENOMEM; |
| 1197 | 1198 | ||
| 1198 | if (adev->ip_blocks == NULL) { | 1199 | if (adev->ip_blocks == NULL) { |
| @@ -1203,18 +1204,18 @@ static int amdgpu_early_init(struct amdgpu_device *adev) | |||
| 1203 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1204 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1204 | if ((amdgpu_ip_block_mask & (1 << i)) == 0) { | 1205 | if ((amdgpu_ip_block_mask & (1 << i)) == 0) { |
| 1205 | DRM_ERROR("disabled ip block: %d\n", i); | 1206 | DRM_ERROR("disabled ip block: %d\n", i); |
| 1206 | adev->ip_block_enabled[i] = false; | 1207 | adev->ip_block_status[i].valid = false; |
| 1207 | } else { | 1208 | } else { |
| 1208 | if (adev->ip_blocks[i].funcs->early_init) { | 1209 | if (adev->ip_blocks[i].funcs->early_init) { |
| 1209 | r = adev->ip_blocks[i].funcs->early_init((void *)adev); | 1210 | r = adev->ip_blocks[i].funcs->early_init((void *)adev); |
| 1210 | if (r == -ENOENT) | 1211 | if (r == -ENOENT) |
| 1211 | adev->ip_block_enabled[i] = false; | 1212 | adev->ip_block_status[i].valid = false; |
| 1212 | else if (r) | 1213 | else if (r) |
| 1213 | return r; | 1214 | return r; |
| 1214 | else | 1215 | else |
| 1215 | adev->ip_block_enabled[i] = true; | 1216 | adev->ip_block_status[i].valid = true; |
| 1216 | } else { | 1217 | } else { |
| 1217 | adev->ip_block_enabled[i] = true; | 1218 | adev->ip_block_status[i].valid = true; |
| 1218 | } | 1219 | } |
| 1219 | } | 1220 | } |
| 1220 | } | 1221 | } |
| @@ -1227,11 +1228,12 @@ static int amdgpu_init(struct amdgpu_device *adev) | |||
| 1227 | int i, r; | 1228 | int i, r; |
| 1228 | 1229 | ||
| 1229 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1230 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1230 | if (!adev->ip_block_enabled[i]) | 1231 | if (!adev->ip_block_status[i].valid) |
| 1231 | continue; | 1232 | continue; |
| 1232 | r = adev->ip_blocks[i].funcs->sw_init((void *)adev); | 1233 | r = adev->ip_blocks[i].funcs->sw_init((void *)adev); |
| 1233 | if (r) | 1234 | if (r) |
| 1234 | return r; | 1235 | return r; |
| 1236 | adev->ip_block_status[i].sw = true; | ||
| 1235 | /* need to do gmc hw init early so we can allocate gpu mem */ | 1237 | /* need to do gmc hw init early so we can allocate gpu mem */ |
| 1236 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { | 1238 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { |
| 1237 | r = amdgpu_vram_scratch_init(adev); | 1239 | r = amdgpu_vram_scratch_init(adev); |
| @@ -1243,11 +1245,12 @@ static int amdgpu_init(struct amdgpu_device *adev) | |||
| 1243 | r = amdgpu_wb_init(adev); | 1245 | r = amdgpu_wb_init(adev); |
| 1244 | if (r) | 1246 | if (r) |
| 1245 | return r; | 1247 | return r; |
| 1248 | adev->ip_block_status[i].hw = true; | ||
| 1246 | } | 1249 | } |
| 1247 | } | 1250 | } |
| 1248 | 1251 | ||
| 1249 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1252 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1250 | if (!adev->ip_block_enabled[i]) | 1253 | if (!adev->ip_block_status[i].sw) |
| 1251 | continue; | 1254 | continue; |
| 1252 | /* gmc hw init is done early */ | 1255 | /* gmc hw init is done early */ |
| 1253 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) | 1256 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) |
| @@ -1255,6 +1258,7 @@ static int amdgpu_init(struct amdgpu_device *adev) | |||
| 1255 | r = adev->ip_blocks[i].funcs->hw_init((void *)adev); | 1258 | r = adev->ip_blocks[i].funcs->hw_init((void *)adev); |
| 1256 | if (r) | 1259 | if (r) |
| 1257 | return r; | 1260 | return r; |
| 1261 | adev->ip_block_status[i].hw = true; | ||
| 1258 | } | 1262 | } |
| 1259 | 1263 | ||
| 1260 | return 0; | 1264 | return 0; |
| @@ -1265,7 +1269,7 @@ static int amdgpu_late_init(struct amdgpu_device *adev) | |||
| 1265 | int i = 0, r; | 1269 | int i = 0, r; |
| 1266 | 1270 | ||
| 1267 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1271 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1268 | if (!adev->ip_block_enabled[i]) | 1272 | if (!adev->ip_block_status[i].valid) |
| 1269 | continue; | 1273 | continue; |
| 1270 | /* enable clockgating to save power */ | 1274 | /* enable clockgating to save power */ |
| 1271 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | 1275 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, |
| @@ -1287,7 +1291,7 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
| 1287 | int i, r; | 1291 | int i, r; |
| 1288 | 1292 | ||
| 1289 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1293 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 1290 | if (!adev->ip_block_enabled[i]) | 1294 | if (!adev->ip_block_status[i].hw) |
| 1291 | continue; | 1295 | continue; |
| 1292 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { | 1296 | if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) { |
| 1293 | amdgpu_wb_fini(adev); | 1297 | amdgpu_wb_fini(adev); |
| @@ -1300,14 +1304,16 @@ static int amdgpu_fini(struct amdgpu_device *adev) | |||
| 1300 | return r; | 1304 | return r; |
| 1301 | r = adev->ip_blocks[i].funcs->hw_fini((void *)adev); | 1305 | r = adev->ip_blocks[i].funcs->hw_fini((void *)adev); |
| 1302 | /* XXX handle errors */ | 1306 | /* XXX handle errors */ |
| 1307 | adev->ip_block_status[i].hw = false; | ||
| 1303 | } | 1308 | } |
| 1304 | 1309 | ||
| 1305 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1310 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 1306 | if (!adev->ip_block_enabled[i]) | 1311 | if (!adev->ip_block_status[i].sw) |
| 1307 | continue; | 1312 | continue; |
| 1308 | r = adev->ip_blocks[i].funcs->sw_fini((void *)adev); | 1313 | r = adev->ip_blocks[i].funcs->sw_fini((void *)adev); |
| 1309 | /* XXX handle errors */ | 1314 | /* XXX handle errors */ |
| 1310 | adev->ip_block_enabled[i] = false; | 1315 | adev->ip_block_status[i].sw = false; |
| 1316 | adev->ip_block_status[i].valid = false; | ||
| 1311 | } | 1317 | } |
| 1312 | 1318 | ||
| 1313 | return 0; | 1319 | return 0; |
| @@ -1318,7 +1324,7 @@ static int amdgpu_suspend(struct amdgpu_device *adev) | |||
| 1318 | int i, r; | 1324 | int i, r; |
| 1319 | 1325 | ||
| 1320 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { | 1326 | for (i = adev->num_ip_blocks - 1; i >= 0; i--) { |
| 1321 | if (!adev->ip_block_enabled[i]) | 1327 | if (!adev->ip_block_status[i].valid) |
| 1322 | continue; | 1328 | continue; |
| 1323 | /* ungate blocks so that suspend can properly shut them down */ | 1329 | /* ungate blocks so that suspend can properly shut them down */ |
| 1324 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, | 1330 | r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev, |
| @@ -1336,7 +1342,7 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
| 1336 | int i, r; | 1342 | int i, r; |
| 1337 | 1343 | ||
| 1338 | for (i = 0; i < adev->num_ip_blocks; i++) { | 1344 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 1339 | if (!adev->ip_block_enabled[i]) | 1345 | if (!adev->ip_block_status[i].valid) |
| 1340 | continue; | 1346 | continue; |
| 1341 | r = adev->ip_blocks[i].funcs->resume(adev); | 1347 | r = adev->ip_blocks[i].funcs->resume(adev); |
| 1342 | if (r) | 1348 | if (r) |
| @@ -1582,8 +1588,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev) | |||
| 1582 | amdgpu_fence_driver_fini(adev); | 1588 | amdgpu_fence_driver_fini(adev); |
| 1583 | amdgpu_fbdev_fini(adev); | 1589 | amdgpu_fbdev_fini(adev); |
| 1584 | r = amdgpu_fini(adev); | 1590 | r = amdgpu_fini(adev); |
| 1585 | kfree(adev->ip_block_enabled); | 1591 | kfree(adev->ip_block_status); |
| 1586 | adev->ip_block_enabled = NULL; | 1592 | adev->ip_block_status = NULL; |
| 1587 | adev->accel_working = false; | 1593 | adev->accel_working = false; |
| 1588 | /* free i2c buses */ | 1594 | /* free i2c buses */ |
| 1589 | amdgpu_i2c_fini(adev); | 1595 | amdgpu_i2c_fini(adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index ae43b58c9733..4afc507820c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |||
| @@ -449,7 +449,7 @@ out: | |||
| 449 | * vital here, so they are not reported back to userspace. | 449 | * vital here, so they are not reported back to userspace. |
| 450 | */ | 450 | */ |
| 451 | static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | 451 | static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, |
| 452 | struct amdgpu_bo_va *bo_va) | 452 | struct amdgpu_bo_va *bo_va, uint32_t operation) |
| 453 | { | 453 | { |
| 454 | struct ttm_validate_buffer tv, *entry; | 454 | struct ttm_validate_buffer tv, *entry; |
| 455 | struct amdgpu_bo_list_entry *vm_bos; | 455 | struct amdgpu_bo_list_entry *vm_bos; |
| @@ -485,7 +485,9 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
| 485 | if (r) | 485 | if (r) |
| 486 | goto error_unlock; | 486 | goto error_unlock; |
| 487 | 487 | ||
| 488 | r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem); | 488 | |
| 489 | if (operation == AMDGPU_VA_OP_MAP) | ||
| 490 | r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem); | ||
| 489 | 491 | ||
| 490 | error_unlock: | 492 | error_unlock: |
| 491 | mutex_unlock(&bo_va->vm->mutex); | 493 | mutex_unlock(&bo_va->vm->mutex); |
| @@ -580,7 +582,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
| 580 | } | 582 | } |
| 581 | 583 | ||
| 582 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) | 584 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) |
| 583 | amdgpu_gem_va_update_vm(adev, bo_va); | 585 | amdgpu_gem_va_update_vm(adev, bo_va, args->operation); |
| 584 | 586 | ||
| 585 | drm_gem_object_unreference_unlocked(gobj); | 587 | drm_gem_object_unreference_unlocked(gobj); |
| 586 | return r; | 588 | return r; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 52dff75aac6f..bc0fac618a3f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
| @@ -180,16 +180,16 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, | |||
| 180 | if (vm) { | 180 | if (vm) { |
| 181 | /* do context switch */ | 181 | /* do context switch */ |
| 182 | amdgpu_vm_flush(ring, vm, ib->sync.last_vm_update); | 182 | amdgpu_vm_flush(ring, vm, ib->sync.last_vm_update); |
| 183 | } | ||
| 184 | 183 | ||
| 185 | if (vm && ring->funcs->emit_gds_switch) | 184 | if (ring->funcs->emit_gds_switch) |
| 186 | amdgpu_ring_emit_gds_switch(ring, ib->vm->ids[ring->idx].id, | 185 | amdgpu_ring_emit_gds_switch(ring, ib->vm->ids[ring->idx].id, |
| 187 | ib->gds_base, ib->gds_size, | 186 | ib->gds_base, ib->gds_size, |
| 188 | ib->gws_base, ib->gws_size, | 187 | ib->gws_base, ib->gws_size, |
| 189 | ib->oa_base, ib->oa_size); | 188 | ib->oa_base, ib->oa_size); |
| 190 | 189 | ||
| 191 | if (ring->funcs->emit_hdp_flush) | 190 | if (ring->funcs->emit_hdp_flush) |
| 192 | amdgpu_ring_emit_hdp_flush(ring); | 191 | amdgpu_ring_emit_hdp_flush(ring); |
| 192 | } | ||
| 193 | 193 | ||
| 194 | old_ctx = ring->current_ctx; | 194 | old_ctx = ring->current_ctx; |
| 195 | for (i = 0; i < num_ibs; ++i) { | 195 | for (i = 0; i < num_ibs; ++i) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 8c40a9671b9f..93000af92283 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
| @@ -242,7 +242,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 242 | 242 | ||
| 243 | for (i = 0; i < adev->num_ip_blocks; i++) { | 243 | for (i = 0; i < adev->num_ip_blocks; i++) { |
| 244 | if (adev->ip_blocks[i].type == type && | 244 | if (adev->ip_blocks[i].type == type && |
| 245 | adev->ip_block_enabled[i]) { | 245 | adev->ip_block_status[i].valid) { |
| 246 | ip.hw_ip_version_major = adev->ip_blocks[i].major; | 246 | ip.hw_ip_version_major = adev->ip_blocks[i].major; |
| 247 | ip.hw_ip_version_minor = adev->ip_blocks[i].minor; | 247 | ip.hw_ip_version_minor = adev->ip_blocks[i].minor; |
| 248 | ip.capabilities_flags = 0; | 248 | ip.capabilities_flags = 0; |
| @@ -281,7 +281,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 281 | 281 | ||
| 282 | for (i = 0; i < adev->num_ip_blocks; i++) | 282 | for (i = 0; i < adev->num_ip_blocks; i++) |
| 283 | if (adev->ip_blocks[i].type == type && | 283 | if (adev->ip_blocks[i].type == type && |
| 284 | adev->ip_block_enabled[i] && | 284 | adev->ip_block_status[i].valid && |
| 285 | count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT) | 285 | count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT) |
| 286 | count++; | 286 | count++; |
| 287 | 287 | ||
| @@ -324,16 +324,17 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 324 | break; | 324 | break; |
| 325 | case AMDGPU_INFO_FW_GFX_RLC: | 325 | case AMDGPU_INFO_FW_GFX_RLC: |
| 326 | fw_info.ver = adev->gfx.rlc_fw_version; | 326 | fw_info.ver = adev->gfx.rlc_fw_version; |
| 327 | fw_info.feature = 0; | 327 | fw_info.feature = adev->gfx.rlc_feature_version; |
| 328 | break; | 328 | break; |
| 329 | case AMDGPU_INFO_FW_GFX_MEC: | 329 | case AMDGPU_INFO_FW_GFX_MEC: |
| 330 | if (info->query_fw.index == 0) | 330 | if (info->query_fw.index == 0) { |
| 331 | fw_info.ver = adev->gfx.mec_fw_version; | 331 | fw_info.ver = adev->gfx.mec_fw_version; |
| 332 | else if (info->query_fw.index == 1) | 332 | fw_info.feature = adev->gfx.mec_feature_version; |
| 333 | } else if (info->query_fw.index == 1) { | ||
| 333 | fw_info.ver = adev->gfx.mec2_fw_version; | 334 | fw_info.ver = adev->gfx.mec2_fw_version; |
| 334 | else | 335 | fw_info.feature = adev->gfx.mec2_feature_version; |
| 336 | } else | ||
| 335 | return -EINVAL; | 337 | return -EINVAL; |
| 336 | fw_info.feature = 0; | ||
| 337 | break; | 338 | break; |
| 338 | case AMDGPU_INFO_FW_SMC: | 339 | case AMDGPU_INFO_FW_SMC: |
| 339 | fw_info.ver = adev->pm.fw_version; | 340 | fw_info.ver = adev->pm.fw_version; |
| @@ -343,7 +344,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 343 | if (info->query_fw.index >= 2) | 344 | if (info->query_fw.index >= 2) |
| 344 | return -EINVAL; | 345 | return -EINVAL; |
| 345 | fw_info.ver = adev->sdma[info->query_fw.index].fw_version; | 346 | fw_info.ver = adev->sdma[info->query_fw.index].fw_version; |
| 346 | fw_info.feature = 0; | 347 | fw_info.feature = adev->sdma[info->query_fw.index].feature_version; |
| 347 | break; | 348 | break; |
| 348 | default: | 349 | default: |
| 349 | return -EINVAL; | 350 | return -EINVAL; |
| @@ -423,7 +424,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 423 | return n ? -EFAULT : 0; | 424 | return n ? -EFAULT : 0; |
| 424 | } | 425 | } |
| 425 | case AMDGPU_INFO_DEV_INFO: { | 426 | case AMDGPU_INFO_DEV_INFO: { |
| 426 | struct drm_amdgpu_info_device dev_info; | 427 | struct drm_amdgpu_info_device dev_info = {}; |
| 427 | struct amdgpu_cu_info cu_info; | 428 | struct amdgpu_cu_info cu_info; |
| 428 | 429 | ||
| 429 | dev_info.device_id = dev->pdev->device; | 430 | dev_info.device_id = dev->pdev->device; |
| @@ -466,6 +467,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
| 466 | memcpy(&dev_info.cu_bitmap[0], &cu_info.bitmap[0], sizeof(cu_info.bitmap)); | 467 | memcpy(&dev_info.cu_bitmap[0], &cu_info.bitmap[0], sizeof(cu_info.bitmap)); |
| 467 | dev_info.vram_type = adev->mc.vram_type; | 468 | dev_info.vram_type = adev->mc.vram_type; |
| 468 | dev_info.vram_bit_width = adev->mc.vram_width; | 469 | dev_info.vram_bit_width = adev->mc.vram_width; |
| 470 | dev_info.vce_harvest_config = adev->vce.harvest_config; | ||
| 469 | 471 | ||
| 470 | return copy_to_user(out, &dev_info, | 472 | return copy_to_user(out, &dev_info, |
| 471 | min((size_t)size, sizeof(dev_info))) ? -EFAULT : 0; | 473 | min((size_t)size, sizeof(dev_info))) ? -EFAULT : 0; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 2f7a5efa21c2..f5c22556ec2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
| @@ -374,7 +374,7 @@ static int amdgpu_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[]) | |||
| 374 | unsigned height_in_mb = ALIGN(height / 16, 2); | 374 | unsigned height_in_mb = ALIGN(height / 16, 2); |
| 375 | unsigned fs_in_mb = width_in_mb * height_in_mb; | 375 | unsigned fs_in_mb = width_in_mb * height_in_mb; |
| 376 | 376 | ||
| 377 | unsigned image_size, tmp, min_dpb_size, num_dpb_buffer; | 377 | unsigned image_size, tmp, min_dpb_size, num_dpb_buffer, min_ctx_size; |
| 378 | 378 | ||
| 379 | image_size = width * height; | 379 | image_size = width * height; |
| 380 | image_size += image_size / 2; | 380 | image_size += image_size / 2; |
| @@ -466,6 +466,8 @@ static int amdgpu_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[]) | |||
| 466 | 466 | ||
| 467 | num_dpb_buffer = (le32_to_cpu(msg[59]) & 0xff) + 2; | 467 | num_dpb_buffer = (le32_to_cpu(msg[59]) & 0xff) + 2; |
| 468 | min_dpb_size = image_size * num_dpb_buffer; | 468 | min_dpb_size = image_size * num_dpb_buffer; |
| 469 | min_ctx_size = ((width + 255) / 16) * ((height + 255) / 16) | ||
| 470 | * 16 * num_dpb_buffer + 52 * 1024; | ||
| 469 | break; | 471 | break; |
| 470 | 472 | ||
| 471 | default: | 473 | default: |
| @@ -486,6 +488,7 @@ static int amdgpu_uvd_cs_msg_decode(uint32_t *msg, unsigned buf_sizes[]) | |||
| 486 | 488 | ||
| 487 | buf_sizes[0x1] = dpb_size; | 489 | buf_sizes[0x1] = dpb_size; |
| 488 | buf_sizes[0x2] = image_size; | 490 | buf_sizes[0x2] = image_size; |
| 491 | buf_sizes[0x4] = min_ctx_size; | ||
| 489 | return 0; | 492 | return 0; |
| 490 | } | 493 | } |
| 491 | 494 | ||
| @@ -628,6 +631,13 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) | |||
| 628 | return -EINVAL; | 631 | return -EINVAL; |
| 629 | } | 632 | } |
| 630 | 633 | ||
| 634 | } else if (cmd == 0x206) { | ||
| 635 | if ((end - start) < ctx->buf_sizes[4]) { | ||
| 636 | DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd, | ||
| 637 | (unsigned)(end - start), | ||
| 638 | ctx->buf_sizes[4]); | ||
| 639 | return -EINVAL; | ||
| 640 | } | ||
| 631 | } else if ((cmd != 0x100) && (cmd != 0x204)) { | 641 | } else if ((cmd != 0x100) && (cmd != 0x204)) { |
| 632 | DRM_ERROR("invalid UVD command %X!\n", cmd); | 642 | DRM_ERROR("invalid UVD command %X!\n", cmd); |
| 633 | return -EINVAL; | 643 | return -EINVAL; |
| @@ -755,9 +765,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) | |||
| 755 | struct amdgpu_uvd_cs_ctx ctx = {}; | 765 | struct amdgpu_uvd_cs_ctx ctx = {}; |
| 756 | unsigned buf_sizes[] = { | 766 | unsigned buf_sizes[] = { |
| 757 | [0x00000000] = 2048, | 767 | [0x00000000] = 2048, |
| 758 | [0x00000001] = 32 * 1024 * 1024, | 768 | [0x00000001] = 0xFFFFFFFF, |
| 759 | [0x00000002] = 2048 * 1152 * 3, | 769 | [0x00000002] = 0xFFFFFFFF, |
| 760 | [0x00000003] = 2048, | 770 | [0x00000003] = 2048, |
| 771 | [0x00000004] = 0xFFFFFFFF, | ||
| 761 | }; | 772 | }; |
| 762 | struct amdgpu_ib *ib = &parser->ibs[ib_idx]; | 773 | struct amdgpu_ib *ib = &parser->ibs[ib_idx]; |
| 763 | int r; | 774 | int r; |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index ab83cc1ca4cc..15df46c93f0a 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
| @@ -500,6 +500,7 @@ static int cik_sdma_load_microcode(struct amdgpu_device *adev) | |||
| 500 | amdgpu_ucode_print_sdma_hdr(&hdr->header); | 500 | amdgpu_ucode_print_sdma_hdr(&hdr->header); |
| 501 | fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; | 501 | fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; |
| 502 | adev->sdma[i].fw_version = le32_to_cpu(hdr->header.ucode_version); | 502 | adev->sdma[i].fw_version = le32_to_cpu(hdr->header.ucode_version); |
| 503 | adev->sdma[i].feature_version = le32_to_cpu(hdr->ucode_feature_version); | ||
| 503 | fw_data = (const __le32 *) | 504 | fw_data = (const __le32 *) |
| 504 | (adev->sdma[i].fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | 505 | (adev->sdma[i].fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); |
| 505 | WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], 0); | 506 | WREG32(mmSDMA0_UCODE_ADDR + sdma_offsets[i], 0); |
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 1a2d419cbf16..ace870afc7d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c | |||
| @@ -494,29 +494,67 @@ static void cz_dpm_fini(struct amdgpu_device *adev) | |||
| 494 | amdgpu_free_extended_power_table(adev); | 494 | amdgpu_free_extended_power_table(adev); |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | #define ixSMUSVI_NB_CURRENTVID 0xD8230044 | ||
| 498 | #define CURRENT_NB_VID_MASK 0xff000000 | ||
| 499 | #define CURRENT_NB_VID__SHIFT 24 | ||
| 500 | #define ixSMUSVI_GFX_CURRENTVID 0xD8230048 | ||
| 501 | #define CURRENT_GFX_VID_MASK 0xff000000 | ||
| 502 | #define CURRENT_GFX_VID__SHIFT 24 | ||
| 503 | |||
| 497 | static void | 504 | static void |
| 498 | cz_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, | 505 | cz_dpm_debugfs_print_current_performance_level(struct amdgpu_device *adev, |
| 499 | struct seq_file *m) | 506 | struct seq_file *m) |
| 500 | { | 507 | { |
| 508 | struct cz_power_info *pi = cz_get_pi(adev); | ||
| 501 | struct amdgpu_clock_voltage_dependency_table *table = | 509 | struct amdgpu_clock_voltage_dependency_table *table = |
| 502 | &adev->pm.dpm.dyn_state.vddc_dependency_on_sclk; | 510 | &adev->pm.dpm.dyn_state.vddc_dependency_on_sclk; |
| 503 | u32 current_index = | 511 | struct amdgpu_uvd_clock_voltage_dependency_table *uvd_table = |
| 504 | (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) & | 512 | &adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; |
| 505 | TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >> | 513 | struct amdgpu_vce_clock_voltage_dependency_table *vce_table = |
| 506 | TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT; | 514 | &adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; |
| 507 | u32 sclk, tmp; | 515 | u32 sclk_index = REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX), |
| 508 | u16 vddc; | 516 | TARGET_AND_CURRENT_PROFILE_INDEX, CURR_SCLK_INDEX); |
| 509 | 517 | u32 uvd_index = REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2), | |
| 510 | if (current_index >= NUM_SCLK_LEVELS) { | 518 | TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_UVD_INDEX); |
| 511 | seq_printf(m, "invalid dpm profile %d\n", current_index); | 519 | u32 vce_index = REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2), |
| 520 | TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_VCE_INDEX); | ||
| 521 | u32 sclk, vclk, dclk, ecclk, tmp; | ||
| 522 | u16 vddnb, vddgfx; | ||
| 523 | |||
| 524 | if (sclk_index >= NUM_SCLK_LEVELS) { | ||
| 525 | seq_printf(m, "invalid sclk dpm profile %d\n", sclk_index); | ||
| 512 | } else { | 526 | } else { |
| 513 | sclk = table->entries[current_index].clk; | 527 | sclk = table->entries[sclk_index].clk; |
| 514 | tmp = (RREG32_SMC(ixSMU_VOLTAGE_STATUS) & | 528 | seq_printf(m, "%u sclk: %u\n", sclk_index, sclk); |
| 515 | SMU_VOLTAGE_STATUS__SMU_VOLTAGE_CURRENT_LEVEL_MASK) >> | 529 | } |
| 516 | SMU_VOLTAGE_STATUS__SMU_VOLTAGE_CURRENT_LEVEL__SHIFT; | 530 | |
| 517 | vddc = cz_convert_8bit_index_to_voltage(adev, (u16)tmp); | 531 | tmp = (RREG32_SMC(ixSMUSVI_NB_CURRENTVID) & |
| 518 | seq_printf(m, "power level %d sclk: %u vddc: %u\n", | 532 | CURRENT_NB_VID_MASK) >> CURRENT_NB_VID__SHIFT; |
| 519 | current_index, sclk, vddc); | 533 | vddnb = cz_convert_8bit_index_to_voltage(adev, (u16)tmp); |
| 534 | tmp = (RREG32_SMC(ixSMUSVI_GFX_CURRENTVID) & | ||
| 535 | CURRENT_GFX_VID_MASK) >> CURRENT_GFX_VID__SHIFT; | ||
| 536 | vddgfx = cz_convert_8bit_index_to_voltage(adev, (u16)tmp); | ||
| 537 | seq_printf(m, "vddnb: %u vddgfx: %u\n", vddnb, vddgfx); | ||
| 538 | |||
| 539 | seq_printf(m, "uvd %sabled\n", pi->uvd_power_gated ? "dis" : "en"); | ||
| 540 | if (!pi->uvd_power_gated) { | ||
| 541 | if (uvd_index >= CZ_MAX_HARDWARE_POWERLEVELS) { | ||
| 542 | seq_printf(m, "invalid uvd dpm level %d\n", uvd_index); | ||
| 543 | } else { | ||
| 544 | vclk = uvd_table->entries[uvd_index].vclk; | ||
| 545 | dclk = uvd_table->entries[uvd_index].dclk; | ||
| 546 | seq_printf(m, "%u uvd vclk: %u dclk: %u\n", uvd_index, vclk, dclk); | ||
| 547 | } | ||
| 548 | } | ||
| 549 | |||
| 550 | seq_printf(m, "vce %sabled\n", pi->vce_power_gated ? "dis" : "en"); | ||
| 551 | if (!pi->vce_power_gated) { | ||
| 552 | if (vce_index >= CZ_MAX_HARDWARE_POWERLEVELS) { | ||
| 553 | seq_printf(m, "invalid vce dpm level %d\n", vce_index); | ||
| 554 | } else { | ||
| 555 | ecclk = vce_table->entries[vce_index].ecclk; | ||
| 556 | seq_printf(m, "%u vce ecclk: %u\n", vce_index, ecclk); | ||
| 557 | } | ||
| 520 | } | 558 | } |
| 521 | } | 559 | } |
| 522 | 560 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 6e77964f1b64..e70a26f587a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | |||
| @@ -2632,6 +2632,7 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2632 | struct drm_device *dev = crtc->dev; | 2632 | struct drm_device *dev = crtc->dev; |
| 2633 | struct amdgpu_device *adev = dev->dev_private; | 2633 | struct amdgpu_device *adev = dev->dev_private; |
| 2634 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2634 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
| 2635 | unsigned type; | ||
| 2635 | 2636 | ||
| 2636 | switch (mode) { | 2637 | switch (mode) { |
| 2637 | case DRM_MODE_DPMS_ON: | 2638 | case DRM_MODE_DPMS_ON: |
| @@ -2640,6 +2641,9 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2640 | dce_v10_0_vga_enable(crtc, true); | 2641 | dce_v10_0_vga_enable(crtc, true); |
| 2641 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); | 2642 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); |
| 2642 | dce_v10_0_vga_enable(crtc, false); | 2643 | dce_v10_0_vga_enable(crtc, false); |
| 2644 | /* Make sure VBLANK interrupt is still enabled */ | ||
| 2645 | type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); | ||
| 2646 | amdgpu_irq_update(adev, &adev->crtc_irq, type); | ||
| 2643 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); | 2647 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); |
| 2644 | dce_v10_0_crtc_load_lut(crtc); | 2648 | dce_v10_0_crtc_load_lut(crtc); |
| 2645 | break; | 2649 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 7f7abb0e0be5..dcb402ee048a 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | |||
| @@ -2631,6 +2631,7 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2631 | struct drm_device *dev = crtc->dev; | 2631 | struct drm_device *dev = crtc->dev; |
| 2632 | struct amdgpu_device *adev = dev->dev_private; | 2632 | struct amdgpu_device *adev = dev->dev_private; |
| 2633 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); | 2633 | struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); |
| 2634 | unsigned type; | ||
| 2634 | 2635 | ||
| 2635 | switch (mode) { | 2636 | switch (mode) { |
| 2636 | case DRM_MODE_DPMS_ON: | 2637 | case DRM_MODE_DPMS_ON: |
| @@ -2639,6 +2640,9 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2639 | dce_v11_0_vga_enable(crtc, true); | 2640 | dce_v11_0_vga_enable(crtc, true); |
| 2640 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); | 2641 | amdgpu_atombios_crtc_blank(crtc, ATOM_DISABLE); |
| 2641 | dce_v11_0_vga_enable(crtc, false); | 2642 | dce_v11_0_vga_enable(crtc, false); |
| 2643 | /* Make sure VBLANK interrupt is still enabled */ | ||
| 2644 | type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); | ||
| 2645 | amdgpu_irq_update(adev, &adev->crtc_irq, type); | ||
| 2642 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); | 2646 | drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); |
| 2643 | dce_v11_0_crtc_load_lut(crtc); | 2647 | dce_v11_0_crtc_load_lut(crtc); |
| 2644 | break; | 2648 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 2c188fb9fd22..0d8bf2cb1956 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
| @@ -2561,7 +2561,7 @@ static bool gfx_v7_0_ring_emit_semaphore(struct amdgpu_ring *ring, | |||
| 2561 | * sheduling on the ring. This function schedules the IB | 2561 | * sheduling on the ring. This function schedules the IB |
| 2562 | * on the gfx ring for execution by the GPU. | 2562 | * on the gfx ring for execution by the GPU. |
| 2563 | */ | 2563 | */ |
| 2564 | static void gfx_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | 2564 | static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, |
| 2565 | struct amdgpu_ib *ib) | 2565 | struct amdgpu_ib *ib) |
| 2566 | { | 2566 | { |
| 2567 | bool need_ctx_switch = ring->current_ctx != ib->ctx; | 2567 | bool need_ctx_switch = ring->current_ctx != ib->ctx; |
| @@ -2569,15 +2569,10 @@ static void gfx_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
| 2569 | u32 next_rptr = ring->wptr + 5; | 2569 | u32 next_rptr = ring->wptr + 5; |
| 2570 | 2570 | ||
| 2571 | /* drop the CE preamble IB for the same context */ | 2571 | /* drop the CE preamble IB for the same context */ |
| 2572 | if ((ring->type == AMDGPU_RING_TYPE_GFX) && | 2572 | if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && !need_ctx_switch) |
| 2573 | (ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && | ||
| 2574 | !need_ctx_switch) | ||
| 2575 | return; | 2573 | return; |
| 2576 | 2574 | ||
| 2577 | if (ring->type == AMDGPU_RING_TYPE_COMPUTE) | 2575 | if (need_ctx_switch) |
| 2578 | control |= INDIRECT_BUFFER_VALID; | ||
| 2579 | |||
| 2580 | if (need_ctx_switch && ring->type == AMDGPU_RING_TYPE_GFX) | ||
| 2581 | next_rptr += 2; | 2576 | next_rptr += 2; |
| 2582 | 2577 | ||
| 2583 | next_rptr += 4; | 2578 | next_rptr += 4; |
| @@ -2588,7 +2583,7 @@ static void gfx_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
| 2588 | amdgpu_ring_write(ring, next_rptr); | 2583 | amdgpu_ring_write(ring, next_rptr); |
| 2589 | 2584 | ||
| 2590 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ | 2585 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ |
| 2591 | if (need_ctx_switch && ring->type == AMDGPU_RING_TYPE_GFX) { | 2586 | if (need_ctx_switch) { |
| 2592 | amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); | 2587 | amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); |
| 2593 | amdgpu_ring_write(ring, 0); | 2588 | amdgpu_ring_write(ring, 0); |
| 2594 | } | 2589 | } |
| @@ -2611,6 +2606,35 @@ static void gfx_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
| 2611 | amdgpu_ring_write(ring, control); | 2606 | amdgpu_ring_write(ring, control); |
| 2612 | } | 2607 | } |
| 2613 | 2608 | ||
| 2609 | static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring, | ||
| 2610 | struct amdgpu_ib *ib) | ||
| 2611 | { | ||
| 2612 | u32 header, control = 0; | ||
| 2613 | u32 next_rptr = ring->wptr + 5; | ||
| 2614 | |||
| 2615 | control |= INDIRECT_BUFFER_VALID; | ||
| 2616 | next_rptr += 4; | ||
| 2617 | amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
| 2618 | amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM); | ||
| 2619 | amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
| 2620 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
| 2621 | amdgpu_ring_write(ring, next_rptr); | ||
| 2622 | |||
| 2623 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); | ||
| 2624 | |||
| 2625 | control |= ib->length_dw | | ||
| 2626 | (ib->vm ? (ib->vm->ids[ring->idx].id << 24) : 0); | ||
| 2627 | |||
| 2628 | amdgpu_ring_write(ring, header); | ||
| 2629 | amdgpu_ring_write(ring, | ||
| 2630 | #ifdef __BIG_ENDIAN | ||
| 2631 | (2 << 0) | | ||
| 2632 | #endif | ||
| 2633 | (ib->gpu_addr & 0xFFFFFFFC)); | ||
| 2634 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); | ||
| 2635 | amdgpu_ring_write(ring, control); | ||
| 2636 | } | ||
| 2637 | |||
| 2614 | /** | 2638 | /** |
| 2615 | * gfx_v7_0_ring_test_ib - basic ring IB test | 2639 | * gfx_v7_0_ring_test_ib - basic ring IB test |
| 2616 | * | 2640 | * |
| @@ -3056,6 +3080,8 @@ static int gfx_v7_0_cp_compute_load_microcode(struct amdgpu_device *adev) | |||
| 3056 | mec_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | 3080 | mec_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; |
| 3057 | amdgpu_ucode_print_gfx_hdr(&mec_hdr->header); | 3081 | amdgpu_ucode_print_gfx_hdr(&mec_hdr->header); |
| 3058 | adev->gfx.mec_fw_version = le32_to_cpu(mec_hdr->header.ucode_version); | 3082 | adev->gfx.mec_fw_version = le32_to_cpu(mec_hdr->header.ucode_version); |
| 3083 | adev->gfx.mec_feature_version = le32_to_cpu( | ||
| 3084 | mec_hdr->ucode_feature_version); | ||
| 3059 | 3085 | ||
| 3060 | gfx_v7_0_cp_compute_enable(adev, false); | 3086 | gfx_v7_0_cp_compute_enable(adev, false); |
| 3061 | 3087 | ||
| @@ -3078,6 +3104,8 @@ static int gfx_v7_0_cp_compute_load_microcode(struct amdgpu_device *adev) | |||
| 3078 | mec2_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; | 3104 | mec2_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; |
| 3079 | amdgpu_ucode_print_gfx_hdr(&mec2_hdr->header); | 3105 | amdgpu_ucode_print_gfx_hdr(&mec2_hdr->header); |
| 3080 | adev->gfx.mec2_fw_version = le32_to_cpu(mec2_hdr->header.ucode_version); | 3106 | adev->gfx.mec2_fw_version = le32_to_cpu(mec2_hdr->header.ucode_version); |
| 3107 | adev->gfx.mec2_feature_version = le32_to_cpu( | ||
| 3108 | mec2_hdr->ucode_feature_version); | ||
| 3081 | 3109 | ||
| 3082 | /* MEC2 */ | 3110 | /* MEC2 */ |
| 3083 | fw_data = (const __le32 *) | 3111 | fw_data = (const __le32 *) |
| @@ -4042,6 +4070,8 @@ static int gfx_v7_0_rlc_resume(struct amdgpu_device *adev) | |||
| 4042 | hdr = (const struct rlc_firmware_header_v1_0 *)adev->gfx.rlc_fw->data; | 4070 | hdr = (const struct rlc_firmware_header_v1_0 *)adev->gfx.rlc_fw->data; |
| 4043 | amdgpu_ucode_print_rlc_hdr(&hdr->header); | 4071 | amdgpu_ucode_print_rlc_hdr(&hdr->header); |
| 4044 | adev->gfx.rlc_fw_version = le32_to_cpu(hdr->header.ucode_version); | 4072 | adev->gfx.rlc_fw_version = le32_to_cpu(hdr->header.ucode_version); |
| 4073 | adev->gfx.rlc_feature_version = le32_to_cpu( | ||
| 4074 | hdr->ucode_feature_version); | ||
| 4045 | 4075 | ||
| 4046 | gfx_v7_0_rlc_stop(adev); | 4076 | gfx_v7_0_rlc_stop(adev); |
| 4047 | 4077 | ||
| @@ -5098,7 +5128,7 @@ static void gfx_v7_0_print_status(void *handle) | |||
| 5098 | dev_info(adev->dev, " CP_HPD_EOP_CONTROL=0x%08X\n", | 5128 | dev_info(adev->dev, " CP_HPD_EOP_CONTROL=0x%08X\n", |
| 5099 | RREG32(mmCP_HPD_EOP_CONTROL)); | 5129 | RREG32(mmCP_HPD_EOP_CONTROL)); |
| 5100 | 5130 | ||
| 5101 | for (queue = 0; queue < 8; i++) { | 5131 | for (queue = 0; queue < 8; queue++) { |
| 5102 | cik_srbm_select(adev, me, pipe, queue, 0); | 5132 | cik_srbm_select(adev, me, pipe, queue, 0); |
| 5103 | dev_info(adev->dev, " queue: %d\n", queue); | 5133 | dev_info(adev->dev, " queue: %d\n", queue); |
| 5104 | dev_info(adev->dev, " CP_PQ_WPTR_POLL_CNTL=0x%08X\n", | 5134 | dev_info(adev->dev, " CP_PQ_WPTR_POLL_CNTL=0x%08X\n", |
| @@ -5555,7 +5585,7 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_gfx = { | |||
| 5555 | .get_wptr = gfx_v7_0_ring_get_wptr_gfx, | 5585 | .get_wptr = gfx_v7_0_ring_get_wptr_gfx, |
| 5556 | .set_wptr = gfx_v7_0_ring_set_wptr_gfx, | 5586 | .set_wptr = gfx_v7_0_ring_set_wptr_gfx, |
| 5557 | .parse_cs = NULL, | 5587 | .parse_cs = NULL, |
| 5558 | .emit_ib = gfx_v7_0_ring_emit_ib, | 5588 | .emit_ib = gfx_v7_0_ring_emit_ib_gfx, |
| 5559 | .emit_fence = gfx_v7_0_ring_emit_fence_gfx, | 5589 | .emit_fence = gfx_v7_0_ring_emit_fence_gfx, |
| 5560 | .emit_semaphore = gfx_v7_0_ring_emit_semaphore, | 5590 | .emit_semaphore = gfx_v7_0_ring_emit_semaphore, |
| 5561 | .emit_vm_flush = gfx_v7_0_ring_emit_vm_flush, | 5591 | .emit_vm_flush = gfx_v7_0_ring_emit_vm_flush, |
| @@ -5571,7 +5601,7 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_compute = { | |||
| 5571 | .get_wptr = gfx_v7_0_ring_get_wptr_compute, | 5601 | .get_wptr = gfx_v7_0_ring_get_wptr_compute, |
| 5572 | .set_wptr = gfx_v7_0_ring_set_wptr_compute, | 5602 | .set_wptr = gfx_v7_0_ring_set_wptr_compute, |
| 5573 | .parse_cs = NULL, | 5603 | .parse_cs = NULL, |
| 5574 | .emit_ib = gfx_v7_0_ring_emit_ib, | 5604 | .emit_ib = gfx_v7_0_ring_emit_ib_compute, |
| 5575 | .emit_fence = gfx_v7_0_ring_emit_fence_compute, | 5605 | .emit_fence = gfx_v7_0_ring_emit_fence_compute, |
| 5576 | .emit_semaphore = gfx_v7_0_ring_emit_semaphore, | 5606 | .emit_semaphore = gfx_v7_0_ring_emit_semaphore, |
| 5577 | .emit_vm_flush = gfx_v7_0_ring_emit_vm_flush, | 5607 | .emit_vm_flush = gfx_v7_0_ring_emit_vm_flush, |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 1c7c992dea37..20e2cfd521d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
| @@ -587,6 +587,7 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
| 587 | int err; | 587 | int err; |
| 588 | struct amdgpu_firmware_info *info = NULL; | 588 | struct amdgpu_firmware_info *info = NULL; |
| 589 | const struct common_firmware_header *header = NULL; | 589 | const struct common_firmware_header *header = NULL; |
| 590 | const struct gfx_firmware_header_v1_0 *cp_hdr; | ||
| 590 | 591 | ||
| 591 | DRM_DEBUG("\n"); | 592 | DRM_DEBUG("\n"); |
| 592 | 593 | ||
| @@ -611,6 +612,9 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
| 611 | err = amdgpu_ucode_validate(adev->gfx.pfp_fw); | 612 | err = amdgpu_ucode_validate(adev->gfx.pfp_fw); |
| 612 | if (err) | 613 | if (err) |
| 613 | goto out; | 614 | goto out; |
| 615 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.pfp_fw->data; | ||
| 616 | adev->gfx.pfp_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); | ||
| 617 | adev->gfx.pfp_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); | ||
| 614 | 618 | ||
| 615 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); | 619 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_me.bin", chip_name); |
| 616 | err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); | 620 | err = request_firmware(&adev->gfx.me_fw, fw_name, adev->dev); |
| @@ -619,6 +623,9 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
| 619 | err = amdgpu_ucode_validate(adev->gfx.me_fw); | 623 | err = amdgpu_ucode_validate(adev->gfx.me_fw); |
| 620 | if (err) | 624 | if (err) |
| 621 | goto out; | 625 | goto out; |
| 626 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.me_fw->data; | ||
| 627 | adev->gfx.me_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); | ||
| 628 | adev->gfx.me_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); | ||
| 622 | 629 | ||
| 623 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); | 630 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ce.bin", chip_name); |
| 624 | err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); | 631 | err = request_firmware(&adev->gfx.ce_fw, fw_name, adev->dev); |
| @@ -627,12 +634,18 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
| 627 | err = amdgpu_ucode_validate(adev->gfx.ce_fw); | 634 | err = amdgpu_ucode_validate(adev->gfx.ce_fw); |
| 628 | if (err) | 635 | if (err) |
| 629 | goto out; | 636 | goto out; |
| 637 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.ce_fw->data; | ||
| 638 | adev->gfx.ce_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); | ||
| 639 | adev->gfx.ce_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); | ||
| 630 | 640 | ||
| 631 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); | 641 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", chip_name); |
| 632 | err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev); | 642 | err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev); |
| 633 | if (err) | 643 | if (err) |
| 634 | goto out; | 644 | goto out; |
| 635 | err = amdgpu_ucode_validate(adev->gfx.rlc_fw); | 645 | err = amdgpu_ucode_validate(adev->gfx.rlc_fw); |
| 646 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.rlc_fw->data; | ||
| 647 | adev->gfx.rlc_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); | ||
| 648 | adev->gfx.rlc_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); | ||
| 636 | 649 | ||
| 637 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); | 650 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name); |
| 638 | err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); | 651 | err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev); |
| @@ -641,6 +654,9 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
| 641 | err = amdgpu_ucode_validate(adev->gfx.mec_fw); | 654 | err = amdgpu_ucode_validate(adev->gfx.mec_fw); |
| 642 | if (err) | 655 | if (err) |
| 643 | goto out; | 656 | goto out; |
| 657 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | ||
| 658 | adev->gfx.mec_fw_version = le32_to_cpu(cp_hdr->header.ucode_version); | ||
| 659 | adev->gfx.mec_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version); | ||
| 644 | 660 | ||
| 645 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); | 661 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec2.bin", chip_name); |
| 646 | err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); | 662 | err = request_firmware(&adev->gfx.mec2_fw, fw_name, adev->dev); |
| @@ -648,6 +664,12 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev) | |||
| 648 | err = amdgpu_ucode_validate(adev->gfx.mec2_fw); | 664 | err = amdgpu_ucode_validate(adev->gfx.mec2_fw); |
| 649 | if (err) | 665 | if (err) |
| 650 | goto out; | 666 | goto out; |
| 667 | cp_hdr = (const struct gfx_firmware_header_v1_0 *) | ||
| 668 | adev->gfx.mec2_fw->data; | ||
| 669 | adev->gfx.mec2_fw_version = le32_to_cpu( | ||
| 670 | cp_hdr->header.ucode_version); | ||
| 671 | adev->gfx.mec2_feature_version = le32_to_cpu( | ||
| 672 | cp_hdr->ucode_feature_version); | ||
| 651 | } else { | 673 | } else { |
| 652 | err = 0; | 674 | err = 0; |
| 653 | adev->gfx.mec2_fw = NULL; | 675 | adev->gfx.mec2_fw = NULL; |
| @@ -1983,6 +2005,7 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev) | |||
| 1983 | adev->gfx.config.max_shader_engines = 1; | 2005 | adev->gfx.config.max_shader_engines = 1; |
| 1984 | adev->gfx.config.max_tile_pipes = 2; | 2006 | adev->gfx.config.max_tile_pipes = 2; |
| 1985 | adev->gfx.config.max_sh_per_se = 1; | 2007 | adev->gfx.config.max_sh_per_se = 1; |
| 2008 | adev->gfx.config.max_backends_per_se = 2; | ||
| 1986 | 2009 | ||
| 1987 | switch (adev->pdev->revision) { | 2010 | switch (adev->pdev->revision) { |
| 1988 | case 0xc4: | 2011 | case 0xc4: |
| @@ -1991,7 +2014,6 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev) | |||
| 1991 | case 0xcc: | 2014 | case 0xcc: |
| 1992 | /* B10 */ | 2015 | /* B10 */ |
| 1993 | adev->gfx.config.max_cu_per_sh = 8; | 2016 | adev->gfx.config.max_cu_per_sh = 8; |
| 1994 | adev->gfx.config.max_backends_per_se = 2; | ||
| 1995 | break; | 2017 | break; |
| 1996 | case 0xc5: | 2018 | case 0xc5: |
| 1997 | case 0x81: | 2019 | case 0x81: |
| @@ -2000,14 +2022,12 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev) | |||
| 2000 | case 0xcd: | 2022 | case 0xcd: |
| 2001 | /* B8 */ | 2023 | /* B8 */ |
| 2002 | adev->gfx.config.max_cu_per_sh = 6; | 2024 | adev->gfx.config.max_cu_per_sh = 6; |
| 2003 | adev->gfx.config.max_backends_per_se = 2; | ||
| 2004 | break; | 2025 | break; |
| 2005 | case 0xc6: | 2026 | case 0xc6: |
| 2006 | case 0xca: | 2027 | case 0xca: |
| 2007 | case 0xce: | 2028 | case 0xce: |
| 2008 | /* B6 */ | 2029 | /* B6 */ |
| 2009 | adev->gfx.config.max_cu_per_sh = 6; | 2030 | adev->gfx.config.max_cu_per_sh = 6; |
| 2010 | adev->gfx.config.max_backends_per_se = 2; | ||
| 2011 | break; | 2031 | break; |
| 2012 | case 0xc7: | 2032 | case 0xc7: |
| 2013 | case 0x87: | 2033 | case 0x87: |
| @@ -2015,7 +2035,6 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev) | |||
| 2015 | default: | 2035 | default: |
| 2016 | /* B4 */ | 2036 | /* B4 */ |
| 2017 | adev->gfx.config.max_cu_per_sh = 4; | 2037 | adev->gfx.config.max_cu_per_sh = 4; |
| 2018 | adev->gfx.config.max_backends_per_se = 1; | ||
| 2019 | break; | 2038 | break; |
| 2020 | } | 2039 | } |
| 2021 | 2040 | ||
| @@ -2275,7 +2294,6 @@ static int gfx_v8_0_rlc_load_microcode(struct amdgpu_device *adev) | |||
| 2275 | 2294 | ||
| 2276 | hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data; | 2295 | hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data; |
| 2277 | amdgpu_ucode_print_rlc_hdr(&hdr->header); | 2296 | amdgpu_ucode_print_rlc_hdr(&hdr->header); |
| 2278 | adev->gfx.rlc_fw_version = le32_to_cpu(hdr->header.ucode_version); | ||
| 2279 | 2297 | ||
| 2280 | fw_data = (const __le32 *)(adev->gfx.rlc_fw->data + | 2298 | fw_data = (const __le32 *)(adev->gfx.rlc_fw->data + |
| 2281 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | 2299 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); |
| @@ -2361,12 +2379,6 @@ static int gfx_v8_0_cp_gfx_load_microcode(struct amdgpu_device *adev) | |||
| 2361 | amdgpu_ucode_print_gfx_hdr(&pfp_hdr->header); | 2379 | amdgpu_ucode_print_gfx_hdr(&pfp_hdr->header); |
| 2362 | amdgpu_ucode_print_gfx_hdr(&ce_hdr->header); | 2380 | amdgpu_ucode_print_gfx_hdr(&ce_hdr->header); |
| 2363 | amdgpu_ucode_print_gfx_hdr(&me_hdr->header); | 2381 | amdgpu_ucode_print_gfx_hdr(&me_hdr->header); |
| 2364 | adev->gfx.pfp_fw_version = le32_to_cpu(pfp_hdr->header.ucode_version); | ||
| 2365 | adev->gfx.ce_fw_version = le32_to_cpu(ce_hdr->header.ucode_version); | ||
| 2366 | adev->gfx.me_fw_version = le32_to_cpu(me_hdr->header.ucode_version); | ||
| 2367 | adev->gfx.me_feature_version = le32_to_cpu(me_hdr->ucode_feature_version); | ||
| 2368 | adev->gfx.ce_feature_version = le32_to_cpu(ce_hdr->ucode_feature_version); | ||
| 2369 | adev->gfx.pfp_feature_version = le32_to_cpu(pfp_hdr->ucode_feature_version); | ||
| 2370 | 2382 | ||
| 2371 | gfx_v8_0_cp_gfx_enable(adev, false); | 2383 | gfx_v8_0_cp_gfx_enable(adev, false); |
| 2372 | 2384 | ||
| @@ -2622,7 +2634,6 @@ static int gfx_v8_0_cp_compute_load_microcode(struct amdgpu_device *adev) | |||
| 2622 | 2634 | ||
| 2623 | mec_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; | 2635 | mec_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data; |
| 2624 | amdgpu_ucode_print_gfx_hdr(&mec_hdr->header); | 2636 | amdgpu_ucode_print_gfx_hdr(&mec_hdr->header); |
| 2625 | adev->gfx.mec_fw_version = le32_to_cpu(mec_hdr->header.ucode_version); | ||
| 2626 | 2637 | ||
| 2627 | fw_data = (const __le32 *) | 2638 | fw_data = (const __le32 *) |
| 2628 | (adev->gfx.mec_fw->data + | 2639 | (adev->gfx.mec_fw->data + |
| @@ -2641,7 +2652,6 @@ static int gfx_v8_0_cp_compute_load_microcode(struct amdgpu_device *adev) | |||
| 2641 | 2652 | ||
| 2642 | mec2_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; | 2653 | mec2_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec2_fw->data; |
| 2643 | amdgpu_ucode_print_gfx_hdr(&mec2_hdr->header); | 2654 | amdgpu_ucode_print_gfx_hdr(&mec2_hdr->header); |
| 2644 | adev->gfx.mec2_fw_version = le32_to_cpu(mec2_hdr->header.ucode_version); | ||
| 2645 | 2655 | ||
| 2646 | fw_data = (const __le32 *) | 2656 | fw_data = (const __le32 *) |
| 2647 | (adev->gfx.mec2_fw->data + | 2657 | (adev->gfx.mec2_fw->data + |
| @@ -3125,7 +3135,7 @@ static int gfx_v8_0_cp_compute_resume(struct amdgpu_device *adev) | |||
| 3125 | WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER, | 3135 | WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER, |
| 3126 | AMDGPU_DOORBELL_KIQ << 2); | 3136 | AMDGPU_DOORBELL_KIQ << 2); |
| 3127 | WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER, | 3137 | WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER, |
| 3128 | 0x7FFFF << 2); | 3138 | AMDGPU_DOORBELL_MEC_RING7 << 2); |
| 3129 | } | 3139 | } |
| 3130 | tmp = RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL); | 3140 | tmp = RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL); |
| 3131 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, | 3141 | tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, |
| @@ -3753,7 +3763,7 @@ static void gfx_v8_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) | |||
| 3753 | amdgpu_ring_write(ring, 0x20); /* poll interval */ | 3763 | amdgpu_ring_write(ring, 0x20); /* poll interval */ |
| 3754 | } | 3764 | } |
| 3755 | 3765 | ||
| 3756 | static void gfx_v8_0_ring_emit_ib(struct amdgpu_ring *ring, | 3766 | static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, |
| 3757 | struct amdgpu_ib *ib) | 3767 | struct amdgpu_ib *ib) |
| 3758 | { | 3768 | { |
| 3759 | bool need_ctx_switch = ring->current_ctx != ib->ctx; | 3769 | bool need_ctx_switch = ring->current_ctx != ib->ctx; |
| @@ -3761,15 +3771,10 @@ static void gfx_v8_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
| 3761 | u32 next_rptr = ring->wptr + 5; | 3771 | u32 next_rptr = ring->wptr + 5; |
| 3762 | 3772 | ||
| 3763 | /* drop the CE preamble IB for the same context */ | 3773 | /* drop the CE preamble IB for the same context */ |
| 3764 | if ((ring->type == AMDGPU_RING_TYPE_GFX) && | 3774 | if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && !need_ctx_switch) |
| 3765 | (ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && | ||
| 3766 | !need_ctx_switch) | ||
| 3767 | return; | 3775 | return; |
| 3768 | 3776 | ||
| 3769 | if (ring->type == AMDGPU_RING_TYPE_COMPUTE) | 3777 | if (need_ctx_switch) |
| 3770 | control |= INDIRECT_BUFFER_VALID; | ||
| 3771 | |||
| 3772 | if (need_ctx_switch && ring->type == AMDGPU_RING_TYPE_GFX) | ||
| 3773 | next_rptr += 2; | 3778 | next_rptr += 2; |
| 3774 | 3779 | ||
| 3775 | next_rptr += 4; | 3780 | next_rptr += 4; |
| @@ -3780,7 +3785,7 @@ static void gfx_v8_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
| 3780 | amdgpu_ring_write(ring, next_rptr); | 3785 | amdgpu_ring_write(ring, next_rptr); |
| 3781 | 3786 | ||
| 3782 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ | 3787 | /* insert SWITCH_BUFFER packet before first IB in the ring frame */ |
| 3783 | if (need_ctx_switch && ring->type == AMDGPU_RING_TYPE_GFX) { | 3788 | if (need_ctx_switch) { |
| 3784 | amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); | 3789 | amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); |
| 3785 | amdgpu_ring_write(ring, 0); | 3790 | amdgpu_ring_write(ring, 0); |
| 3786 | } | 3791 | } |
| @@ -3803,6 +3808,36 @@ static void gfx_v8_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
| 3803 | amdgpu_ring_write(ring, control); | 3808 | amdgpu_ring_write(ring, control); |
| 3804 | } | 3809 | } |
| 3805 | 3810 | ||
| 3811 | static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring, | ||
| 3812 | struct amdgpu_ib *ib) | ||
| 3813 | { | ||
| 3814 | u32 header, control = 0; | ||
| 3815 | u32 next_rptr = ring->wptr + 5; | ||
| 3816 | |||
| 3817 | control |= INDIRECT_BUFFER_VALID; | ||
| 3818 | |||
| 3819 | next_rptr += 4; | ||
| 3820 | amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | ||
| 3821 | amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM); | ||
| 3822 | amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
| 3823 | amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); | ||
| 3824 | amdgpu_ring_write(ring, next_rptr); | ||
| 3825 | |||
| 3826 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); | ||
| 3827 | |||
| 3828 | control |= ib->length_dw | | ||
| 3829 | (ib->vm ? (ib->vm->ids[ring->idx].id << 24) : 0); | ||
| 3830 | |||
| 3831 | amdgpu_ring_write(ring, header); | ||
| 3832 | amdgpu_ring_write(ring, | ||
| 3833 | #ifdef __BIG_ENDIAN | ||
| 3834 | (2 << 0) | | ||
| 3835 | #endif | ||
| 3836 | (ib->gpu_addr & 0xFFFFFFFC)); | ||
| 3837 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); | ||
| 3838 | amdgpu_ring_write(ring, control); | ||
| 3839 | } | ||
| 3840 | |||
| 3806 | static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, | 3841 | static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, |
| 3807 | u64 seq, unsigned flags) | 3842 | u64 seq, unsigned flags) |
| 3808 | { | 3843 | { |
| @@ -4224,7 +4259,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = { | |||
| 4224 | .get_wptr = gfx_v8_0_ring_get_wptr_gfx, | 4259 | .get_wptr = gfx_v8_0_ring_get_wptr_gfx, |
| 4225 | .set_wptr = gfx_v8_0_ring_set_wptr_gfx, | 4260 | .set_wptr = gfx_v8_0_ring_set_wptr_gfx, |
| 4226 | .parse_cs = NULL, | 4261 | .parse_cs = NULL, |
| 4227 | .emit_ib = gfx_v8_0_ring_emit_ib, | 4262 | .emit_ib = gfx_v8_0_ring_emit_ib_gfx, |
| 4228 | .emit_fence = gfx_v8_0_ring_emit_fence_gfx, | 4263 | .emit_fence = gfx_v8_0_ring_emit_fence_gfx, |
| 4229 | .emit_semaphore = gfx_v8_0_ring_emit_semaphore, | 4264 | .emit_semaphore = gfx_v8_0_ring_emit_semaphore, |
| 4230 | .emit_vm_flush = gfx_v8_0_ring_emit_vm_flush, | 4265 | .emit_vm_flush = gfx_v8_0_ring_emit_vm_flush, |
| @@ -4240,7 +4275,7 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { | |||
| 4240 | .get_wptr = gfx_v8_0_ring_get_wptr_compute, | 4275 | .get_wptr = gfx_v8_0_ring_get_wptr_compute, |
| 4241 | .set_wptr = gfx_v8_0_ring_set_wptr_compute, | 4276 | .set_wptr = gfx_v8_0_ring_set_wptr_compute, |
| 4242 | .parse_cs = NULL, | 4277 | .parse_cs = NULL, |
| 4243 | .emit_ib = gfx_v8_0_ring_emit_ib, | 4278 | .emit_ib = gfx_v8_0_ring_emit_ib_compute, |
| 4244 | .emit_fence = gfx_v8_0_ring_emit_fence_compute, | 4279 | .emit_fence = gfx_v8_0_ring_emit_fence_compute, |
| 4245 | .emit_semaphore = gfx_v8_0_ring_emit_semaphore, | 4280 | .emit_semaphore = gfx_v8_0_ring_emit_semaphore, |
| 4246 | .emit_vm_flush = gfx_v8_0_ring_emit_vm_flush, | 4281 | .emit_vm_flush = gfx_v8_0_ring_emit_vm_flush, |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index d7895885fe0c..a988dfb1d394 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
| @@ -121,6 +121,7 @@ static int sdma_v2_4_init_microcode(struct amdgpu_device *adev) | |||
| 121 | int err, i; | 121 | int err, i; |
| 122 | struct amdgpu_firmware_info *info = NULL; | 122 | struct amdgpu_firmware_info *info = NULL; |
| 123 | const struct common_firmware_header *header = NULL; | 123 | const struct common_firmware_header *header = NULL; |
| 124 | const struct sdma_firmware_header_v1_0 *hdr; | ||
| 124 | 125 | ||
| 125 | DRM_DEBUG("\n"); | 126 | DRM_DEBUG("\n"); |
| 126 | 127 | ||
| @@ -142,6 +143,9 @@ static int sdma_v2_4_init_microcode(struct amdgpu_device *adev) | |||
| 142 | err = amdgpu_ucode_validate(adev->sdma[i].fw); | 143 | err = amdgpu_ucode_validate(adev->sdma[i].fw); |
| 143 | if (err) | 144 | if (err) |
| 144 | goto out; | 145 | goto out; |
| 146 | hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma[i].fw->data; | ||
| 147 | adev->sdma[i].fw_version = le32_to_cpu(hdr->header.ucode_version); | ||
| 148 | adev->sdma[i].feature_version = le32_to_cpu(hdr->ucode_feature_version); | ||
| 145 | 149 | ||
| 146 | if (adev->firmware.smu_load) { | 150 | if (adev->firmware.smu_load) { |
| 147 | info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i]; | 151 | info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i]; |
| @@ -541,8 +545,6 @@ static int sdma_v2_4_load_microcode(struct amdgpu_device *adev) | |||
| 541 | hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma[i].fw->data; | 545 | hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma[i].fw->data; |
| 542 | amdgpu_ucode_print_sdma_hdr(&hdr->header); | 546 | amdgpu_ucode_print_sdma_hdr(&hdr->header); |
| 543 | fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; | 547 | fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; |
| 544 | adev->sdma[i].fw_version = le32_to_cpu(hdr->header.ucode_version); | ||
| 545 | |||
| 546 | fw_data = (const __le32 *) | 548 | fw_data = (const __le32 *) |
| 547 | (adev->sdma[i].fw->data + | 549 | (adev->sdma[i].fw->data + |
| 548 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | 550 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 7bb37b93993f..2b86569b18d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
| @@ -159,6 +159,7 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev) | |||
| 159 | int err, i; | 159 | int err, i; |
| 160 | struct amdgpu_firmware_info *info = NULL; | 160 | struct amdgpu_firmware_info *info = NULL; |
| 161 | const struct common_firmware_header *header = NULL; | 161 | const struct common_firmware_header *header = NULL; |
| 162 | const struct sdma_firmware_header_v1_0 *hdr; | ||
| 162 | 163 | ||
| 163 | DRM_DEBUG("\n"); | 164 | DRM_DEBUG("\n"); |
| 164 | 165 | ||
| @@ -183,6 +184,9 @@ static int sdma_v3_0_init_microcode(struct amdgpu_device *adev) | |||
| 183 | err = amdgpu_ucode_validate(adev->sdma[i].fw); | 184 | err = amdgpu_ucode_validate(adev->sdma[i].fw); |
| 184 | if (err) | 185 | if (err) |
| 185 | goto out; | 186 | goto out; |
| 187 | hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma[i].fw->data; | ||
| 188 | adev->sdma[i].fw_version = le32_to_cpu(hdr->header.ucode_version); | ||
| 189 | adev->sdma[i].feature_version = le32_to_cpu(hdr->ucode_feature_version); | ||
| 186 | 190 | ||
| 187 | if (adev->firmware.smu_load) { | 191 | if (adev->firmware.smu_load) { |
| 188 | info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i]; | 192 | info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i]; |
| @@ -630,8 +634,6 @@ static int sdma_v3_0_load_microcode(struct amdgpu_device *adev) | |||
| 630 | hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma[i].fw->data; | 634 | hdr = (const struct sdma_firmware_header_v1_0 *)adev->sdma[i].fw->data; |
| 631 | amdgpu_ucode_print_sdma_hdr(&hdr->header); | 635 | amdgpu_ucode_print_sdma_hdr(&hdr->header); |
| 632 | fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; | 636 | fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; |
| 633 | adev->sdma[i].fw_version = le32_to_cpu(hdr->header.ucode_version); | ||
| 634 | |||
| 635 | fw_data = (const __le32 *) | 637 | fw_data = (const __le32 *) |
| 636 | (adev->sdma[i].fw->data + | 638 | (adev->sdma[i].fw->data + |
| 637 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); | 639 | le32_to_cpu(hdr->header.ucode_array_offset_bytes)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index d62c4002e39c..d1064ca3670e 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | |||
| @@ -35,6 +35,8 @@ | |||
| 35 | #include "oss/oss_2_0_d.h" | 35 | #include "oss/oss_2_0_d.h" |
| 36 | #include "oss/oss_2_0_sh_mask.h" | 36 | #include "oss/oss_2_0_sh_mask.h" |
| 37 | #include "gca/gfx_8_0_d.h" | 37 | #include "gca/gfx_8_0_d.h" |
| 38 | #include "smu/smu_7_1_2_d.h" | ||
| 39 | #include "smu/smu_7_1_2_sh_mask.h" | ||
| 38 | 40 | ||
| 39 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 | 41 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 |
| 40 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 | 42 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 |
| @@ -112,6 +114,10 @@ static int vce_v3_0_start(struct amdgpu_device *adev) | |||
| 112 | 114 | ||
| 113 | mutex_lock(&adev->grbm_idx_mutex); | 115 | mutex_lock(&adev->grbm_idx_mutex); |
| 114 | for (idx = 0; idx < 2; ++idx) { | 116 | for (idx = 0; idx < 2; ++idx) { |
| 117 | |||
| 118 | if (adev->vce.harvest_config & (1 << idx)) | ||
| 119 | continue; | ||
| 120 | |||
| 115 | if(idx == 0) | 121 | if(idx == 0) |
| 116 | WREG32_P(mmGRBM_GFX_INDEX, 0, | 122 | WREG32_P(mmGRBM_GFX_INDEX, 0, |
| 117 | ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); | 123 | ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); |
| @@ -190,10 +196,52 @@ static int vce_v3_0_start(struct amdgpu_device *adev) | |||
| 190 | return 0; | 196 | return 0; |
| 191 | } | 197 | } |
| 192 | 198 | ||
| 199 | #define ixVCE_HARVEST_FUSE_MACRO__ADDRESS 0xC0014074 | ||
| 200 | #define VCE_HARVEST_FUSE_MACRO__SHIFT 27 | ||
| 201 | #define VCE_HARVEST_FUSE_MACRO__MASK 0x18000000 | ||
| 202 | |||
| 203 | static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev) | ||
| 204 | { | ||
| 205 | u32 tmp; | ||
| 206 | unsigned ret; | ||
| 207 | |||
| 208 | if (adev->flags & AMDGPU_IS_APU) | ||
| 209 | tmp = (RREG32_SMC(ixVCE_HARVEST_FUSE_MACRO__ADDRESS) & | ||
| 210 | VCE_HARVEST_FUSE_MACRO__MASK) >> | ||
| 211 | VCE_HARVEST_FUSE_MACRO__SHIFT; | ||
| 212 | else | ||
| 213 | tmp = (RREG32_SMC(ixCC_HARVEST_FUSES) & | ||
| 214 | CC_HARVEST_FUSES__VCE_DISABLE_MASK) >> | ||
| 215 | CC_HARVEST_FUSES__VCE_DISABLE__SHIFT; | ||
| 216 | |||
| 217 | switch (tmp) { | ||
| 218 | case 1: | ||
| 219 | ret = AMDGPU_VCE_HARVEST_VCE0; | ||
| 220 | break; | ||
| 221 | case 2: | ||
| 222 | ret = AMDGPU_VCE_HARVEST_VCE1; | ||
| 223 | break; | ||
| 224 | case 3: | ||
| 225 | ret = AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1; | ||
| 226 | break; | ||
| 227 | default: | ||
| 228 | ret = 0; | ||
| 229 | } | ||
| 230 | |||
| 231 | return ret; | ||
| 232 | } | ||
| 233 | |||
| 193 | static int vce_v3_0_early_init(void *handle) | 234 | static int vce_v3_0_early_init(void *handle) |
| 194 | { | 235 | { |
| 195 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 236 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 196 | 237 | ||
| 238 | adev->vce.harvest_config = vce_v3_0_get_harvest_config(adev); | ||
| 239 | |||
| 240 | if ((adev->vce.harvest_config & | ||
| 241 | (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) == | ||
| 242 | (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) | ||
| 243 | return -ENOENT; | ||
| 244 | |||
| 197 | vce_v3_0_set_ring_funcs(adev); | 245 | vce_v3_0_set_ring_funcs(adev); |
| 198 | vce_v3_0_set_irq_funcs(adev); | 246 | vce_v3_0_set_irq_funcs(adev); |
| 199 | 247 | ||
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index 8b8fe3762ca9..9f6e234e7029 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | |||
| @@ -357,6 +357,7 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev) | |||
| 357 | planes->overlays[i]->base.possible_crtcs = 1 << crtc->id; | 357 | planes->overlays[i]->base.possible_crtcs = 1 << crtc->id; |
| 358 | 358 | ||
| 359 | drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs); | 359 | drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs); |
| 360 | drm_crtc_vblank_reset(&crtc->base); | ||
| 360 | 361 | ||
| 361 | dc->crtc = &crtc->base; | 362 | dc->crtc = &crtc->base; |
| 362 | 363 | ||
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 60b0c13d7ff5..6fad1f9648f3 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | |||
| @@ -313,20 +313,20 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev) | |||
| 313 | 313 | ||
| 314 | pm_runtime_enable(dev->dev); | 314 | pm_runtime_enable(dev->dev); |
| 315 | 315 | ||
| 316 | ret = atmel_hlcdc_dc_modeset_init(dev); | 316 | ret = drm_vblank_init(dev, 1); |
| 317 | if (ret < 0) { | 317 | if (ret < 0) { |
| 318 | dev_err(dev->dev, "failed to initialize mode setting\n"); | 318 | dev_err(dev->dev, "failed to initialize vblank\n"); |
| 319 | goto err_periph_clk_disable; | 319 | goto err_periph_clk_disable; |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | drm_mode_config_reset(dev); | 322 | ret = atmel_hlcdc_dc_modeset_init(dev); |
| 323 | |||
| 324 | ret = drm_vblank_init(dev, 1); | ||
| 325 | if (ret < 0) { | 323 | if (ret < 0) { |
| 326 | dev_err(dev->dev, "failed to initialize vblank\n"); | 324 | dev_err(dev->dev, "failed to initialize mode setting\n"); |
| 327 | goto err_periph_clk_disable; | 325 | goto err_periph_clk_disable; |
| 328 | } | 326 | } |
| 329 | 327 | ||
| 328 | drm_mode_config_reset(dev); | ||
| 329 | |||
| 330 | pm_runtime_get_sync(dev->dev); | 330 | pm_runtime_get_sync(dev->dev); |
| 331 | ret = drm_irq_install(dev, dc->hlcdc->irq); | 331 | ret = drm_irq_install(dev, dc->hlcdc->irq); |
| 332 | pm_runtime_put_sync(dev->dev); | 332 | pm_runtime_put_sync(dev->dev); |
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 52dbeedcdcc8..d432348837a5 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
| @@ -196,7 +196,12 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) | |||
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | funcs = connector->helper_private; | 198 | funcs = connector->helper_private; |
| 199 | new_encoder = funcs->best_encoder(connector); | 199 | |
| 200 | if (funcs->atomic_best_encoder) | ||
| 201 | new_encoder = funcs->atomic_best_encoder(connector, | ||
| 202 | connector_state); | ||
| 203 | else | ||
| 204 | new_encoder = funcs->best_encoder(connector); | ||
| 200 | 205 | ||
| 201 | if (!new_encoder) { | 206 | if (!new_encoder) { |
| 202 | DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", | 207 | DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", |
| @@ -229,6 +234,9 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) | |||
| 229 | } | 234 | } |
| 230 | } | 235 | } |
| 231 | 236 | ||
| 237 | if (WARN_ON(!connector_state->crtc)) | ||
| 238 | return -EINVAL; | ||
| 239 | |||
| 232 | connector_state->best_encoder = new_encoder; | 240 | connector_state->best_encoder = new_encoder; |
| 233 | idx = drm_crtc_index(connector_state->crtc); | 241 | idx = drm_crtc_index(connector_state->crtc); |
| 234 | 242 | ||
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 21f1f5ce2d60..33d877c65ced 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -5274,12 +5274,9 @@ void drm_mode_config_reset(struct drm_device *dev) | |||
| 5274 | encoder->funcs->reset(encoder); | 5274 | encoder->funcs->reset(encoder); |
| 5275 | 5275 | ||
| 5276 | mutex_lock(&dev->mode_config.mutex); | 5276 | mutex_lock(&dev->mode_config.mutex); |
| 5277 | drm_for_each_connector(connector, dev) { | 5277 | drm_for_each_connector(connector, dev) |
| 5278 | connector->status = connector_status_unknown; | ||
| 5279 | |||
| 5280 | if (connector->funcs->reset) | 5278 | if (connector->funcs->reset) |
| 5281 | connector->funcs->reset(connector); | 5279 | connector->funcs->reset(connector); |
| 5282 | } | ||
| 5283 | mutex_unlock(&dev->mode_config.mutex); | 5280 | mutex_unlock(&dev->mode_config.mutex); |
| 5284 | } | 5281 | } |
| 5285 | EXPORT_SYMBOL(drm_mode_config_reset); | 5282 | EXPORT_SYMBOL(drm_mode_config_reset); |
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 778bbb6425b8..b0487c9f018c 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
| @@ -1294,7 +1294,6 @@ retry: | |||
| 1294 | goto retry; | 1294 | goto retry; |
| 1295 | } | 1295 | } |
| 1296 | DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret); | 1296 | DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret); |
| 1297 | WARN(1, "fail\n"); | ||
| 1298 | 1297 | ||
| 1299 | return -EIO; | 1298 | return -EIO; |
| 1300 | } | 1299 | } |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 05b939e8da41..22d207e211e7 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -75,7 +75,7 @@ module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600) | |||
| 75 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); | 75 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); |
| 76 | 76 | ||
| 77 | static void store_vblank(struct drm_device *dev, int crtc, | 77 | static void store_vblank(struct drm_device *dev, int crtc, |
| 78 | unsigned vblank_count_inc, | 78 | u32 vblank_count_inc, |
| 79 | struct timeval *t_vblank) | 79 | struct timeval *t_vblank) |
| 80 | { | 80 | { |
| 81 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; | 81 | struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 842d6b8dc3c4..2a652359af64 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c | |||
| @@ -1745,7 +1745,6 @@ static int fimc_probe(struct platform_device *pdev) | |||
| 1745 | spin_lock_init(&ctx->lock); | 1745 | spin_lock_init(&ctx->lock); |
| 1746 | platform_set_drvdata(pdev, ctx); | 1746 | platform_set_drvdata(pdev, ctx); |
| 1747 | 1747 | ||
| 1748 | pm_runtime_set_active(dev); | ||
| 1749 | pm_runtime_enable(dev); | 1748 | pm_runtime_enable(dev); |
| 1750 | 1749 | ||
| 1751 | ret = exynos_drm_ippdrv_register(ippdrv); | 1750 | ret = exynos_drm_ippdrv_register(ippdrv); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 8040ed2a831f..f1c6b76c127f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c | |||
| @@ -593,8 +593,7 @@ static int gsc_src_set_transf(struct device *dev, | |||
| 593 | 593 | ||
| 594 | gsc_write(cfg, GSC_IN_CON); | 594 | gsc_write(cfg, GSC_IN_CON); |
| 595 | 595 | ||
| 596 | ctx->rotation = cfg & | 596 | ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0; |
| 597 | (GSC_IN_ROT_90 | GSC_IN_ROT_270) ? 1 : 0; | ||
| 598 | *swap = ctx->rotation; | 597 | *swap = ctx->rotation; |
| 599 | 598 | ||
| 600 | return 0; | 599 | return 0; |
| @@ -857,8 +856,7 @@ static int gsc_dst_set_transf(struct device *dev, | |||
| 857 | 856 | ||
| 858 | gsc_write(cfg, GSC_IN_CON); | 857 | gsc_write(cfg, GSC_IN_CON); |
| 859 | 858 | ||
| 860 | ctx->rotation = cfg & | 859 | ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0; |
| 861 | (GSC_IN_ROT_90 | GSC_IN_ROT_270) ? 1 : 0; | ||
| 862 | *swap = ctx->rotation; | 860 | *swap = ctx->rotation; |
| 863 | 861 | ||
| 864 | return 0; | 862 | return 0; |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 99e286489031..4a00990e4ae4 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -1064,6 +1064,7 @@ static int hdmi_get_modes(struct drm_connector *connector) | |||
| 1064 | { | 1064 | { |
| 1065 | struct hdmi_context *hdata = ctx_from_connector(connector); | 1065 | struct hdmi_context *hdata = ctx_from_connector(connector); |
| 1066 | struct edid *edid; | 1066 | struct edid *edid; |
| 1067 | int ret; | ||
| 1067 | 1068 | ||
| 1068 | if (!hdata->ddc_adpt) | 1069 | if (!hdata->ddc_adpt) |
| 1069 | return -ENODEV; | 1070 | return -ENODEV; |
| @@ -1079,7 +1080,11 @@ static int hdmi_get_modes(struct drm_connector *connector) | |||
| 1079 | 1080 | ||
| 1080 | drm_mode_connector_update_edid_property(connector, edid); | 1081 | drm_mode_connector_update_edid_property(connector, edid); |
| 1081 | 1082 | ||
| 1082 | return drm_add_edid_modes(connector, edid); | 1083 | ret = drm_add_edid_modes(connector, edid); |
| 1084 | |||
| 1085 | kfree(edid); | ||
| 1086 | |||
| 1087 | return ret; | ||
| 1083 | } | 1088 | } |
| 1084 | 1089 | ||
| 1085 | static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) | 1090 | static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index cae98db33062..4706b56902b4 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
| @@ -718,6 +718,10 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) | |||
| 718 | 718 | ||
| 719 | /* handling VSYNC */ | 719 | /* handling VSYNC */ |
| 720 | if (val & MXR_INT_STATUS_VSYNC) { | 720 | if (val & MXR_INT_STATUS_VSYNC) { |
| 721 | /* vsync interrupt use different bit for read and clear */ | ||
| 722 | val |= MXR_INT_CLEAR_VSYNC; | ||
| 723 | val &= ~MXR_INT_STATUS_VSYNC; | ||
| 724 | |||
| 721 | /* interlace scan need to check shadow register */ | 725 | /* interlace scan need to check shadow register */ |
| 722 | if (ctx->interlace) { | 726 | if (ctx->interlace) { |
| 723 | base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0)); | 727 | base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0)); |
| @@ -743,11 +747,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg) | |||
| 743 | 747 | ||
| 744 | out: | 748 | out: |
| 745 | /* clear interrupts */ | 749 | /* clear interrupts */ |
| 746 | if (~val & MXR_INT_EN_VSYNC) { | ||
| 747 | /* vsync interrupt use different bit for read and clear */ | ||
| 748 | val &= ~MXR_INT_EN_VSYNC; | ||
| 749 | val |= MXR_INT_CLEAR_VSYNC; | ||
| 750 | } | ||
| 751 | mixer_reg_write(res, MXR_INT_STATUS, val); | 750 | mixer_reg_write(res, MXR_INT_STATUS, val); |
| 752 | 751 | ||
| 753 | spin_unlock(&res->reg_slock); | 752 | spin_unlock(&res->reg_slock); |
| @@ -907,8 +906,8 @@ static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) | |||
| 907 | } | 906 | } |
| 908 | 907 | ||
| 909 | /* enable vsync interrupt */ | 908 | /* enable vsync interrupt */ |
| 910 | mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC, | 909 | mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); |
| 911 | MXR_INT_EN_VSYNC); | 910 | mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC); |
| 912 | 911 | ||
| 913 | return 0; | 912 | return 0; |
| 914 | } | 913 | } |
| @@ -918,7 +917,13 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) | |||
| 918 | struct mixer_context *mixer_ctx = crtc->ctx; | 917 | struct mixer_context *mixer_ctx = crtc->ctx; |
| 919 | struct mixer_resources *res = &mixer_ctx->mixer_res; | 918 | struct mixer_resources *res = &mixer_ctx->mixer_res; |
| 920 | 919 | ||
| 920 | if (!mixer_ctx->powered) { | ||
| 921 | mixer_ctx->int_en &= MXR_INT_EN_VSYNC; | ||
| 922 | return; | ||
| 923 | } | ||
| 924 | |||
| 921 | /* disable vsync interrupt */ | 925 | /* disable vsync interrupt */ |
| 926 | mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); | ||
| 922 | mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); | 927 | mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); |
| 923 | } | 928 | } |
| 924 | 929 | ||
| @@ -1047,6 +1052,8 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) | |||
| 1047 | 1052 | ||
| 1048 | mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); | 1053 | mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); |
| 1049 | 1054 | ||
| 1055 | if (ctx->int_en & MXR_INT_EN_VSYNC) | ||
| 1056 | mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC); | ||
| 1050 | mixer_reg_write(res, MXR_INT_EN, ctx->int_en); | 1057 | mixer_reg_write(res, MXR_INT_EN, ctx->int_en); |
| 1051 | mixer_win_reset(ctx); | 1058 | mixer_win_reset(ctx); |
| 1052 | } | 1059 | } |
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index fe1599d75f14..424228be79ae 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
| @@ -606,8 +606,6 @@ static void | |||
| 606 | tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr, | 606 | tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr, |
| 607 | uint8_t *buf, size_t size) | 607 | uint8_t *buf, size_t size) |
| 608 | { | 608 | { |
| 609 | buf[PB(0)] = tda998x_cksum(buf, size); | ||
| 610 | |||
| 611 | reg_clear(priv, REG_DIP_IF_FLAGS, bit); | 609 | reg_clear(priv, REG_DIP_IF_FLAGS, bit); |
| 612 | reg_write_range(priv, addr, buf, size); | 610 | reg_write_range(priv, addr, buf, size); |
| 613 | reg_set(priv, REG_DIP_IF_FLAGS, bit); | 611 | reg_set(priv, REG_DIP_IF_FLAGS, bit); |
| @@ -627,6 +625,8 @@ tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) | |||
| 627 | buf[PB(4)] = p->audio_frame[4]; | 625 | buf[PB(4)] = p->audio_frame[4]; |
| 628 | buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */ | 626 | buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */ |
| 629 | 627 | ||
| 628 | buf[PB(0)] = tda998x_cksum(buf, sizeof(buf)); | ||
| 629 | |||
| 630 | tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, | 630 | tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, |
| 631 | sizeof(buf)); | 631 | sizeof(buf)); |
| 632 | } | 632 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e9d2befbcaf3..574d0f1c26bf 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -3359,15 +3359,14 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val); | |||
| 3359 | #define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true) | 3359 | #define I915_READ64(reg) dev_priv->uncore.funcs.mmio_readq(dev_priv, (reg), true) |
| 3360 | 3360 | ||
| 3361 | #define I915_READ64_2x32(lower_reg, upper_reg) ({ \ | 3361 | #define I915_READ64_2x32(lower_reg, upper_reg) ({ \ |
| 3362 | u32 upper = I915_READ(upper_reg); \ | 3362 | u32 upper, lower, tmp; \ |
| 3363 | u32 lower = I915_READ(lower_reg); \ | 3363 | tmp = I915_READ(upper_reg); \ |
| 3364 | u32 tmp = I915_READ(upper_reg); \ | 3364 | do { \ |
| 3365 | if (upper != tmp) { \ | 3365 | upper = tmp; \ |
| 3366 | upper = tmp; \ | 3366 | lower = I915_READ(lower_reg); \ |
| 3367 | lower = I915_READ(lower_reg); \ | 3367 | tmp = I915_READ(upper_reg); \ |
| 3368 | WARN_ON(I915_READ(upper_reg) != upper); \ | 3368 | } while (upper != tmp); \ |
| 3369 | } \ | 3369 | (u64)upper << 32 | lower; }) |
| 3370 | (u64)upper << 32 | lower; }) | ||
| 3371 | 3370 | ||
| 3372 | #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) | 3371 | #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) |
| 3373 | #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) | 3372 | #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index c2a291e09bd9..96054a560f4f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -2003,6 +2003,17 @@ static int ggtt_bind_vma(struct i915_vma *vma, | |||
| 2003 | vma->vm->insert_entries(vma->vm, pages, | 2003 | vma->vm->insert_entries(vma->vm, pages, |
| 2004 | vma->node.start, | 2004 | vma->node.start, |
| 2005 | cache_level, pte_flags); | 2005 | cache_level, pte_flags); |
| 2006 | |||
| 2007 | /* Note the inconsistency here is due to absence of the | ||
| 2008 | * aliasing ppgtt on gen4 and earlier. Though we always | ||
| 2009 | * request PIN_USER for execbuffer (translated to LOCAL_BIND), | ||
| 2010 | * without the appgtt, we cannot honour that request and so | ||
| 2011 | * must substitute it with a global binding. Since we do this | ||
| 2012 | * behind the upper layers back, we need to explicitly set | ||
| 2013 | * the bound flag ourselves. | ||
| 2014 | */ | ||
| 2015 | vma->bound |= GLOBAL_BIND; | ||
| 2016 | |||
| 2006 | } | 2017 | } |
| 2007 | 2018 | ||
| 2008 | if (dev_priv->mm.aliasing_ppgtt && flags & LOCAL_BIND) { | 2019 | if (dev_priv->mm.aliasing_ppgtt && flags & LOCAL_BIND) { |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 633bd1fcab69..d19c9db5e18c 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -464,7 +464,10 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ | 466 | /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ |
| 467 | args->phys_swizzle_mode = args->swizzle_mode; | 467 | if (dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) |
| 468 | args->phys_swizzle_mode = I915_BIT_6_SWIZZLE_UNKNOWN; | ||
| 469 | else | ||
| 470 | args->phys_swizzle_mode = args->swizzle_mode; | ||
| 468 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) | 471 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) |
| 469 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9; | 472 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9; |
| 470 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) | 473 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 2ff9eb00fdec..31b1079cbd1b 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
| @@ -1015,15 +1015,34 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
| 1015 | const union child_device_config *p_child; | 1015 | const union child_device_config *p_child; |
| 1016 | union child_device_config *child_dev_ptr; | 1016 | union child_device_config *child_dev_ptr; |
| 1017 | int i, child_device_num, count; | 1017 | int i, child_device_num, count; |
| 1018 | u16 block_size; | 1018 | u8 expected_size; |
| 1019 | u16 block_size; | ||
| 1019 | 1020 | ||
| 1020 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 1021 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
| 1021 | if (!p_defs) { | 1022 | if (!p_defs) { |
| 1022 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); | 1023 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); |
| 1023 | return; | 1024 | return; |
| 1024 | } | 1025 | } |
| 1025 | if (p_defs->child_dev_size < sizeof(*p_child)) { | 1026 | if (bdb->version < 195) { |
| 1026 | DRM_ERROR("General definiton block child device size is too small.\n"); | 1027 | expected_size = 33; |
| 1028 | } else if (bdb->version == 195) { | ||
| 1029 | expected_size = 37; | ||
| 1030 | } else if (bdb->version <= 197) { | ||
| 1031 | expected_size = 38; | ||
| 1032 | } else { | ||
| 1033 | expected_size = 38; | ||
| 1034 | DRM_DEBUG_DRIVER("Expected child_device_config size for BDB version %u not known; assuming %u\n", | ||
| 1035 | expected_size, bdb->version); | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | if (expected_size > sizeof(*p_child)) { | ||
| 1039 | DRM_ERROR("child_device_config cannot fit in p_child\n"); | ||
| 1040 | return; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | if (p_defs->child_dev_size != expected_size) { | ||
| 1044 | DRM_ERROR("Size mismatch; child_device_config size=%u (expected %u); bdb->version: %u\n", | ||
| 1045 | p_defs->child_dev_size, expected_size, bdb->version); | ||
| 1027 | return; | 1046 | return; |
| 1028 | } | 1047 | } |
| 1029 | /* get the block size of general definitions */ | 1048 | /* get the block size of general definitions */ |
| @@ -1070,7 +1089,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
| 1070 | 1089 | ||
| 1071 | child_dev_ptr = dev_priv->vbt.child_dev + count; | 1090 | child_dev_ptr = dev_priv->vbt.child_dev + count; |
| 1072 | count++; | 1091 | count++; |
| 1073 | memcpy(child_dev_ptr, p_child, sizeof(*p_child)); | 1092 | memcpy(child_dev_ptr, p_child, p_defs->child_dev_size); |
| 1074 | } | 1093 | } |
| 1075 | return; | 1094 | return; |
| 1076 | } | 1095 | } |
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index efc8cf53f0f3..a61df29918ed 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
| @@ -357,6 +357,16 @@ intel_dp_mst_mode_valid(struct drm_connector *connector, | |||
| 357 | return MODE_OK; | 357 | return MODE_OK; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector, | ||
| 361 | struct drm_connector_state *state) | ||
| 362 | { | ||
| 363 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 364 | struct intel_dp *intel_dp = intel_connector->mst_port; | ||
| 365 | struct intel_crtc *crtc = to_intel_crtc(state->crtc); | ||
| 366 | |||
| 367 | return &intel_dp->mst_encoders[crtc->pipe]->base.base; | ||
| 368 | } | ||
| 369 | |||
| 360 | static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) | 370 | static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector) |
| 361 | { | 371 | { |
| 362 | struct intel_connector *intel_connector = to_intel_connector(connector); | 372 | struct intel_connector *intel_connector = to_intel_connector(connector); |
| @@ -367,6 +377,7 @@ static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connecto | |||
| 367 | static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { | 377 | static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { |
| 368 | .get_modes = intel_dp_mst_get_modes, | 378 | .get_modes = intel_dp_mst_get_modes, |
| 369 | .mode_valid = intel_dp_mst_mode_valid, | 379 | .mode_valid = intel_dp_mst_mode_valid, |
| 380 | .atomic_best_encoder = intel_mst_atomic_best_encoder, | ||
| 370 | .best_encoder = intel_mst_best_encoder, | 381 | .best_encoder = intel_mst_best_encoder, |
| 371 | }; | 382 | }; |
| 372 | 383 | ||
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 45285a9178fe..9d3c2e420d2b 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
| @@ -1274,10 +1274,12 @@ int i915_reg_read_ioctl(struct drm_device *dev, | |||
| 1274 | struct drm_i915_private *dev_priv = dev->dev_private; | 1274 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1275 | struct drm_i915_reg_read *reg = data; | 1275 | struct drm_i915_reg_read *reg = data; |
| 1276 | struct register_whitelist const *entry = whitelist; | 1276 | struct register_whitelist const *entry = whitelist; |
| 1277 | unsigned size; | ||
| 1278 | u64 offset; | ||
| 1277 | int i, ret = 0; | 1279 | int i, ret = 0; |
| 1278 | 1280 | ||
| 1279 | for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { | 1281 | for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { |
| 1280 | if (entry->offset == reg->offset && | 1282 | if (entry->offset == (reg->offset & -entry->size) && |
| 1281 | (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask)) | 1283 | (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask)) |
| 1282 | break; | 1284 | break; |
| 1283 | } | 1285 | } |
| @@ -1285,23 +1287,33 @@ int i915_reg_read_ioctl(struct drm_device *dev, | |||
| 1285 | if (i == ARRAY_SIZE(whitelist)) | 1287 | if (i == ARRAY_SIZE(whitelist)) |
| 1286 | return -EINVAL; | 1288 | return -EINVAL; |
| 1287 | 1289 | ||
| 1290 | /* We use the low bits to encode extra flags as the register should | ||
| 1291 | * be naturally aligned (and those that are not so aligned merely | ||
| 1292 | * limit the available flags for that register). | ||
| 1293 | */ | ||
| 1294 | offset = entry->offset; | ||
| 1295 | size = entry->size; | ||
| 1296 | size |= reg->offset ^ offset; | ||
| 1297 | |||
| 1288 | intel_runtime_pm_get(dev_priv); | 1298 | intel_runtime_pm_get(dev_priv); |
| 1289 | 1299 | ||
| 1290 | switch (entry->size) { | 1300 | switch (size) { |
| 1301 | case 8 | 1: | ||
| 1302 | reg->val = I915_READ64_2x32(offset, offset+4); | ||
| 1303 | break; | ||
| 1291 | case 8: | 1304 | case 8: |
| 1292 | reg->val = I915_READ64(reg->offset); | 1305 | reg->val = I915_READ64(offset); |
| 1293 | break; | 1306 | break; |
| 1294 | case 4: | 1307 | case 4: |
| 1295 | reg->val = I915_READ(reg->offset); | 1308 | reg->val = I915_READ(offset); |
| 1296 | break; | 1309 | break; |
| 1297 | case 2: | 1310 | case 2: |
| 1298 | reg->val = I915_READ16(reg->offset); | 1311 | reg->val = I915_READ16(offset); |
| 1299 | break; | 1312 | break; |
| 1300 | case 1: | 1313 | case 1: |
| 1301 | reg->val = I915_READ8(reg->offset); | 1314 | reg->val = I915_READ8(offset); |
| 1302 | break; | 1315 | break; |
| 1303 | default: | 1316 | default: |
| 1304 | MISSING_CASE(entry->size); | ||
| 1305 | ret = -EINVAL; | 1317 | ret = -EINVAL; |
| 1306 | goto out; | 1318 | goto out; |
| 1307 | } | 1319 | } |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 0d1dbb737933..247a424445f7 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | |||
| @@ -220,13 +220,15 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, | |||
| 220 | uint32_t op_mode = 0; | 220 | uint32_t op_mode = 0; |
| 221 | uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT; | 221 | uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT; |
| 222 | uint32_t phasey_step = MDP4_VG_PHASE_STEP_DEFAULT; | 222 | uint32_t phasey_step = MDP4_VG_PHASE_STEP_DEFAULT; |
| 223 | enum mdp4_frame_format frame_type = mdp4_get_frame_format(fb); | 223 | enum mdp4_frame_format frame_type; |
| 224 | 224 | ||
| 225 | if (!(crtc && fb)) { | 225 | if (!(crtc && fb)) { |
| 226 | DBG("%s: disabled!", mdp4_plane->name); | 226 | DBG("%s: disabled!", mdp4_plane->name); |
| 227 | return 0; | 227 | return 0; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | frame_type = mdp4_get_frame_format(fb); | ||
| 231 | |||
| 230 | /* src values are in Q16 fixed point, convert to integer: */ | 232 | /* src values are in Q16 fixed point, convert to integer: */ |
| 231 | src_x = src_x >> 16; | 233 | src_x = src_x >> 16; |
| 232 | src_y = src_y >> 16; | 234 | src_y = src_y >> 16; |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 206f758f7d64..e253db5de5aa 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | |||
| @@ -76,7 +76,20 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st | |||
| 76 | 76 | ||
| 77 | static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) | 77 | static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) |
| 78 | { | 78 | { |
| 79 | int i; | ||
| 79 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); | 80 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); |
| 81 | int nplanes = mdp5_kms->dev->mode_config.num_total_plane; | ||
| 82 | |||
| 83 | for (i = 0; i < nplanes; i++) { | ||
| 84 | struct drm_plane *plane = state->planes[i]; | ||
| 85 | struct drm_plane_state *plane_state = state->plane_states[i]; | ||
| 86 | |||
| 87 | if (!plane) | ||
| 88 | continue; | ||
| 89 | |||
| 90 | mdp5_plane_complete_commit(plane, plane_state); | ||
| 91 | } | ||
| 92 | |||
| 80 | mdp5_disable(mdp5_kms); | 93 | mdp5_disable(mdp5_kms); |
| 81 | } | 94 | } |
| 82 | 95 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index e0eb24587c84..e79ac09b7216 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | |||
| @@ -227,6 +227,8 @@ void mdp5_plane_install_properties(struct drm_plane *plane, | |||
| 227 | struct drm_mode_object *obj); | 227 | struct drm_mode_object *obj); |
| 228 | uint32_t mdp5_plane_get_flush(struct drm_plane *plane); | 228 | uint32_t mdp5_plane_get_flush(struct drm_plane *plane); |
| 229 | void mdp5_plane_complete_flip(struct drm_plane *plane); | 229 | void mdp5_plane_complete_flip(struct drm_plane *plane); |
| 230 | void mdp5_plane_complete_commit(struct drm_plane *plane, | ||
| 231 | struct drm_plane_state *state); | ||
| 230 | enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane); | 232 | enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane); |
| 231 | struct drm_plane *mdp5_plane_init(struct drm_device *dev, | 233 | struct drm_plane *mdp5_plane_init(struct drm_device *dev, |
| 232 | enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset); | 234 | enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 57b8f56ae9d0..22275568ab8b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | |||
| @@ -31,8 +31,6 @@ struct mdp5_plane { | |||
| 31 | 31 | ||
| 32 | uint32_t nformats; | 32 | uint32_t nformats; |
| 33 | uint32_t formats[32]; | 33 | uint32_t formats[32]; |
| 34 | |||
| 35 | bool enabled; | ||
| 36 | }; | 34 | }; |
| 37 | #define to_mdp5_plane(x) container_of(x, struct mdp5_plane, base) | 35 | #define to_mdp5_plane(x) container_of(x, struct mdp5_plane, base) |
| 38 | 36 | ||
| @@ -56,22 +54,6 @@ static bool plane_enabled(struct drm_plane_state *state) | |||
| 56 | return state->fb && state->crtc; | 54 | return state->fb && state->crtc; |
| 57 | } | 55 | } |
| 58 | 56 | ||
| 59 | static int mdp5_plane_disable(struct drm_plane *plane) | ||
| 60 | { | ||
| 61 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); | ||
| 62 | struct mdp5_kms *mdp5_kms = get_kms(plane); | ||
| 63 | enum mdp5_pipe pipe = mdp5_plane->pipe; | ||
| 64 | |||
| 65 | DBG("%s: disable", mdp5_plane->name); | ||
| 66 | |||
| 67 | if (mdp5_kms) { | ||
| 68 | /* Release the memory we requested earlier from the SMP: */ | ||
| 69 | mdp5_smp_release(mdp5_kms->smp, pipe); | ||
| 70 | } | ||
| 71 | |||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | static void mdp5_plane_destroy(struct drm_plane *plane) | 57 | static void mdp5_plane_destroy(struct drm_plane *plane) |
| 76 | { | 58 | { |
| 77 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); | 59 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); |
| @@ -224,7 +206,6 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane, | |||
| 224 | 206 | ||
| 225 | if (!plane_enabled(state)) { | 207 | if (!plane_enabled(state)) { |
| 226 | to_mdp5_plane_state(state)->pending = true; | 208 | to_mdp5_plane_state(state)->pending = true; |
| 227 | mdp5_plane_disable(plane); | ||
| 228 | } else if (to_mdp5_plane_state(state)->mode_changed) { | 209 | } else if (to_mdp5_plane_state(state)->mode_changed) { |
| 229 | int ret; | 210 | int ret; |
| 230 | to_mdp5_plane_state(state)->pending = true; | 211 | to_mdp5_plane_state(state)->pending = true; |
| @@ -602,6 +583,20 @@ uint32_t mdp5_plane_get_flush(struct drm_plane *plane) | |||
| 602 | return mdp5_plane->flush_mask; | 583 | return mdp5_plane->flush_mask; |
| 603 | } | 584 | } |
| 604 | 585 | ||
| 586 | /* called after vsync in thread context */ | ||
| 587 | void mdp5_plane_complete_commit(struct drm_plane *plane, | ||
| 588 | struct drm_plane_state *state) | ||
| 589 | { | ||
| 590 | struct mdp5_kms *mdp5_kms = get_kms(plane); | ||
| 591 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); | ||
| 592 | enum mdp5_pipe pipe = mdp5_plane->pipe; | ||
| 593 | |||
| 594 | if (!plane_enabled(plane->state)) { | ||
| 595 | DBG("%s: free SMP", mdp5_plane->name); | ||
| 596 | mdp5_smp_release(mdp5_kms->smp, pipe); | ||
| 597 | } | ||
| 598 | } | ||
| 599 | |||
| 605 | /* initialize plane */ | 600 | /* initialize plane */ |
| 606 | struct drm_plane *mdp5_plane_init(struct drm_device *dev, | 601 | struct drm_plane *mdp5_plane_init(struct drm_device *dev, |
| 607 | enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset) | 602 | enum mdp5_pipe pipe, bool private_plane, uint32_t reg_offset) |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c index 16702aecf0df..64a27d86f2f5 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c | |||
| @@ -34,22 +34,44 @@ | |||
| 34 | * and CANNOT be re-allocated (eg: MMB0 and MMB1 both tied to RGB0). | 34 | * and CANNOT be re-allocated (eg: MMB0 and MMB1 both tied to RGB0). |
| 35 | * | 35 | * |
| 36 | * For each block that can be dynamically allocated, it can be either | 36 | * For each block that can be dynamically allocated, it can be either |
| 37 | * free, or pending/in-use by a client. The updates happen in three steps: | 37 | * free: |
| 38 | * The block is free. | ||
| 39 | * | ||
| 40 | * pending: | ||
| 41 | * The block is allocated to some client and not free. | ||
| 42 | * | ||
| 43 | * configured: | ||
| 44 | * The block is allocated to some client, and assigned to that | ||
| 45 | * client in MDP5_MDP_SMP_ALLOC registers. | ||
| 46 | * | ||
| 47 | * inuse: | ||
| 48 | * The block is being actively used by a client. | ||
| 49 | * | ||
| 50 | * The updates happen in the following steps: | ||
| 38 | * | 51 | * |
| 39 | * 1) mdp5_smp_request(): | 52 | * 1) mdp5_smp_request(): |
| 40 | * When plane scanout is setup, calculate required number of | 53 | * When plane scanout is setup, calculate required number of |
| 41 | * blocks needed per client, and request. Blocks not inuse or | 54 | * blocks needed per client, and request. Blocks neither inuse nor |
| 42 | * pending by any other client are added to client's pending | 55 | * configured nor pending by any other client are added to client's |
| 43 | * set. | 56 | * pending set. |
| 57 | * For shrinking, blocks in pending but not in configured can be freed | ||
| 58 | * directly, but those already in configured will be freed later by | ||
| 59 | * mdp5_smp_commit. | ||
| 44 | * | 60 | * |
| 45 | * 2) mdp5_smp_configure(): | 61 | * 2) mdp5_smp_configure(): |
| 46 | * As hw is programmed, before FLUSH, MDP5_MDP_SMP_ALLOC registers | 62 | * As hw is programmed, before FLUSH, MDP5_MDP_SMP_ALLOC registers |
| 47 | * are configured for the union(pending, inuse) | 63 | * are configured for the union(pending, inuse) |
| 64 | * Current pending is copied to configured. | ||
| 65 | * It is assumed that mdp5_smp_request and mdp5_smp_configure not run | ||
| 66 | * concurrently for the same pipe. | ||
| 48 | * | 67 | * |
| 49 | * 3) mdp5_smp_commit(): | 68 | * 3) mdp5_smp_commit(): |
| 50 | * After next vblank, copy pending -> inuse. Optionally update | 69 | * After next vblank, copy configured -> inuse. Optionally update |
| 51 | * MDP5_SMP_ALLOC registers if there are newly unused blocks | 70 | * MDP5_SMP_ALLOC registers if there are newly unused blocks |
| 52 | * | 71 | * |
| 72 | * 4) mdp5_smp_release(): | ||
| 73 | * Must be called after the pipe is disabled and no longer uses any SMB | ||
| 74 | * | ||
| 53 | * On the next vblank after changes have been committed to hw, the | 75 | * On the next vblank after changes have been committed to hw, the |
| 54 | * client's pending blocks become it's in-use blocks (and no-longer | 76 | * client's pending blocks become it's in-use blocks (and no-longer |
| 55 | * in-use blocks become available to other clients). | 77 | * in-use blocks become available to other clients). |
| @@ -77,6 +99,9 @@ struct mdp5_smp { | |||
| 77 | struct mdp5_client_smp_state client_state[MAX_CLIENTS]; | 99 | struct mdp5_client_smp_state client_state[MAX_CLIENTS]; |
| 78 | }; | 100 | }; |
| 79 | 101 | ||
| 102 | static void update_smp_state(struct mdp5_smp *smp, | ||
| 103 | u32 cid, mdp5_smp_state_t *assigned); | ||
| 104 | |||
| 80 | static inline | 105 | static inline |
| 81 | struct mdp5_kms *get_kms(struct mdp5_smp *smp) | 106 | struct mdp5_kms *get_kms(struct mdp5_smp *smp) |
| 82 | { | 107 | { |
| @@ -149,7 +174,12 @@ static int smp_request_block(struct mdp5_smp *smp, | |||
| 149 | for (i = cur_nblks; i > nblks; i--) { | 174 | for (i = cur_nblks; i > nblks; i--) { |
| 150 | int blk = find_first_bit(ps->pending, cnt); | 175 | int blk = find_first_bit(ps->pending, cnt); |
| 151 | clear_bit(blk, ps->pending); | 176 | clear_bit(blk, ps->pending); |
| 152 | /* don't clear in global smp_state until _commit() */ | 177 | |
| 178 | /* clear in global smp_state if not in configured | ||
| 179 | * otherwise until _commit() | ||
| 180 | */ | ||
| 181 | if (!test_bit(blk, ps->configured)) | ||
| 182 | clear_bit(blk, smp->state); | ||
| 153 | } | 183 | } |
| 154 | } | 184 | } |
| 155 | 185 | ||
| @@ -223,10 +253,33 @@ int mdp5_smp_request(struct mdp5_smp *smp, enum mdp5_pipe pipe, u32 fmt, u32 wid | |||
| 223 | /* Release SMP blocks for all clients of the pipe */ | 253 | /* Release SMP blocks for all clients of the pipe */ |
| 224 | void mdp5_smp_release(struct mdp5_smp *smp, enum mdp5_pipe pipe) | 254 | void mdp5_smp_release(struct mdp5_smp *smp, enum mdp5_pipe pipe) |
| 225 | { | 255 | { |
| 226 | int i, nblks; | 256 | int i; |
| 257 | unsigned long flags; | ||
| 258 | int cnt = smp->blk_cnt; | ||
| 259 | |||
| 260 | for (i = 0; i < pipe2nclients(pipe); i++) { | ||
| 261 | mdp5_smp_state_t assigned; | ||
| 262 | u32 cid = pipe2client(pipe, i); | ||
| 263 | struct mdp5_client_smp_state *ps = &smp->client_state[cid]; | ||
| 264 | |||
| 265 | spin_lock_irqsave(&smp->state_lock, flags); | ||
| 266 | |||
| 267 | /* clear hw assignment */ | ||
| 268 | bitmap_or(assigned, ps->inuse, ps->configured, cnt); | ||
| 269 | update_smp_state(smp, CID_UNUSED, &assigned); | ||
| 270 | |||
| 271 | /* free to global pool */ | ||
| 272 | bitmap_andnot(smp->state, smp->state, ps->pending, cnt); | ||
| 273 | bitmap_andnot(smp->state, smp->state, assigned, cnt); | ||
| 274 | |||
| 275 | /* clear client's infor */ | ||
| 276 | bitmap_zero(ps->pending, cnt); | ||
| 277 | bitmap_zero(ps->configured, cnt); | ||
| 278 | bitmap_zero(ps->inuse, cnt); | ||
| 279 | |||
| 280 | spin_unlock_irqrestore(&smp->state_lock, flags); | ||
| 281 | } | ||
| 227 | 282 | ||
| 228 | for (i = 0, nblks = 0; i < pipe2nclients(pipe); i++) | ||
| 229 | smp_request_block(smp, pipe2client(pipe, i), 0); | ||
| 230 | set_fifo_thresholds(smp, pipe, 0); | 283 | set_fifo_thresholds(smp, pipe, 0); |
| 231 | } | 284 | } |
| 232 | 285 | ||
| @@ -274,12 +327,20 @@ void mdp5_smp_configure(struct mdp5_smp *smp, enum mdp5_pipe pipe) | |||
| 274 | u32 cid = pipe2client(pipe, i); | 327 | u32 cid = pipe2client(pipe, i); |
| 275 | struct mdp5_client_smp_state *ps = &smp->client_state[cid]; | 328 | struct mdp5_client_smp_state *ps = &smp->client_state[cid]; |
| 276 | 329 | ||
| 277 | bitmap_or(assigned, ps->inuse, ps->pending, cnt); | 330 | /* |
| 331 | * if vblank has not happened since last smp_configure | ||
| 332 | * skip the configure for now | ||
| 333 | */ | ||
| 334 | if (!bitmap_equal(ps->inuse, ps->configured, cnt)) | ||
| 335 | continue; | ||
| 336 | |||
| 337 | bitmap_copy(ps->configured, ps->pending, cnt); | ||
| 338 | bitmap_or(assigned, ps->inuse, ps->configured, cnt); | ||
| 278 | update_smp_state(smp, cid, &assigned); | 339 | update_smp_state(smp, cid, &assigned); |
| 279 | } | 340 | } |
| 280 | } | 341 | } |
| 281 | 342 | ||
| 282 | /* step #3: after vblank, copy pending -> inuse: */ | 343 | /* step #3: after vblank, copy configured -> inuse: */ |
| 283 | void mdp5_smp_commit(struct mdp5_smp *smp, enum mdp5_pipe pipe) | 344 | void mdp5_smp_commit(struct mdp5_smp *smp, enum mdp5_pipe pipe) |
| 284 | { | 345 | { |
| 285 | int cnt = smp->blk_cnt; | 346 | int cnt = smp->blk_cnt; |
| @@ -295,7 +356,7 @@ void mdp5_smp_commit(struct mdp5_smp *smp, enum mdp5_pipe pipe) | |||
| 295 | * using, which can be released and made available to other | 356 | * using, which can be released and made available to other |
| 296 | * clients: | 357 | * clients: |
| 297 | */ | 358 | */ |
| 298 | if (bitmap_andnot(released, ps->inuse, ps->pending, cnt)) { | 359 | if (bitmap_andnot(released, ps->inuse, ps->configured, cnt)) { |
| 299 | unsigned long flags; | 360 | unsigned long flags; |
| 300 | 361 | ||
| 301 | spin_lock_irqsave(&smp->state_lock, flags); | 362 | spin_lock_irqsave(&smp->state_lock, flags); |
| @@ -306,7 +367,7 @@ void mdp5_smp_commit(struct mdp5_smp *smp, enum mdp5_pipe pipe) | |||
| 306 | update_smp_state(smp, CID_UNUSED, &released); | 367 | update_smp_state(smp, CID_UNUSED, &released); |
| 307 | } | 368 | } |
| 308 | 369 | ||
| 309 | bitmap_copy(ps->inuse, ps->pending, cnt); | 370 | bitmap_copy(ps->inuse, ps->configured, cnt); |
| 310 | } | 371 | } |
| 311 | } | 372 | } |
| 312 | 373 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h index e47179f63585..5b6c2363f592 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | struct mdp5_client_smp_state { | 24 | struct mdp5_client_smp_state { |
| 25 | mdp5_smp_state_t inuse; | 25 | mdp5_smp_state_t inuse; |
| 26 | mdp5_smp_state_t configured; | ||
| 26 | mdp5_smp_state_t pending; | 27 | mdp5_smp_state_t pending; |
| 27 | }; | 28 | }; |
| 28 | 29 | ||
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 1b22d8bfe142..1ceb4f22dd89 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c | |||
| @@ -283,12 +283,8 @@ int msm_atomic_commit(struct drm_device *dev, | |||
| 283 | 283 | ||
| 284 | timeout = ktime_add_ms(ktime_get(), 1000); | 284 | timeout = ktime_add_ms(ktime_get(), 1000); |
| 285 | 285 | ||
| 286 | ret = msm_wait_fence_interruptable(dev, c->fence, &timeout); | 286 | /* uninterruptible wait */ |
| 287 | if (ret) { | 287 | msm_wait_fence(dev, c->fence, &timeout, false); |
| 288 | WARN_ON(ret); // TODO unswap state back? or?? | ||
| 289 | commit_destroy(c); | ||
| 290 | return ret; | ||
| 291 | } | ||
| 292 | 288 | ||
| 293 | complete_commit(c); | 289 | complete_commit(c); |
| 294 | 290 | ||
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b7ef56ed8d1c..d3467b115e04 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
| @@ -637,8 +637,8 @@ static void msm_debugfs_cleanup(struct drm_minor *minor) | |||
| 637 | * Fences: | 637 | * Fences: |
| 638 | */ | 638 | */ |
| 639 | 639 | ||
| 640 | int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, | 640 | int msm_wait_fence(struct drm_device *dev, uint32_t fence, |
| 641 | ktime_t *timeout) | 641 | ktime_t *timeout , bool interruptible) |
| 642 | { | 642 | { |
| 643 | struct msm_drm_private *priv = dev->dev_private; | 643 | struct msm_drm_private *priv = dev->dev_private; |
| 644 | int ret; | 644 | int ret; |
| @@ -667,7 +667,12 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, | |||
| 667 | remaining_jiffies = timespec_to_jiffies(&ts); | 667 | remaining_jiffies = timespec_to_jiffies(&ts); |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | ret = wait_event_interruptible_timeout(priv->fence_event, | 670 | if (interruptible) |
| 671 | ret = wait_event_interruptible_timeout(priv->fence_event, | ||
| 672 | fence_completed(dev, fence), | ||
| 673 | remaining_jiffies); | ||
| 674 | else | ||
| 675 | ret = wait_event_timeout(priv->fence_event, | ||
| 671 | fence_completed(dev, fence), | 676 | fence_completed(dev, fence), |
| 672 | remaining_jiffies); | 677 | remaining_jiffies); |
| 673 | 678 | ||
| @@ -853,7 +858,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, | |||
| 853 | return -EINVAL; | 858 | return -EINVAL; |
| 854 | } | 859 | } |
| 855 | 860 | ||
| 856 | return msm_wait_fence_interruptable(dev, args->fence, &timeout); | 861 | return msm_wait_fence(dev, args->fence, &timeout, true); |
| 857 | } | 862 | } |
| 858 | 863 | ||
| 859 | static const struct drm_ioctl_desc msm_ioctls[] = { | 864 | static const struct drm_ioctl_desc msm_ioctls[] = { |
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index e7c5ea125d45..4ff0ec9c994b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h | |||
| @@ -164,8 +164,8 @@ int msm_atomic_commit(struct drm_device *dev, | |||
| 164 | 164 | ||
| 165 | int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); | 165 | int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); |
| 166 | 166 | ||
| 167 | int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, | 167 | int msm_wait_fence(struct drm_device *dev, uint32_t fence, |
| 168 | ktime_t *timeout); | 168 | ktime_t *timeout, bool interruptible); |
| 169 | int msm_queue_fence_cb(struct drm_device *dev, | 169 | int msm_queue_fence_cb(struct drm_device *dev, |
| 170 | struct msm_fence_cb *cb, uint32_t fence); | 170 | struct msm_fence_cb *cb, uint32_t fence); |
| 171 | void msm_update_fence(struct drm_device *dev, uint32_t fence); | 171 | void msm_update_fence(struct drm_device *dev, uint32_t fence); |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index f211b80e3a1e..c76cc853b08a 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
| @@ -460,7 +460,7 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout) | |||
| 460 | if (op & MSM_PREP_NOSYNC) | 460 | if (op & MSM_PREP_NOSYNC) |
| 461 | timeout = NULL; | 461 | timeout = NULL; |
| 462 | 462 | ||
| 463 | ret = msm_wait_fence_interruptable(dev, fence, timeout); | 463 | ret = msm_wait_fence(dev, fence, timeout, true); |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | /* TODO cache maintenance */ | 466 | /* TODO cache maintenance */ |
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c index dd7a7ab603e2..831461bc98a5 100644 --- a/drivers/gpu/drm/msm/msm_gem_prime.c +++ b/drivers/gpu/drm/msm/msm_gem_prime.c | |||
| @@ -23,8 +23,12 @@ | |||
| 23 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) | 23 | struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) |
| 24 | { | 24 | { |
| 25 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | 25 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 26 | BUG_ON(!msm_obj->sgt); /* should have already pinned! */ | 26 | int npages = obj->size >> PAGE_SHIFT; |
| 27 | return msm_obj->sgt; | 27 | |
| 28 | if (WARN_ON(!msm_obj->pages)) /* should have already pinned! */ | ||
| 29 | return NULL; | ||
| 30 | |||
| 31 | return drm_prime_pages_to_sg(msm_obj->pages, npages); | ||
| 28 | } | 32 | } |
| 29 | 33 | ||
| 30 | void *msm_gem_prime_vmap(struct drm_gem_object *obj) | 34 | void *msm_gem_prime_vmap(struct drm_gem_object *obj) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 36b40c9252b5..109b8262dc85 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
| @@ -128,6 +128,7 @@ nouveau_cli_destroy(struct nouveau_cli *cli) | |||
| 128 | nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL); | 128 | nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL); |
| 129 | nvif_client_fini(&cli->base); | 129 | nvif_client_fini(&cli->base); |
| 130 | usif_client_fini(cli); | 130 | usif_client_fini(cli); |
| 131 | kfree(cli); | ||
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | static void | 134 | static void |
| @@ -865,8 +866,10 @@ nouveau_drm_preclose(struct drm_device *dev, struct drm_file *fpriv) | |||
| 865 | 866 | ||
| 866 | pm_runtime_get_sync(dev->dev); | 867 | pm_runtime_get_sync(dev->dev); |
| 867 | 868 | ||
| 869 | mutex_lock(&cli->mutex); | ||
| 868 | if (cli->abi16) | 870 | if (cli->abi16) |
| 869 | nouveau_abi16_fini(cli->abi16); | 871 | nouveau_abi16_fini(cli->abi16); |
| 872 | mutex_unlock(&cli->mutex); | ||
| 870 | 873 | ||
| 871 | mutex_lock(&drm->client.mutex); | 874 | mutex_lock(&drm->client.mutex); |
| 872 | list_del(&cli->head); | 875 | list_del(&cli->head); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c index 775277f1edb0..dcfbbfaf1739 100644 --- a/drivers/gpu/drm/nouveau/nouveau_platform.c +++ b/drivers/gpu/drm/nouveau/nouveau_platform.c | |||
| @@ -92,6 +92,8 @@ static int nouveau_platform_power_down(struct nouveau_platform_gpu *gpu) | |||
| 92 | return 0; | 92 | return 0; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | #if IS_ENABLED(CONFIG_IOMMU_API) | ||
| 96 | |||
| 95 | static void nouveau_platform_probe_iommu(struct device *dev, | 97 | static void nouveau_platform_probe_iommu(struct device *dev, |
| 96 | struct nouveau_platform_gpu *gpu) | 98 | struct nouveau_platform_gpu *gpu) |
| 97 | { | 99 | { |
| @@ -158,6 +160,20 @@ static void nouveau_platform_remove_iommu(struct device *dev, | |||
| 158 | } | 160 | } |
| 159 | } | 161 | } |
| 160 | 162 | ||
| 163 | #else | ||
| 164 | |||
| 165 | static void nouveau_platform_probe_iommu(struct device *dev, | ||
| 166 | struct nouveau_platform_gpu *gpu) | ||
| 167 | { | ||
| 168 | } | ||
| 169 | |||
| 170 | static void nouveau_platform_remove_iommu(struct device *dev, | ||
| 171 | struct nouveau_platform_gpu *gpu) | ||
| 172 | { | ||
| 173 | } | ||
| 174 | |||
| 175 | #endif | ||
| 176 | |||
| 161 | static int nouveau_platform_probe(struct platform_device *pdev) | 177 | static int nouveau_platform_probe(struct platform_device *pdev) |
| 162 | { | 178 | { |
| 163 | struct nouveau_platform_gpu *gpu; | 179 | struct nouveau_platform_gpu *gpu; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 1f8ec0e2156c..737e8f976a98 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
| @@ -175,15 +175,24 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, | |||
| 175 | node->page_shift = 12; | 175 | node->page_shift = 12; |
| 176 | 176 | ||
| 177 | switch (drm->device.info.family) { | 177 | switch (drm->device.info.family) { |
| 178 | case NV_DEVICE_INFO_V0_TNT: | ||
| 179 | case NV_DEVICE_INFO_V0_CELSIUS: | ||
| 180 | case NV_DEVICE_INFO_V0_KELVIN: | ||
| 181 | case NV_DEVICE_INFO_V0_RANKINE: | ||
| 182 | case NV_DEVICE_INFO_V0_CURIE: | ||
| 183 | break; | ||
| 178 | case NV_DEVICE_INFO_V0_TESLA: | 184 | case NV_DEVICE_INFO_V0_TESLA: |
| 179 | if (drm->device.info.chipset != 0x50) | 185 | if (drm->device.info.chipset != 0x50) |
| 180 | node->memtype = (nvbo->tile_flags & 0x7f00) >> 8; | 186 | node->memtype = (nvbo->tile_flags & 0x7f00) >> 8; |
| 181 | break; | 187 | break; |
| 182 | case NV_DEVICE_INFO_V0_FERMI: | 188 | case NV_DEVICE_INFO_V0_FERMI: |
| 183 | case NV_DEVICE_INFO_V0_KEPLER: | 189 | case NV_DEVICE_INFO_V0_KEPLER: |
| 190 | case NV_DEVICE_INFO_V0_MAXWELL: | ||
| 184 | node->memtype = (nvbo->tile_flags & 0xff00) >> 8; | 191 | node->memtype = (nvbo->tile_flags & 0xff00) >> 8; |
| 185 | break; | 192 | break; |
| 186 | default: | 193 | default: |
| 194 | NV_WARN(drm, "%s: unhandled family type %x\n", __func__, | ||
| 195 | drm->device.info.family); | ||
| 187 | break; | 196 | break; |
| 188 | } | 197 | } |
| 189 | 198 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 4ef602c5469d..495c57644ced 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c | |||
| @@ -203,7 +203,7 @@ nv04_fbcon_accel_init(struct fb_info *info) | |||
| 203 | if (ret) | 203 | if (ret) |
| 204 | return ret; | 204 | return ret; |
| 205 | 205 | ||
| 206 | if (RING_SPACE(chan, 49)) { | 206 | if (RING_SPACE(chan, 49 + (device->info.chipset >= 0x11 ? 4 : 0))) { |
| 207 | nouveau_fbcon_gpu_lockup(info); | 207 | nouveau_fbcon_gpu_lockup(info); |
| 208 | return 0; | 208 | return 0; |
| 209 | } | 209 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 7da7958556a3..981342d142ff 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
| @@ -979,7 +979,7 @@ nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update) | |||
| 979 | { | 979 | { |
| 980 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); | 980 | struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); |
| 981 | 981 | ||
| 982 | if (show && nv_crtc->cursor.nvbo) | 982 | if (show && nv_crtc->cursor.nvbo && nv_crtc->base.enabled) |
| 983 | nv50_crtc_cursor_show(nv_crtc); | 983 | nv50_crtc_cursor_show(nv_crtc); |
| 984 | else | 984 | else |
| 985 | nv50_crtc_cursor_hide(nv_crtc); | 985 | nv50_crtc_cursor_hide(nv_crtc); |
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 394c89abcc97..901130b06072 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
| @@ -188,7 +188,7 @@ nv50_fbcon_accel_init(struct fb_info *info) | |||
| 188 | if (ret) | 188 | if (ret) |
| 189 | return ret; | 189 | return ret; |
| 190 | 190 | ||
| 191 | ret = RING_SPACE(chan, 59); | 191 | ret = RING_SPACE(chan, 58); |
| 192 | if (ret) { | 192 | if (ret) { |
| 193 | nouveau_fbcon_gpu_lockup(info); | 193 | nouveau_fbcon_gpu_lockup(info); |
| 194 | return ret; | 194 | return ret; |
| @@ -252,6 +252,7 @@ nv50_fbcon_accel_init(struct fb_info *info) | |||
| 252 | OUT_RING(chan, info->var.yres_virtual); | 252 | OUT_RING(chan, info->var.yres_virtual); |
| 253 | OUT_RING(chan, upper_32_bits(fb->vma.offset)); | 253 | OUT_RING(chan, upper_32_bits(fb->vma.offset)); |
| 254 | OUT_RING(chan, lower_32_bits(fb->vma.offset)); | 254 | OUT_RING(chan, lower_32_bits(fb->vma.offset)); |
| 255 | FIRE_RING(chan); | ||
| 255 | 256 | ||
| 256 | return 0; | 257 | return 0; |
| 257 | } | 258 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index 61246677e8dc..fcd2e5f27bb9 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c | |||
| @@ -188,7 +188,7 @@ nvc0_fbcon_accel_init(struct fb_info *info) | |||
| 188 | return -EINVAL; | 188 | return -EINVAL; |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | ret = RING_SPACE(chan, 60); | 191 | ret = RING_SPACE(chan, 58); |
| 192 | if (ret) { | 192 | if (ret) { |
| 193 | WARN_ON(1); | 193 | WARN_ON(1); |
| 194 | nouveau_fbcon_gpu_lockup(info); | 194 | nouveau_fbcon_gpu_lockup(info); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c index 9ef6728c528d..7f2f05f78cc8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf110.c | |||
| @@ -809,7 +809,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl, | |||
| 809 | case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break; | 809 | case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break; |
| 810 | default: | 810 | default: |
| 811 | nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl); | 811 | nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl); |
| 812 | return 0x0000; | 812 | return NULL; |
| 813 | } | 813 | } |
| 814 | } | 814 | } |
| 815 | 815 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 5606c25e5d02..ca11ddb6ed46 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | |||
| @@ -663,6 +663,37 @@ gf100_gr_zbc_init(struct gf100_gr_priv *priv) | |||
| 663 | gf100_gr_zbc_clear_depth(priv, index); | 663 | gf100_gr_zbc_clear_depth(priv, index); |
| 664 | } | 664 | } |
| 665 | 665 | ||
| 666 | /** | ||
| 667 | * Wait until GR goes idle. GR is considered idle if it is disabled by the | ||
| 668 | * MC (0x200) register, or GR is not busy and a context switch is not in | ||
| 669 | * progress. | ||
| 670 | */ | ||
| 671 | int | ||
| 672 | gf100_gr_wait_idle(struct gf100_gr_priv *priv) | ||
| 673 | { | ||
| 674 | unsigned long end_jiffies = jiffies + msecs_to_jiffies(2000); | ||
| 675 | bool gr_enabled, ctxsw_active, gr_busy; | ||
| 676 | |||
| 677 | do { | ||
| 678 | /* | ||
| 679 | * required to make sure FIFO_ENGINE_STATUS (0x2640) is | ||
| 680 | * up-to-date | ||
| 681 | */ | ||
| 682 | nv_rd32(priv, 0x400700); | ||
| 683 | |||
| 684 | gr_enabled = nv_rd32(priv, 0x200) & 0x1000; | ||
| 685 | ctxsw_active = nv_rd32(priv, 0x2640) & 0x8000; | ||
| 686 | gr_busy = nv_rd32(priv, 0x40060c) & 0x1; | ||
| 687 | |||
| 688 | if (!gr_enabled || (!gr_busy && !ctxsw_active)) | ||
| 689 | return 0; | ||
| 690 | } while (time_before(jiffies, end_jiffies)); | ||
| 691 | |||
| 692 | nv_error(priv, "wait for idle timeout (en: %d, ctxsw: %d, busy: %d)\n", | ||
| 693 | gr_enabled, ctxsw_active, gr_busy); | ||
| 694 | return -EAGAIN; | ||
| 695 | } | ||
| 696 | |||
| 666 | void | 697 | void |
| 667 | gf100_gr_mmio(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) | 698 | gf100_gr_mmio(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) |
| 668 | { | 699 | { |
| @@ -699,7 +730,13 @@ gf100_gr_icmd(struct gf100_gr_priv *priv, const struct gf100_gr_pack *p) | |||
| 699 | 730 | ||
| 700 | while (addr < next) { | 731 | while (addr < next) { |
| 701 | nv_wr32(priv, 0x400200, addr); | 732 | nv_wr32(priv, 0x400200, addr); |
| 702 | nv_wait(priv, 0x400700, 0x00000002, 0x00000000); | 733 | /** |
| 734 | * Wait for GR to go idle after submitting a | ||
| 735 | * GO_IDLE bundle | ||
| 736 | */ | ||
| 737 | if ((addr & 0xffff) == 0xe100) | ||
| 738 | gf100_gr_wait_idle(priv); | ||
| 739 | nv_wait(priv, 0x400700, 0x00000004, 0x00000000); | ||
| 703 | addr += init->pitch; | 740 | addr += init->pitch; |
| 704 | } | 741 | } |
| 705 | } | 742 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 8af1a89eda84..c9533fdac4fc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h | |||
| @@ -181,6 +181,7 @@ struct gf100_gr_oclass { | |||
| 181 | int ppc_nr; | 181 | int ppc_nr; |
| 182 | }; | 182 | }; |
| 183 | 183 | ||
| 184 | int gf100_gr_wait_idle(struct gf100_gr_priv *); | ||
| 184 | void gf100_gr_mmio(struct gf100_gr_priv *, const struct gf100_gr_pack *); | 185 | void gf100_gr_mmio(struct gf100_gr_priv *, const struct gf100_gr_pack *); |
| 185 | void gf100_gr_icmd(struct gf100_gr_priv *, const struct gf100_gr_pack *); | 186 | void gf100_gr_icmd(struct gf100_gr_priv *, const struct gf100_gr_pack *); |
| 186 | void gf100_gr_mthd(struct gf100_gr_priv *, const struct gf100_gr_pack *); | 187 | void gf100_gr_mthd(struct gf100_gr_priv *, const struct gf100_gr_pack *); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c index 2006c445938d..4cf36a3aa814 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c | |||
| @@ -332,9 +332,12 @@ static void | |||
| 332 | nvkm_perfctx_dtor(struct nvkm_object *object) | 332 | nvkm_perfctx_dtor(struct nvkm_object *object) |
| 333 | { | 333 | { |
| 334 | struct nvkm_pm *ppm = (void *)object->engine; | 334 | struct nvkm_pm *ppm = (void *)object->engine; |
| 335 | struct nvkm_perfctx *ctx = (void *)object; | ||
| 336 | |||
| 335 | mutex_lock(&nv_subdev(ppm)->mutex); | 337 | mutex_lock(&nv_subdev(ppm)->mutex); |
| 336 | nvkm_engctx_destroy(&ppm->context->base); | 338 | nvkm_engctx_destroy(&ctx->base); |
| 337 | ppm->context = NULL; | 339 | if (ppm->context == ctx) |
| 340 | ppm->context = NULL; | ||
| 338 | mutex_unlock(&nv_subdev(ppm)->mutex); | 341 | mutex_unlock(&nv_subdev(ppm)->mutex); |
| 339 | } | 342 | } |
| 340 | 343 | ||
| @@ -355,12 +358,11 @@ nvkm_perfctx_ctor(struct nvkm_object *parent, struct nvkm_object *engine, | |||
| 355 | mutex_lock(&nv_subdev(ppm)->mutex); | 358 | mutex_lock(&nv_subdev(ppm)->mutex); |
| 356 | if (ppm->context == NULL) | 359 | if (ppm->context == NULL) |
| 357 | ppm->context = ctx; | 360 | ppm->context = ctx; |
| 358 | mutex_unlock(&nv_subdev(ppm)->mutex); | ||
| 359 | |||
| 360 | if (ctx != ppm->context) | 361 | if (ctx != ppm->context) |
| 361 | return -EBUSY; | 362 | ret = -EBUSY; |
| 363 | mutex_unlock(&nv_subdev(ppm)->mutex); | ||
| 362 | 364 | ||
| 363 | return 0; | 365 | return ret; |
| 364 | } | 366 | } |
| 365 | 367 | ||
| 366 | struct nvkm_oclass | 368 | struct nvkm_oclass |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c index f67cdae1e90a..f4611e3f0971 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | |||
| @@ -1285,6 +1285,44 @@ init_zm_reg_sequence(struct nvbios_init *init) | |||
| 1285 | } | 1285 | } |
| 1286 | 1286 | ||
| 1287 | /** | 1287 | /** |
| 1288 | * INIT_PLL_INDIRECT - opcode 0x59 | ||
| 1289 | * | ||
| 1290 | */ | ||
| 1291 | static void | ||
| 1292 | init_pll_indirect(struct nvbios_init *init) | ||
| 1293 | { | ||
| 1294 | struct nvkm_bios *bios = init->bios; | ||
| 1295 | u32 reg = nv_ro32(bios, init->offset + 1); | ||
| 1296 | u16 addr = nv_ro16(bios, init->offset + 5); | ||
| 1297 | u32 freq = (u32)nv_ro16(bios, addr) * 1000; | ||
| 1298 | |||
| 1299 | trace("PLL_INDIRECT\tR[0x%06x] =PLL= VBIOS[%04x] = %dkHz\n", | ||
| 1300 | reg, addr, freq); | ||
| 1301 | init->offset += 7; | ||
| 1302 | |||
| 1303 | init_prog_pll(init, reg, freq); | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | /** | ||
| 1307 | * INIT_ZM_REG_INDIRECT - opcode 0x5a | ||
| 1308 | * | ||
| 1309 | */ | ||
| 1310 | static void | ||
| 1311 | init_zm_reg_indirect(struct nvbios_init *init) | ||
| 1312 | { | ||
| 1313 | struct nvkm_bios *bios = init->bios; | ||
| 1314 | u32 reg = nv_ro32(bios, init->offset + 1); | ||
| 1315 | u16 addr = nv_ro16(bios, init->offset + 5); | ||
| 1316 | u32 data = nv_ro32(bios, addr); | ||
| 1317 | |||
| 1318 | trace("ZM_REG_INDIRECT\tR[0x%06x] = VBIOS[0x%04x] = 0x%08x\n", | ||
| 1319 | reg, addr, data); | ||
| 1320 | init->offset += 7; | ||
| 1321 | |||
| 1322 | init_wr32(init, addr, data); | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | /** | ||
| 1288 | * INIT_SUB_DIRECT - opcode 0x5b | 1326 | * INIT_SUB_DIRECT - opcode 0x5b |
| 1289 | * | 1327 | * |
| 1290 | */ | 1328 | */ |
| @@ -2145,6 +2183,8 @@ static struct nvbios_init_opcode { | |||
| 2145 | [0x56] = { init_condition_time }, | 2183 | [0x56] = { init_condition_time }, |
| 2146 | [0x57] = { init_ltime }, | 2184 | [0x57] = { init_ltime }, |
| 2147 | [0x58] = { init_zm_reg_sequence }, | 2185 | [0x58] = { init_zm_reg_sequence }, |
| 2186 | [0x59] = { init_pll_indirect }, | ||
| 2187 | [0x5a] = { init_zm_reg_indirect }, | ||
| 2148 | [0x5b] = { init_sub_direct }, | 2188 | [0x5b] = { init_sub_direct }, |
| 2149 | [0x5c] = { init_jump }, | 2189 | [0x5c] = { init_jump }, |
| 2150 | [0x5e] = { init_i2c_if }, | 2190 | [0x5e] = { init_i2c_if }, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c index 822d32a28d6e..065e9f5c8db9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c | |||
| @@ -180,7 +180,8 @@ gt215_clk_info(struct nvkm_clk *clock, int clk, u32 khz, | |||
| 180 | struct gt215_clk_info *info) | 180 | struct gt215_clk_info *info) |
| 181 | { | 181 | { |
| 182 | struct gt215_clk_priv *priv = (void *)clock; | 182 | struct gt215_clk_priv *priv = (void *)clock; |
| 183 | u32 oclk, sclk, sdiv, diff; | 183 | u32 oclk, sclk, sdiv; |
| 184 | s32 diff; | ||
| 184 | 185 | ||
| 185 | info->clk = 0; | 186 | info->clk = 0; |
| 186 | 187 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c index c0fdb89e74ac..24dcdfb58a8d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c | |||
| @@ -38,6 +38,14 @@ gk20a_ibus_init_priv_ring(struct gk20a_ibus_priv *priv) | |||
| 38 | nv_wr32(priv, 0x12004c, 0x4); | 38 | nv_wr32(priv, 0x12004c, 0x4); |
| 39 | nv_wr32(priv, 0x122204, 0x2); | 39 | nv_wr32(priv, 0x122204, 0x2); |
| 40 | nv_rd32(priv, 0x122204); | 40 | nv_rd32(priv, 0x122204); |
| 41 | |||
| 42 | /* | ||
| 43 | * Bug: increase clock timeout to avoid operation failure at high | ||
| 44 | * gpcclk rate. | ||
| 45 | */ | ||
| 46 | nv_wr32(priv, 0x122354, 0x800); | ||
| 47 | nv_wr32(priv, 0x128328, 0x800); | ||
| 48 | nv_wr32(priv, 0x124320, 0x800); | ||
| 41 | } | 49 | } |
| 42 | 50 | ||
| 43 | static void | 51 | static void |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index 80614f1b2074..282143f49d72 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c | |||
| @@ -50,7 +50,12 @@ nv04_instobj_dtor(struct nvkm_object *object) | |||
| 50 | { | 50 | { |
| 51 | struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object); | 51 | struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object); |
| 52 | struct nv04_instobj_priv *node = (void *)object; | 52 | struct nv04_instobj_priv *node = (void *)object; |
| 53 | struct nvkm_subdev *subdev = (void *)priv; | ||
| 54 | |||
| 55 | mutex_lock(&subdev->mutex); | ||
| 53 | nvkm_mm_free(&priv->heap, &node->mem); | 56 | nvkm_mm_free(&priv->heap, &node->mem); |
| 57 | mutex_unlock(&subdev->mutex); | ||
| 58 | |||
| 54 | nvkm_instobj_destroy(&node->base); | 59 | nvkm_instobj_destroy(&node->base); |
| 55 | } | 60 | } |
| 56 | 61 | ||
| @@ -62,6 +67,7 @@ nv04_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine, | |||
| 62 | struct nv04_instmem_priv *priv = (void *)nvkm_instmem(parent); | 67 | struct nv04_instmem_priv *priv = (void *)nvkm_instmem(parent); |
| 63 | struct nv04_instobj_priv *node; | 68 | struct nv04_instobj_priv *node; |
| 64 | struct nvkm_instobj_args *args = data; | 69 | struct nvkm_instobj_args *args = data; |
| 70 | struct nvkm_subdev *subdev = (void *)priv; | ||
| 65 | int ret; | 71 | int ret; |
| 66 | 72 | ||
| 67 | if (!args->align) | 73 | if (!args->align) |
| @@ -72,8 +78,10 @@ nv04_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine, | |||
| 72 | if (ret) | 78 | if (ret) |
| 73 | return ret; | 79 | return ret; |
| 74 | 80 | ||
| 81 | mutex_lock(&subdev->mutex); | ||
| 75 | ret = nvkm_mm_head(&priv->heap, 0, 1, args->size, args->size, | 82 | ret = nvkm_mm_head(&priv->heap, 0, 1, args->size, args->size, |
| 76 | args->align, &node->mem); | 83 | args->align, &node->mem); |
| 84 | mutex_unlock(&subdev->mutex); | ||
| 77 | if (ret) | 85 | if (ret) |
| 78 | return ret; | 86 | return ret; |
| 79 | 87 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index dd39f434b4a7..c3872598b85a 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -2299,8 +2299,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 2299 | encoder_mode = atombios_get_encoder_mode(encoder); | 2299 | encoder_mode = atombios_get_encoder_mode(encoder); |
| 2300 | if (connector && (radeon_audio != 0) && | 2300 | if (connector && (radeon_audio != 0) && |
| 2301 | ((encoder_mode == ATOM_ENCODER_MODE_HDMI) || | 2301 | ((encoder_mode == ATOM_ENCODER_MODE_HDMI) || |
| 2302 | (ENCODER_MODE_IS_DP(encoder_mode) && | 2302 | ENCODER_MODE_IS_DP(encoder_mode))) |
| 2303 | drm_detect_monitor_audio(radeon_connector_edid(connector))))) | ||
| 2304 | radeon_audio_mode_set(encoder, adjusted_mode); | 2303 | radeon_audio_mode_set(encoder, adjusted_mode); |
| 2305 | } | 2304 | } |
| 2306 | 2305 | ||
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 68fd9fc677e3..44480c1b9738 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
| @@ -93,30 +93,26 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder) | |||
| 93 | struct radeon_device *rdev = encoder->dev->dev_private; | 93 | struct radeon_device *rdev = encoder->dev->dev_private; |
| 94 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 94 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 95 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 95 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 96 | u32 offset; | ||
| 97 | 96 | ||
| 98 | if (!dig || !dig->afmt || !dig->afmt->pin) | 97 | if (!dig || !dig->afmt || !dig->pin) |
| 99 | return; | 98 | return; |
| 100 | 99 | ||
| 101 | offset = dig->afmt->offset; | 100 | WREG32(AFMT_AUDIO_SRC_CONTROL + dig->afmt->offset, |
| 102 | 101 | AFMT_AUDIO_SRC_SELECT(dig->pin->id)); | |
| 103 | WREG32(AFMT_AUDIO_SRC_CONTROL + offset, | ||
| 104 | AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id)); | ||
| 105 | } | 102 | } |
| 106 | 103 | ||
| 107 | void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | 104 | void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, |
| 108 | struct drm_connector *connector, struct drm_display_mode *mode) | 105 | struct drm_connector *connector, |
| 106 | struct drm_display_mode *mode) | ||
| 109 | { | 107 | { |
| 110 | struct radeon_device *rdev = encoder->dev->dev_private; | 108 | struct radeon_device *rdev = encoder->dev->dev_private; |
| 111 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 109 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 112 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 110 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 113 | u32 tmp = 0, offset; | 111 | u32 tmp = 0; |
| 114 | 112 | ||
| 115 | if (!dig || !dig->afmt || !dig->afmt->pin) | 113 | if (!dig || !dig->afmt || !dig->pin) |
| 116 | return; | 114 | return; |
| 117 | 115 | ||
| 118 | offset = dig->afmt->pin->offset; | ||
| 119 | |||
| 120 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { | 116 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { |
| 121 | if (connector->latency_present[1]) | 117 | if (connector->latency_present[1]) |
| 122 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | | 118 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | |
| @@ -130,24 +126,24 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | |||
| 130 | else | 126 | else |
| 131 | tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0); | 127 | tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0); |
| 132 | } | 128 | } |
| 133 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); | 129 | WREG32_ENDPOINT(dig->pin->offset, |
| 130 | AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); | ||
| 134 | } | 131 | } |
| 135 | 132 | ||
| 136 | void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, | 133 | void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, |
| 137 | u8 *sadb, int sad_count) | 134 | u8 *sadb, int sad_count) |
| 138 | { | 135 | { |
| 139 | struct radeon_device *rdev = encoder->dev->dev_private; | 136 | struct radeon_device *rdev = encoder->dev->dev_private; |
| 140 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 137 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 141 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 138 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 142 | u32 offset, tmp; | 139 | u32 tmp; |
| 143 | 140 | ||
| 144 | if (!dig || !dig->afmt || !dig->afmt->pin) | 141 | if (!dig || !dig->afmt || !dig->pin) |
| 145 | return; | 142 | return; |
| 146 | 143 | ||
| 147 | offset = dig->afmt->pin->offset; | ||
| 148 | |||
| 149 | /* program the speaker allocation */ | 144 | /* program the speaker allocation */ |
| 150 | tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | 145 | tmp = RREG32_ENDPOINT(dig->pin->offset, |
| 146 | AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | ||
| 151 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); | 147 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); |
| 152 | /* set HDMI mode */ | 148 | /* set HDMI mode */ |
| 153 | tmp |= HDMI_CONNECTION; | 149 | tmp |= HDMI_CONNECTION; |
| @@ -155,24 +151,24 @@ void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, | |||
| 155 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | 151 | tmp |= SPEAKER_ALLOCATION(sadb[0]); |
| 156 | else | 152 | else |
| 157 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | 153 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
| 158 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | 154 | WREG32_ENDPOINT(dig->pin->offset, |
| 155 | AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | ||
| 159 | } | 156 | } |
| 160 | 157 | ||
| 161 | void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, | 158 | void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, |
| 162 | u8 *sadb, int sad_count) | 159 | u8 *sadb, int sad_count) |
| 163 | { | 160 | { |
| 164 | struct radeon_device *rdev = encoder->dev->dev_private; | 161 | struct radeon_device *rdev = encoder->dev->dev_private; |
| 165 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 162 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 166 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 163 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 167 | u32 offset, tmp; | 164 | u32 tmp; |
| 168 | 165 | ||
| 169 | if (!dig || !dig->afmt || !dig->afmt->pin) | 166 | if (!dig || !dig->afmt || !dig->pin) |
| 170 | return; | 167 | return; |
| 171 | 168 | ||
| 172 | offset = dig->afmt->pin->offset; | ||
| 173 | |||
| 174 | /* program the speaker allocation */ | 169 | /* program the speaker allocation */ |
| 175 | tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | 170 | tmp = RREG32_ENDPOINT(dig->pin->offset, |
| 171 | AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); | ||
| 176 | tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); | 172 | tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); |
| 177 | /* set DP mode */ | 173 | /* set DP mode */ |
| 178 | tmp |= DP_CONNECTION; | 174 | tmp |= DP_CONNECTION; |
| @@ -180,13 +176,13 @@ void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, | |||
| 180 | tmp |= SPEAKER_ALLOCATION(sadb[0]); | 176 | tmp |= SPEAKER_ALLOCATION(sadb[0]); |
| 181 | else | 177 | else |
| 182 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ | 178 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
| 183 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | 179 | WREG32_ENDPOINT(dig->pin->offset, |
| 180 | AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); | ||
| 184 | } | 181 | } |
| 185 | 182 | ||
| 186 | void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, | 183 | void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, |
| 187 | struct cea_sad *sads, int sad_count) | 184 | struct cea_sad *sads, int sad_count) |
| 188 | { | 185 | { |
| 189 | u32 offset; | ||
| 190 | int i; | 186 | int i; |
| 191 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 187 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 192 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 188 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| @@ -206,11 +202,9 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, | |||
| 206 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, | 202 | { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, |
| 207 | }; | 203 | }; |
| 208 | 204 | ||
| 209 | if (!dig || !dig->afmt || !dig->afmt->pin) | 205 | if (!dig || !dig->afmt || !dig->pin) |
| 210 | return; | 206 | return; |
| 211 | 207 | ||
| 212 | offset = dig->afmt->pin->offset; | ||
| 213 | |||
| 214 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { | 208 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
| 215 | u32 value = 0; | 209 | u32 value = 0; |
| 216 | u8 stereo_freqs = 0; | 210 | u8 stereo_freqs = 0; |
| @@ -237,7 +231,7 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, | |||
| 237 | 231 | ||
| 238 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); | 232 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); |
| 239 | 233 | ||
| 240 | WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); | 234 | WREG32_ENDPOINT(dig->pin->offset, eld_reg_to_type[i][0], value); |
| 241 | } | 235 | } |
| 242 | } | 236 | } |
| 243 | 237 | ||
| @@ -253,7 +247,7 @@ void dce6_audio_enable(struct radeon_device *rdev, | |||
| 253 | } | 247 | } |
| 254 | 248 | ||
| 255 | void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, | 249 | void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, |
| 256 | struct radeon_crtc *crtc, unsigned int clock) | 250 | struct radeon_crtc *crtc, unsigned int clock) |
| 257 | { | 251 | { |
| 258 | /* Two dtos; generally use dto0 for HDMI */ | 252 | /* Two dtos; generally use dto0 for HDMI */ |
| 259 | u32 value = 0; | 253 | u32 value = 0; |
| @@ -272,7 +266,7 @@ void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, | |||
| 272 | } | 266 | } |
| 273 | 267 | ||
| 274 | void dce6_dp_audio_set_dto(struct radeon_device *rdev, | 268 | void dce6_dp_audio_set_dto(struct radeon_device *rdev, |
| 275 | struct radeon_crtc *crtc, unsigned int clock) | 269 | struct radeon_crtc *crtc, unsigned int clock) |
| 276 | { | 270 | { |
| 277 | /* Two dtos; generally use dto1 for DP */ | 271 | /* Two dtos; generally use dto1 for DP */ |
| 278 | u32 value = 0; | 272 | u32 value = 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index fa719c53449b..fbc8d88d6e5d 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c | |||
| @@ -245,6 +245,28 @@ static struct radeon_audio_funcs dce6_dp_funcs = { | |||
| 245 | static void radeon_audio_enable(struct radeon_device *rdev, | 245 | static void radeon_audio_enable(struct radeon_device *rdev, |
| 246 | struct r600_audio_pin *pin, u8 enable_mask) | 246 | struct r600_audio_pin *pin, u8 enable_mask) |
| 247 | { | 247 | { |
| 248 | struct drm_encoder *encoder; | ||
| 249 | struct radeon_encoder *radeon_encoder; | ||
| 250 | struct radeon_encoder_atom_dig *dig; | ||
| 251 | int pin_count = 0; | ||
| 252 | |||
| 253 | if (!pin) | ||
| 254 | return; | ||
| 255 | |||
| 256 | if (rdev->mode_info.mode_config_initialized) { | ||
| 257 | list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) { | ||
| 258 | if (radeon_encoder_is_digital(encoder)) { | ||
| 259 | radeon_encoder = to_radeon_encoder(encoder); | ||
| 260 | dig = radeon_encoder->enc_priv; | ||
| 261 | if (dig->pin == pin) | ||
| 262 | pin_count++; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 266 | if ((pin_count > 1) && (enable_mask == 0)) | ||
| 267 | return; | ||
| 268 | } | ||
| 269 | |||
| 248 | if (rdev->audio.funcs->enable) | 270 | if (rdev->audio.funcs->enable) |
| 249 | rdev->audio.funcs->enable(rdev, pin, enable_mask); | 271 | rdev->audio.funcs->enable(rdev, pin, enable_mask); |
| 250 | } | 272 | } |
| @@ -336,24 +358,13 @@ void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset, | |||
| 336 | 358 | ||
| 337 | static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) | 359 | static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) |
| 338 | { | 360 | { |
| 339 | struct radeon_encoder *radeon_encoder; | 361 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 340 | struct drm_connector *connector; | 362 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 341 | struct radeon_connector *radeon_connector = NULL; | ||
| 342 | struct cea_sad *sads; | 363 | struct cea_sad *sads; |
| 343 | int sad_count; | 364 | int sad_count; |
| 344 | 365 | ||
| 345 | list_for_each_entry(connector, | 366 | if (!connector) |
| 346 | &encoder->dev->mode_config.connector_list, head) { | ||
| 347 | if (connector->encoder == encoder) { | ||
| 348 | radeon_connector = to_radeon_connector(connector); | ||
| 349 | break; | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | if (!radeon_connector) { | ||
| 354 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
| 355 | return; | 367 | return; |
| 356 | } | ||
| 357 | 368 | ||
| 358 | sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); | 369 | sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads); |
| 359 | if (sad_count <= 0) { | 370 | if (sad_count <= 0) { |
| @@ -362,8 +373,6 @@ static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) | |||
| 362 | } | 373 | } |
| 363 | BUG_ON(!sads); | 374 | BUG_ON(!sads); |
| 364 | 375 | ||
| 365 | radeon_encoder = to_radeon_encoder(encoder); | ||
| 366 | |||
| 367 | if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs) | 376 | if (radeon_encoder->audio && radeon_encoder->audio->write_sad_regs) |
| 368 | radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count); | 377 | radeon_encoder->audio->write_sad_regs(encoder, sads, sad_count); |
| 369 | 378 | ||
| @@ -372,27 +381,16 @@ static void radeon_audio_write_sad_regs(struct drm_encoder *encoder) | |||
| 372 | 381 | ||
| 373 | static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) | 382 | static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) |
| 374 | { | 383 | { |
| 384 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 375 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 385 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 376 | struct drm_connector *connector; | ||
| 377 | struct radeon_connector *radeon_connector = NULL; | ||
| 378 | u8 *sadb = NULL; | 386 | u8 *sadb = NULL; |
| 379 | int sad_count; | 387 | int sad_count; |
| 380 | 388 | ||
| 381 | list_for_each_entry(connector, | 389 | if (!connector) |
| 382 | &encoder->dev->mode_config.connector_list, head) { | ||
| 383 | if (connector->encoder == encoder) { | ||
| 384 | radeon_connector = to_radeon_connector(connector); | ||
| 385 | break; | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | if (!radeon_connector) { | ||
| 390 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
| 391 | return; | 390 | return; |
| 392 | } | ||
| 393 | 391 | ||
| 394 | sad_count = drm_edid_to_speaker_allocation( | 392 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), |
| 395 | radeon_connector_edid(connector), &sadb); | 393 | &sadb); |
| 396 | if (sad_count < 0) { | 394 | if (sad_count < 0) { |
| 397 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", | 395 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", |
| 398 | sad_count); | 396 | sad_count); |
| @@ -406,26 +404,13 @@ static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder) | |||
| 406 | } | 404 | } |
| 407 | 405 | ||
| 408 | static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, | 406 | static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, |
| 409 | struct drm_display_mode *mode) | 407 | struct drm_display_mode *mode) |
| 410 | { | 408 | { |
| 411 | struct radeon_encoder *radeon_encoder; | 409 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 412 | struct drm_connector *connector; | 410 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 413 | struct radeon_connector *radeon_connector = 0; | ||
| 414 | |||
| 415 | list_for_each_entry(connector, | ||
| 416 | &encoder->dev->mode_config.connector_list, head) { | ||
| 417 | if (connector->encoder == encoder) { | ||
| 418 | radeon_connector = to_radeon_connector(connector); | ||
| 419 | break; | ||
| 420 | } | ||
| 421 | } | ||
| 422 | 411 | ||
| 423 | if (!radeon_connector) { | 412 | if (!connector) |
| 424 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
| 425 | return; | 413 | return; |
| 426 | } | ||
| 427 | |||
| 428 | radeon_encoder = to_radeon_encoder(encoder); | ||
| 429 | 414 | ||
| 430 | if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields) | 415 | if (radeon_encoder->audio && radeon_encoder->audio->write_latency_fields) |
| 431 | radeon_encoder->audio->write_latency_fields(encoder, connector, mode); | 416 | radeon_encoder->audio->write_latency_fields(encoder, connector, mode); |
| @@ -451,29 +436,23 @@ static void radeon_audio_select_pin(struct drm_encoder *encoder) | |||
| 451 | } | 436 | } |
| 452 | 437 | ||
| 453 | void radeon_audio_detect(struct drm_connector *connector, | 438 | void radeon_audio_detect(struct drm_connector *connector, |
| 439 | struct drm_encoder *encoder, | ||
| 454 | enum drm_connector_status status) | 440 | enum drm_connector_status status) |
| 455 | { | 441 | { |
| 456 | struct radeon_device *rdev; | 442 | struct drm_device *dev = connector->dev; |
| 457 | struct radeon_encoder *radeon_encoder; | 443 | struct radeon_device *rdev = dev->dev_private; |
| 444 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 458 | struct radeon_encoder_atom_dig *dig; | 445 | struct radeon_encoder_atom_dig *dig; |
| 459 | 446 | ||
| 460 | if (!connector || !connector->encoder) | 447 | if (!radeon_audio_chipset_supported(rdev)) |
| 461 | return; | 448 | return; |
| 462 | 449 | ||
| 463 | rdev = connector->encoder->dev->dev_private; | 450 | if (!radeon_encoder_is_digital(encoder)) |
| 464 | |||
| 465 | if (!radeon_audio_chipset_supported(rdev)) | ||
| 466 | return; | 451 | return; |
| 467 | 452 | ||
| 468 | radeon_encoder = to_radeon_encoder(connector->encoder); | ||
| 469 | dig = radeon_encoder->enc_priv; | 453 | dig = radeon_encoder->enc_priv; |
| 470 | 454 | ||
| 471 | if (status == connector_status_connected) { | 455 | if (status == connector_status_connected) { |
| 472 | if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) { | ||
| 473 | radeon_encoder->audio = NULL; | ||
| 474 | return; | ||
| 475 | } | ||
| 476 | |||
| 477 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | 456 | if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { |
| 478 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 457 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 479 | 458 | ||
| @@ -486,11 +465,17 @@ void radeon_audio_detect(struct drm_connector *connector, | |||
| 486 | radeon_encoder->audio = rdev->audio.hdmi_funcs; | 465 | radeon_encoder->audio = rdev->audio.hdmi_funcs; |
| 487 | } | 466 | } |
| 488 | 467 | ||
| 489 | dig->afmt->pin = radeon_audio_get_pin(connector->encoder); | 468 | if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { |
| 490 | radeon_audio_enable(rdev, dig->afmt->pin, 0xf); | 469 | if (!dig->pin) |
| 470 | dig->pin = radeon_audio_get_pin(encoder); | ||
| 471 | radeon_audio_enable(rdev, dig->pin, 0xf); | ||
| 472 | } else { | ||
| 473 | radeon_audio_enable(rdev, dig->pin, 0); | ||
| 474 | dig->pin = NULL; | ||
| 475 | } | ||
| 491 | } else { | 476 | } else { |
| 492 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | 477 | radeon_audio_enable(rdev, dig->pin, 0); |
| 493 | dig->afmt->pin = NULL; | 478 | dig->pin = NULL; |
| 494 | } | 479 | } |
| 495 | } | 480 | } |
| 496 | 481 | ||
| @@ -518,29 +503,18 @@ static void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock | |||
| 518 | } | 503 | } |
| 519 | 504 | ||
| 520 | static int radeon_audio_set_avi_packet(struct drm_encoder *encoder, | 505 | static int radeon_audio_set_avi_packet(struct drm_encoder *encoder, |
| 521 | struct drm_display_mode *mode) | 506 | struct drm_display_mode *mode) |
| 522 | { | 507 | { |
| 523 | struct radeon_device *rdev = encoder->dev->dev_private; | 508 | struct radeon_device *rdev = encoder->dev->dev_private; |
| 524 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 509 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 525 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 510 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 526 | struct drm_connector *connector; | 511 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 527 | struct radeon_connector *radeon_connector = NULL; | ||
| 528 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; | 512 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; |
| 529 | struct hdmi_avi_infoframe frame; | 513 | struct hdmi_avi_infoframe frame; |
| 530 | int err; | 514 | int err; |
| 531 | 515 | ||
| 532 | list_for_each_entry(connector, | 516 | if (!connector) |
| 533 | &encoder->dev->mode_config.connector_list, head) { | 517 | return -EINVAL; |
| 534 | if (connector->encoder == encoder) { | ||
| 535 | radeon_connector = to_radeon_connector(connector); | ||
| 536 | break; | ||
| 537 | } | ||
| 538 | } | ||
| 539 | |||
| 540 | if (!radeon_connector) { | ||
| 541 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
| 542 | return -ENOENT; | ||
| 543 | } | ||
| 544 | 518 | ||
| 545 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | 519 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); |
| 546 | if (err < 0) { | 520 | if (err < 0) { |
| @@ -563,8 +537,8 @@ static int radeon_audio_set_avi_packet(struct drm_encoder *encoder, | |||
| 563 | return err; | 537 | return err; |
| 564 | } | 538 | } |
| 565 | 539 | ||
| 566 | if (dig && dig->afmt && | 540 | if (dig && dig->afmt && radeon_encoder->audio && |
| 567 | radeon_encoder->audio && radeon_encoder->audio->set_avi_packet) | 541 | radeon_encoder->audio->set_avi_packet) |
| 568 | radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset, | 542 | radeon_encoder->audio->set_avi_packet(rdev, dig->afmt->offset, |
| 569 | buffer, sizeof(buffer)); | 543 | buffer, sizeof(buffer)); |
| 570 | 544 | ||
| @@ -722,30 +696,41 @@ static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 722 | { | 696 | { |
| 723 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 697 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 724 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 698 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 699 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 725 | 700 | ||
| 726 | if (!dig || !dig->afmt) | 701 | if (!dig || !dig->afmt) |
| 727 | return; | 702 | return; |
| 728 | 703 | ||
| 729 | radeon_audio_set_mute(encoder, true); | 704 | if (!connector) |
| 705 | return; | ||
| 730 | 706 | ||
| 731 | radeon_audio_write_speaker_allocation(encoder); | 707 | if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { |
| 732 | radeon_audio_write_sad_regs(encoder); | 708 | radeon_audio_set_mute(encoder, true); |
| 733 | radeon_audio_write_latency_fields(encoder, mode); | ||
| 734 | radeon_audio_set_dto(encoder, mode->clock); | ||
| 735 | radeon_audio_set_vbi_packet(encoder); | ||
| 736 | radeon_hdmi_set_color_depth(encoder); | ||
| 737 | radeon_audio_update_acr(encoder, mode->clock); | ||
| 738 | radeon_audio_set_audio_packet(encoder); | ||
| 739 | radeon_audio_select_pin(encoder); | ||
| 740 | 709 | ||
| 741 | if (radeon_audio_set_avi_packet(encoder, mode) < 0) | 710 | radeon_audio_write_speaker_allocation(encoder); |
| 742 | return; | 711 | radeon_audio_write_sad_regs(encoder); |
| 712 | radeon_audio_write_latency_fields(encoder, mode); | ||
| 713 | radeon_audio_set_dto(encoder, mode->clock); | ||
| 714 | radeon_audio_set_vbi_packet(encoder); | ||
| 715 | radeon_hdmi_set_color_depth(encoder); | ||
| 716 | radeon_audio_update_acr(encoder, mode->clock); | ||
| 717 | radeon_audio_set_audio_packet(encoder); | ||
| 718 | radeon_audio_select_pin(encoder); | ||
| 719 | |||
| 720 | if (radeon_audio_set_avi_packet(encoder, mode) < 0) | ||
| 721 | return; | ||
| 743 | 722 | ||
| 744 | radeon_audio_set_mute(encoder, false); | 723 | radeon_audio_set_mute(encoder, false); |
| 724 | } else { | ||
| 725 | radeon_hdmi_set_color_depth(encoder); | ||
| 726 | |||
| 727 | if (radeon_audio_set_avi_packet(encoder, mode) < 0) | ||
| 728 | return; | ||
| 729 | } | ||
| 745 | } | 730 | } |
| 746 | 731 | ||
| 747 | static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, | 732 | static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, |
| 748 | struct drm_display_mode *mode) | 733 | struct drm_display_mode *mode) |
| 749 | { | 734 | { |
| 750 | struct drm_device *dev = encoder->dev; | 735 | struct drm_device *dev = encoder->dev; |
| 751 | struct radeon_device *rdev = dev->dev_private; | 736 | struct radeon_device *rdev = dev->dev_private; |
| @@ -759,22 +744,27 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, | |||
| 759 | if (!dig || !dig->afmt) | 744 | if (!dig || !dig->afmt) |
| 760 | return; | 745 | return; |
| 761 | 746 | ||
| 762 | radeon_audio_write_speaker_allocation(encoder); | 747 | if (!connector) |
| 763 | radeon_audio_write_sad_regs(encoder); | ||
| 764 | radeon_audio_write_latency_fields(encoder, mode); | ||
| 765 | if (rdev->clock.dp_extclk || ASIC_IS_DCE5(rdev)) | ||
| 766 | radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10); | ||
| 767 | else | ||
| 768 | radeon_audio_set_dto(encoder, dig_connector->dp_clock); | ||
| 769 | radeon_audio_set_audio_packet(encoder); | ||
| 770 | radeon_audio_select_pin(encoder); | ||
| 771 | |||
| 772 | if (radeon_audio_set_avi_packet(encoder, mode) < 0) | ||
| 773 | return; | 748 | return; |
| 749 | |||
| 750 | if (drm_detect_monitor_audio(radeon_connector_edid(connector))) { | ||
| 751 | radeon_audio_write_speaker_allocation(encoder); | ||
| 752 | radeon_audio_write_sad_regs(encoder); | ||
| 753 | radeon_audio_write_latency_fields(encoder, mode); | ||
| 754 | if (rdev->clock.dp_extclk || ASIC_IS_DCE5(rdev)) | ||
| 755 | radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10); | ||
| 756 | else | ||
| 757 | radeon_audio_set_dto(encoder, dig_connector->dp_clock); | ||
| 758 | radeon_audio_set_audio_packet(encoder); | ||
| 759 | radeon_audio_select_pin(encoder); | ||
| 760 | |||
| 761 | if (radeon_audio_set_avi_packet(encoder, mode) < 0) | ||
| 762 | return; | ||
| 763 | } | ||
| 774 | } | 764 | } |
| 775 | 765 | ||
| 776 | void radeon_audio_mode_set(struct drm_encoder *encoder, | 766 | void radeon_audio_mode_set(struct drm_encoder *encoder, |
| 777 | struct drm_display_mode *mode) | 767 | struct drm_display_mode *mode) |
| 778 | { | 768 | { |
| 779 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 769 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 780 | 770 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 8438304f7139..059cc3012062 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h | |||
| @@ -68,7 +68,8 @@ struct radeon_audio_funcs | |||
| 68 | 68 | ||
| 69 | int radeon_audio_init(struct radeon_device *rdev); | 69 | int radeon_audio_init(struct radeon_device *rdev); |
| 70 | void radeon_audio_detect(struct drm_connector *connector, | 70 | void radeon_audio_detect(struct drm_connector *connector, |
| 71 | enum drm_connector_status status); | 71 | struct drm_encoder *encoder, |
| 72 | enum drm_connector_status status); | ||
| 72 | u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, | 73 | u32 radeon_audio_endpoint_rreg(struct radeon_device *rdev, |
| 73 | u32 offset, u32 reg); | 74 | u32 offset, u32 reg); |
| 74 | void radeon_audio_endpoint_wreg(struct radeon_device *rdev, | 75 | void radeon_audio_endpoint_wreg(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 3e5f6b71f3ad..c097d3a82bda 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -1255,10 +1255,15 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
| 1255 | 1255 | ||
| 1256 | if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && | 1256 | if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && |
| 1257 | (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) { | 1257 | (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) { |
| 1258 | u32 hss = (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8; | ||
| 1259 | |||
| 1260 | if (hss > lvds->native_mode.hdisplay) | ||
| 1261 | hss = (10 - 1) * 8; | ||
| 1262 | |||
| 1258 | lvds->native_mode.htotal = lvds->native_mode.hdisplay + | 1263 | lvds->native_mode.htotal = lvds->native_mode.hdisplay + |
| 1259 | (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; | 1264 | (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; |
| 1260 | lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + | 1265 | lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + |
| 1261 | (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8; | 1266 | hss; |
| 1262 | lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + | 1267 | lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + |
| 1263 | (RBIOS8(tmp + 23) * 8); | 1268 | (RBIOS8(tmp + 23) * 8); |
| 1264 | 1269 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index cebb65e07e1d..94b21ae70ef7 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -1379,8 +1379,16 @@ out: | |||
| 1379 | /* updated in get modes as well since we need to know if it's analog or digital */ | 1379 | /* updated in get modes as well since we need to know if it's analog or digital */ |
| 1380 | radeon_connector_update_scratch_regs(connector, ret); | 1380 | radeon_connector_update_scratch_regs(connector, ret); |
| 1381 | 1381 | ||
| 1382 | if (radeon_audio != 0) | 1382 | if ((radeon_audio != 0) && radeon_connector->use_digital) { |
| 1383 | radeon_audio_detect(connector, ret); | 1383 | const struct drm_connector_helper_funcs *connector_funcs = |
| 1384 | connector->helper_private; | ||
| 1385 | |||
| 1386 | encoder = connector_funcs->best_encoder(connector); | ||
| 1387 | if (encoder && (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)) { | ||
| 1388 | radeon_connector_get_edid(connector); | ||
| 1389 | radeon_audio_detect(connector, encoder, ret); | ||
| 1390 | } | ||
| 1391 | } | ||
| 1384 | 1392 | ||
| 1385 | exit: | 1393 | exit: |
| 1386 | pm_runtime_mark_last_busy(connector->dev->dev); | 1394 | pm_runtime_mark_last_busy(connector->dev->dev); |
| @@ -1717,8 +1725,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1717 | 1725 | ||
| 1718 | radeon_connector_update_scratch_regs(connector, ret); | 1726 | radeon_connector_update_scratch_regs(connector, ret); |
| 1719 | 1727 | ||
| 1720 | if (radeon_audio != 0) | 1728 | if ((radeon_audio != 0) && encoder) { |
| 1721 | radeon_audio_detect(connector, ret); | 1729 | radeon_connector_get_edid(connector); |
| 1730 | radeon_audio_detect(connector, encoder, ret); | ||
| 1731 | } | ||
| 1722 | 1732 | ||
| 1723 | out: | 1733 | out: |
| 1724 | pm_runtime_mark_last_busy(connector->dev->dev); | 1734 | pm_runtime_mark_last_busy(connector->dev->dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 07909d817381..aecc3e3dec0c 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -237,7 +237,6 @@ struct radeon_afmt { | |||
| 237 | int offset; | 237 | int offset; |
| 238 | bool last_buffer_filled_status; | 238 | bool last_buffer_filled_status; |
| 239 | int id; | 239 | int id; |
| 240 | struct r600_audio_pin *pin; | ||
| 241 | }; | 240 | }; |
| 242 | 241 | ||
| 243 | struct radeon_mode_info { | 242 | struct radeon_mode_info { |
| @@ -439,6 +438,7 @@ struct radeon_encoder_atom_dig { | |||
| 439 | uint8_t backlight_level; | 438 | uint8_t backlight_level; |
| 440 | int panel_mode; | 439 | int panel_mode; |
| 441 | struct radeon_afmt *afmt; | 440 | struct radeon_afmt *afmt; |
| 441 | struct r600_audio_pin *pin; | ||
| 442 | int active_mst_links; | 442 | int active_mst_links; |
| 443 | }; | 443 | }; |
| 444 | 444 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 882cccdad272..ac6fe40b99f7 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
| @@ -490,7 +490,8 @@ pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp) | |||
| 490 | else if (boot_cpu_data.x86 > 3) | 490 | else if (boot_cpu_data.x86 > 3) |
| 491 | tmp = pgprot_noncached(tmp); | 491 | tmp = pgprot_noncached(tmp); |
| 492 | #endif | 492 | #endif |
| 493 | #if defined(__ia64__) || defined(__arm__) || defined(__powerpc__) | 493 | #if defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \ |
| 494 | defined(__powerpc__) | ||
| 494 | if (caching_flags & TTM_PL_FLAG_WC) | 495 | if (caching_flags & TTM_PL_FLAG_WC) |
| 495 | tmp = pgprot_writecombine(tmp); | 496 | tmp = pgprot_writecombine(tmp); |
| 496 | else | 497 | else |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 654c8daeb5ab..97ad3bcb99a7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
| @@ -2492,7 +2492,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
| 2492 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, | 2492 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, |
| 2493 | true, NULL); | 2493 | true, NULL); |
| 2494 | if (unlikely(ret != 0)) | 2494 | if (unlikely(ret != 0)) |
| 2495 | goto out_err; | 2495 | goto out_err_nores; |
| 2496 | 2496 | ||
| 2497 | ret = vmw_validate_buffers(dev_priv, sw_context); | 2497 | ret = vmw_validate_buffers(dev_priv, sw_context); |
| 2498 | if (unlikely(ret != 0)) | 2498 | if (unlikely(ret != 0)) |
| @@ -2536,6 +2536,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
| 2536 | vmw_resource_relocations_free(&sw_context->res_relocations); | 2536 | vmw_resource_relocations_free(&sw_context->res_relocations); |
| 2537 | 2537 | ||
| 2538 | vmw_fifo_commit(dev_priv, command_size); | 2538 | vmw_fifo_commit(dev_priv, command_size); |
| 2539 | mutex_unlock(&dev_priv->binding_mutex); | ||
| 2539 | 2540 | ||
| 2540 | vmw_query_bo_switch_commit(dev_priv, sw_context); | 2541 | vmw_query_bo_switch_commit(dev_priv, sw_context); |
| 2541 | ret = vmw_execbuf_fence_commands(file_priv, dev_priv, | 2542 | ret = vmw_execbuf_fence_commands(file_priv, dev_priv, |
| @@ -2551,7 +2552,6 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
| 2551 | DRM_ERROR("Fence submission error. Syncing.\n"); | 2552 | DRM_ERROR("Fence submission error. Syncing.\n"); |
| 2552 | 2553 | ||
| 2553 | vmw_resource_list_unreserve(&sw_context->resource_list, false); | 2554 | vmw_resource_list_unreserve(&sw_context->resource_list, false); |
| 2554 | mutex_unlock(&dev_priv->binding_mutex); | ||
| 2555 | 2555 | ||
| 2556 | ttm_eu_fence_buffer_objects(&ticket, &sw_context->validate_nodes, | 2556 | ttm_eu_fence_buffer_objects(&ticket, &sw_context->validate_nodes, |
| 2557 | (void *) fence); | 2557 | (void *) fence); |
