diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/cik_sdma.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/ni_dma.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/nid.h | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 33 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/si.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/si_dma.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.c | 39 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 18 |
12 files changed, 186 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 6dcde3798b45..64fdae558d36 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
| @@ -6033,6 +6033,17 @@ void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 6033 | radeon_ring_write(ring, 0); | 6033 | radeon_ring_write(ring, 0); |
| 6034 | radeon_ring_write(ring, 1 << vm_id); | 6034 | radeon_ring_write(ring, 1 << vm_id); |
| 6035 | 6035 | ||
| 6036 | /* wait for the invalidate to complete */ | ||
| 6037 | radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); | ||
| 6038 | radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */ | ||
| 6039 | WAIT_REG_MEM_FUNCTION(0) | /* always */ | ||
| 6040 | WAIT_REG_MEM_ENGINE(0))); /* me */ | ||
| 6041 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
| 6042 | radeon_ring_write(ring, 0); | ||
| 6043 | radeon_ring_write(ring, 0); /* ref */ | ||
| 6044 | radeon_ring_write(ring, 0); /* mask */ | ||
| 6045 | radeon_ring_write(ring, 0x20); /* poll interval */ | ||
| 6046 | |||
| 6036 | /* compute doesn't have PFP */ | 6047 | /* compute doesn't have PFP */ |
| 6037 | if (usepfp) { | 6048 | if (usepfp) { |
| 6038 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 6049 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index dde5c7e29eb2..a0133c74f4cf 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
| @@ -903,6 +903,9 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib) | |||
| 903 | void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | 903 | void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
| 904 | unsigned vm_id, uint64_t pd_addr) | 904 | unsigned vm_id, uint64_t pd_addr) |
| 905 | { | 905 | { |
| 906 | u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(0) | | ||
| 907 | SDMA_POLL_REG_MEM_EXTRA_FUNC(0)); /* always */ | ||
| 908 | |||
| 906 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 909 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
| 907 | if (vm_id < 8) { | 910 | if (vm_id < 8) { |
| 908 | radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); | 911 | radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); |
| @@ -943,5 +946,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 943 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 946 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
| 944 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 947 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
| 945 | radeon_ring_write(ring, 1 << vm_id); | 948 | radeon_ring_write(ring, 1 << vm_id); |
| 949 | |||
| 950 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); | ||
| 951 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
| 952 | radeon_ring_write(ring, 0); | ||
| 953 | radeon_ring_write(ring, 0); /* reference */ | ||
| 954 | radeon_ring_write(ring, 0); /* mask */ | ||
| 955 | radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */ | ||
| 946 | } | 956 | } |
| 947 | 957 | ||
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 360de9f1f491..aea48c89b241 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -2516,6 +2516,16 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 2516 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); | 2516 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); |
| 2517 | radeon_ring_write(ring, 1 << vm_id); | 2517 | radeon_ring_write(ring, 1 << vm_id); |
| 2518 | 2518 | ||
| 2519 | /* wait for the invalidate to complete */ | ||
| 2520 | radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); | ||
| 2521 | radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ | ||
| 2522 | WAIT_REG_MEM_ENGINE(0))); /* me */ | ||
| 2523 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
| 2524 | radeon_ring_write(ring, 0); | ||
| 2525 | radeon_ring_write(ring, 0); /* ref */ | ||
| 2526 | radeon_ring_write(ring, 0); /* mask */ | ||
| 2527 | radeon_ring_write(ring, 0x20); /* poll interval */ | ||
| 2528 | |||
| 2519 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 2529 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
| 2520 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | 2530 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); |
| 2521 | radeon_ring_write(ring, 0x0); | 2531 | radeon_ring_write(ring, 0x0); |
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index 50f88611ff60..4be2bb7cbef3 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c | |||
| @@ -463,5 +463,11 @@ void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 463 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | 463 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); |
| 464 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | 464 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); |
| 465 | radeon_ring_write(ring, 1 << vm_id); | 465 | radeon_ring_write(ring, 1 << vm_id); |
| 466 | |||
| 467 | /* wait for invalidate to complete */ | ||
| 468 | radeon_ring_write(ring, DMA_SRBM_READ_PACKET); | ||
| 469 | radeon_ring_write(ring, (0xff << 20) | (VM_INVALIDATE_REQUEST >> 2)); | ||
| 470 | radeon_ring_write(ring, 0); /* mask */ | ||
| 471 | radeon_ring_write(ring, 0); /* value */ | ||
| 466 | } | 472 | } |
| 467 | 473 | ||
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 2e12e4d69253..ad7125486894 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
| @@ -1133,6 +1133,23 @@ | |||
| 1133 | #define PACKET3_MEM_SEMAPHORE 0x39 | 1133 | #define PACKET3_MEM_SEMAPHORE 0x39 |
| 1134 | #define PACKET3_MPEG_INDEX 0x3A | 1134 | #define PACKET3_MPEG_INDEX 0x3A |
| 1135 | #define PACKET3_WAIT_REG_MEM 0x3C | 1135 | #define PACKET3_WAIT_REG_MEM 0x3C |
| 1136 | #define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) | ||
| 1137 | /* 0 - always | ||
| 1138 | * 1 - < | ||
| 1139 | * 2 - <= | ||
| 1140 | * 3 - == | ||
| 1141 | * 4 - != | ||
| 1142 | * 5 - >= | ||
| 1143 | * 6 - > | ||
| 1144 | */ | ||
| 1145 | #define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) | ||
| 1146 | /* 0 - reg | ||
| 1147 | * 1 - mem | ||
| 1148 | */ | ||
| 1149 | #define WAIT_REG_MEM_ENGINE(x) ((x) << 8) | ||
| 1150 | /* 0 - me | ||
| 1151 | * 1 - pfp | ||
| 1152 | */ | ||
| 1136 | #define PACKET3_MEM_WRITE 0x3D | 1153 | #define PACKET3_MEM_WRITE 0x3D |
| 1137 | #define PACKET3_PFP_SYNC_ME 0x42 | 1154 | #define PACKET3_PFP_SYNC_ME 0x42 |
| 1138 | #define PACKET3_SURFACE_SYNC 0x43 | 1155 | #define PACKET3_SURFACE_SYNC 0x43 |
| @@ -1272,6 +1289,13 @@ | |||
| 1272 | (1 << 21) | \ | 1289 | (1 << 21) | \ |
| 1273 | (((n) & 0xFFFFF) << 0)) | 1290 | (((n) & 0xFFFFF) << 0)) |
| 1274 | 1291 | ||
| 1292 | #define DMA_SRBM_POLL_PACKET ((9 << 28) | \ | ||
| 1293 | (1 << 27) | \ | ||
| 1294 | (1 << 26)) | ||
| 1295 | |||
| 1296 | #define DMA_SRBM_READ_PACKET ((9 << 28) | \ | ||
| 1297 | (1 << 27)) | ||
| 1298 | |||
| 1275 | /* async DMA Packet types */ | 1299 | /* async DMA Packet types */ |
| 1276 | #define DMA_PACKET_WRITE 0x2 | 1300 | #define DMA_PACKET_WRITE 0x2 |
| 1277 | #define DMA_PACKET_COPY 0x3 | 1301 | #define DMA_PACKET_COPY 0x3 |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 850de57069be..121aff6a3b41 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
| @@ -333,6 +333,20 @@ static struct radeon_asic_ring r300_gfx_ring = { | |||
| 333 | .set_wptr = &r100_gfx_set_wptr, | 333 | .set_wptr = &r100_gfx_set_wptr, |
| 334 | }; | 334 | }; |
| 335 | 335 | ||
| 336 | static struct radeon_asic_ring rv515_gfx_ring = { | ||
| 337 | .ib_execute = &r100_ring_ib_execute, | ||
| 338 | .emit_fence = &r300_fence_ring_emit, | ||
| 339 | .emit_semaphore = &r100_semaphore_ring_emit, | ||
| 340 | .cs_parse = &r300_cs_parse, | ||
| 341 | .ring_start = &rv515_ring_start, | ||
| 342 | .ring_test = &r100_ring_test, | ||
| 343 | .ib_test = &r100_ib_test, | ||
| 344 | .is_lockup = &r100_gpu_is_lockup, | ||
| 345 | .get_rptr = &r100_gfx_get_rptr, | ||
| 346 | .get_wptr = &r100_gfx_get_wptr, | ||
| 347 | .set_wptr = &r100_gfx_set_wptr, | ||
| 348 | }; | ||
| 349 | |||
| 336 | static struct radeon_asic r300_asic = { | 350 | static struct radeon_asic r300_asic = { |
| 337 | .init = &r300_init, | 351 | .init = &r300_init, |
| 338 | .fini = &r300_fini, | 352 | .fini = &r300_fini, |
| @@ -748,7 +762,7 @@ static struct radeon_asic rv515_asic = { | |||
| 748 | .set_page = &rv370_pcie_gart_set_page, | 762 | .set_page = &rv370_pcie_gart_set_page, |
| 749 | }, | 763 | }, |
| 750 | .ring = { | 764 | .ring = { |
| 751 | [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring | 765 | [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring |
| 752 | }, | 766 | }, |
| 753 | .irq = { | 767 | .irq = { |
| 754 | .set = &rs600_irq_set, | 768 | .set = &rs600_irq_set, |
| @@ -814,7 +828,7 @@ static struct radeon_asic r520_asic = { | |||
| 814 | .set_page = &rv370_pcie_gart_set_page, | 828 | .set_page = &rv370_pcie_gart_set_page, |
| 815 | }, | 829 | }, |
| 816 | .ring = { | 830 | .ring = { |
| 817 | [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring | 831 | [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring |
| 818 | }, | 832 | }, |
| 819 | .irq = { | 833 | .irq = { |
| 820 | .set = &rs600_irq_set, | 834 | .set = &rs600_irq_set, |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index a46f73737994..d0b4f7d1140d 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -576,7 +576,7 @@ error_unreserve: | |||
| 576 | error_free: | 576 | error_free: |
| 577 | drm_free_large(vm_bos); | 577 | drm_free_large(vm_bos); |
| 578 | 578 | ||
| 579 | if (r) | 579 | if (r && r != -ERESTARTSYS) |
| 580 | DRM_ERROR("Couldn't update BO_VA (%d)\n", r); | 580 | DRM_ERROR("Couldn't update BO_VA (%d)\n", r); |
| 581 | } | 581 | } |
| 582 | 582 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 32522cc940a1..f7da8fe96a66 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -1287,8 +1287,39 @@ dpm_failed: | |||
| 1287 | return ret; | 1287 | return ret; |
| 1288 | } | 1288 | } |
| 1289 | 1289 | ||
| 1290 | struct radeon_dpm_quirk { | ||
| 1291 | u32 chip_vendor; | ||
| 1292 | u32 chip_device; | ||
| 1293 | u32 subsys_vendor; | ||
| 1294 | u32 subsys_device; | ||
| 1295 | }; | ||
| 1296 | |||
| 1297 | /* cards with dpm stability problems */ | ||
| 1298 | static struct radeon_dpm_quirk radeon_dpm_quirk_list[] = { | ||
| 1299 | /* TURKS - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 */ | ||
| 1300 | { PCI_VENDOR_ID_ATI, 0x6759, 0x1682, 0x3195 }, | ||
| 1301 | /* TURKS - https://bugzilla.kernel.org/show_bug.cgi?id=83731 */ | ||
| 1302 | { PCI_VENDOR_ID_ATI, 0x6840, 0x1179, 0xfb81 }, | ||
| 1303 | { 0, 0, 0, 0 }, | ||
| 1304 | }; | ||
| 1305 | |||
| 1290 | int radeon_pm_init(struct radeon_device *rdev) | 1306 | int radeon_pm_init(struct radeon_device *rdev) |
| 1291 | { | 1307 | { |
| 1308 | struct radeon_dpm_quirk *p = radeon_dpm_quirk_list; | ||
| 1309 | bool disable_dpm = false; | ||
| 1310 | |||
| 1311 | /* Apply dpm quirks */ | ||
| 1312 | while (p && p->chip_device != 0) { | ||
| 1313 | if (rdev->pdev->vendor == p->chip_vendor && | ||
| 1314 | rdev->pdev->device == p->chip_device && | ||
| 1315 | rdev->pdev->subsystem_vendor == p->subsys_vendor && | ||
| 1316 | rdev->pdev->subsystem_device == p->subsys_device) { | ||
| 1317 | disable_dpm = true; | ||
| 1318 | break; | ||
| 1319 | } | ||
| 1320 | ++p; | ||
| 1321 | } | ||
| 1322 | |||
| 1292 | /* enable dpm on rv6xx+ */ | 1323 | /* enable dpm on rv6xx+ */ |
| 1293 | switch (rdev->family) { | 1324 | switch (rdev->family) { |
| 1294 | case CHIP_RV610: | 1325 | case CHIP_RV610: |
| @@ -1344,6 +1375,8 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
| 1344 | (!(rdev->flags & RADEON_IS_IGP)) && | 1375 | (!(rdev->flags & RADEON_IS_IGP)) && |
| 1345 | (!rdev->smc_fw)) | 1376 | (!rdev->smc_fw)) |
| 1346 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1377 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
| 1378 | else if (disable_dpm && (radeon_dpm == -1)) | ||
| 1379 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
| 1347 | else if (radeon_dpm == 0) | 1380 | else if (radeon_dpm == 0) |
| 1348 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1381 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
| 1349 | else | 1382 | else |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 60df444bd075..5d89b874a1a2 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -5057,6 +5057,16 @@ void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 5057 | radeon_ring_write(ring, 0); | 5057 | radeon_ring_write(ring, 0); |
| 5058 | radeon_ring_write(ring, 1 << vm_id); | 5058 | radeon_ring_write(ring, 1 << vm_id); |
| 5059 | 5059 | ||
| 5060 | /* wait for the invalidate to complete */ | ||
| 5061 | radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); | ||
| 5062 | radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ | ||
| 5063 | WAIT_REG_MEM_ENGINE(0))); /* me */ | ||
| 5064 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
| 5065 | radeon_ring_write(ring, 0); | ||
| 5066 | radeon_ring_write(ring, 0); /* ref */ | ||
| 5067 | radeon_ring_write(ring, 0); /* mask */ | ||
| 5068 | radeon_ring_write(ring, 0x20); /* poll interval */ | ||
| 5069 | |||
| 5060 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 5070 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
| 5061 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | 5071 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); |
| 5062 | radeon_ring_write(ring, 0x0); | 5072 | radeon_ring_write(ring, 0x0); |
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index f5cc777e1c5f..aa7b872b2c43 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
| @@ -206,6 +206,14 @@ void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
| 206 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | 206 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); |
| 207 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | 207 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); |
| 208 | radeon_ring_write(ring, 1 << vm_id); | 208 | radeon_ring_write(ring, 1 << vm_id); |
| 209 | |||
| 210 | /* wait for invalidate to complete */ | ||
| 211 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_POLL_REG_MEM, 0, 0, 0, 0)); | ||
| 212 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST); | ||
| 213 | radeon_ring_write(ring, 0xff << 16); /* retry */ | ||
| 214 | radeon_ring_write(ring, 1 << vm_id); /* mask */ | ||
| 215 | radeon_ring_write(ring, 0); /* value */ | ||
| 216 | radeon_ring_write(ring, (0 << 28) | 0x20); /* func(always) | poll interval */ | ||
| 209 | } | 217 | } |
| 210 | 218 | ||
| 211 | /** | 219 | /** |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 32e354b8b0ab..eff8a6444956 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
| @@ -2908,6 +2908,22 @@ static int si_init_smc_spll_table(struct radeon_device *rdev) | |||
| 2908 | return ret; | 2908 | return ret; |
| 2909 | } | 2909 | } |
| 2910 | 2910 | ||
| 2911 | struct si_dpm_quirk { | ||
| 2912 | u32 chip_vendor; | ||
| 2913 | u32 chip_device; | ||
| 2914 | u32 subsys_vendor; | ||
| 2915 | u32 subsys_device; | ||
| 2916 | u32 max_sclk; | ||
| 2917 | u32 max_mclk; | ||
| 2918 | }; | ||
| 2919 | |||
| 2920 | /* cards with dpm stability problems */ | ||
| 2921 | static struct si_dpm_quirk si_dpm_quirk_list[] = { | ||
| 2922 | /* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ | ||
| 2923 | { PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, | ||
| 2924 | { 0, 0, 0, 0 }, | ||
| 2925 | }; | ||
| 2926 | |||
| 2911 | static void si_apply_state_adjust_rules(struct radeon_device *rdev, | 2927 | static void si_apply_state_adjust_rules(struct radeon_device *rdev, |
| 2912 | struct radeon_ps *rps) | 2928 | struct radeon_ps *rps) |
| 2913 | { | 2929 | { |
| @@ -2918,7 +2934,22 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
| 2918 | u32 mclk, sclk; | 2934 | u32 mclk, sclk; |
| 2919 | u16 vddc, vddci; | 2935 | u16 vddc, vddci; |
| 2920 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; | 2936 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; |
| 2937 | u32 max_sclk = 0, max_mclk = 0; | ||
| 2921 | int i; | 2938 | int i; |
| 2939 | struct si_dpm_quirk *p = si_dpm_quirk_list; | ||
| 2940 | |||
| 2941 | /* Apply dpm quirks */ | ||
| 2942 | while (p && p->chip_device != 0) { | ||
| 2943 | if (rdev->pdev->vendor == p->chip_vendor && | ||
| 2944 | rdev->pdev->device == p->chip_device && | ||
| 2945 | rdev->pdev->subsystem_vendor == p->subsys_vendor && | ||
| 2946 | rdev->pdev->subsystem_device == p->subsys_device) { | ||
| 2947 | max_sclk = p->max_sclk; | ||
| 2948 | max_mclk = p->max_mclk; | ||
| 2949 | break; | ||
| 2950 | } | ||
| 2951 | ++p; | ||
| 2952 | } | ||
| 2922 | 2953 | ||
| 2923 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 2954 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
| 2924 | ni_dpm_vblank_too_short(rdev)) | 2955 | ni_dpm_vblank_too_short(rdev)) |
| @@ -2972,6 +3003,14 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
| 2972 | if (ps->performance_levels[i].mclk > max_mclk_vddc) | 3003 | if (ps->performance_levels[i].mclk > max_mclk_vddc) |
| 2973 | ps->performance_levels[i].mclk = max_mclk_vddc; | 3004 | ps->performance_levels[i].mclk = max_mclk_vddc; |
| 2974 | } | 3005 | } |
| 3006 | if (max_mclk) { | ||
| 3007 | if (ps->performance_levels[i].mclk > max_mclk) | ||
| 3008 | ps->performance_levels[i].mclk = max_mclk; | ||
| 3009 | } | ||
| 3010 | if (max_sclk) { | ||
| 3011 | if (ps->performance_levels[i].sclk > max_sclk) | ||
| 3012 | ps->performance_levels[i].sclk = max_sclk; | ||
| 3013 | } | ||
| 2975 | } | 3014 | } |
| 2976 | 3015 | ||
| 2977 | /* XXX validate the min clocks required for display */ | 3016 | /* XXX validate the min clocks required for display */ |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 4069be89e585..84999242c747 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
| @@ -1632,6 +1632,23 @@ | |||
| 1632 | #define PACKET3_MPEG_INDEX 0x3A | 1632 | #define PACKET3_MPEG_INDEX 0x3A |
| 1633 | #define PACKET3_COPY_DW 0x3B | 1633 | #define PACKET3_COPY_DW 0x3B |
| 1634 | #define PACKET3_WAIT_REG_MEM 0x3C | 1634 | #define PACKET3_WAIT_REG_MEM 0x3C |
| 1635 | #define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) | ||
| 1636 | /* 0 - always | ||
| 1637 | * 1 - < | ||
| 1638 | * 2 - <= | ||
| 1639 | * 3 - == | ||
| 1640 | * 4 - != | ||
| 1641 | * 5 - >= | ||
| 1642 | * 6 - > | ||
| 1643 | */ | ||
| 1644 | #define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) | ||
| 1645 | /* 0 - reg | ||
| 1646 | * 1 - mem | ||
| 1647 | */ | ||
| 1648 | #define WAIT_REG_MEM_ENGINE(x) ((x) << 8) | ||
| 1649 | /* 0 - me | ||
| 1650 | * 1 - pfp | ||
| 1651 | */ | ||
| 1635 | #define PACKET3_MEM_WRITE 0x3D | 1652 | #define PACKET3_MEM_WRITE 0x3D |
| 1636 | #define PACKET3_COPY_DATA 0x40 | 1653 | #define PACKET3_COPY_DATA 0x40 |
| 1637 | #define PACKET3_CP_DMA 0x41 | 1654 | #define PACKET3_CP_DMA 0x41 |
| @@ -1835,6 +1852,7 @@ | |||
| 1835 | #define DMA_PACKET_TRAP 0x7 | 1852 | #define DMA_PACKET_TRAP 0x7 |
| 1836 | #define DMA_PACKET_SRBM_WRITE 0x9 | 1853 | #define DMA_PACKET_SRBM_WRITE 0x9 |
| 1837 | #define DMA_PACKET_CONSTANT_FILL 0xd | 1854 | #define DMA_PACKET_CONSTANT_FILL 0xd |
| 1855 | #define DMA_PACKET_POLL_REG_MEM 0xe | ||
| 1838 | #define DMA_PACKET_NOP 0xf | 1856 | #define DMA_PACKET_NOP 0xf |
| 1839 | 1857 | ||
| 1840 | #define VCE_STATUS 0x20004 | 1858 | #define VCE_STATUS 0x20004 |
