mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
Merge branch 'drm-fixes-3.19' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
Some radeon fixes for 3.19: - GPUVM stability fixes - SI dpm quirks - Regression fixes * 'drm-fixes-3.19' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: use rv515_ring_start on r5xx drm/radeon: add si dpm quirk list drm/radeon: don't print error on -ERESTARTSYS drm/radeon: add a dpm quirk list drm/radeon: fix VM flush on CIK (v3) drm/radeon: fix VM flush on SI (v3) drm/radeon: fix VM flush on cayman/aruba (v3)
This commit is contained in:
commit
b46ce98d93
12 changed files with 186 additions and 3 deletions
|
@ -6033,6 +6033,17 @@ void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
|
|||
radeon_ring_write(ring, 0);
|
||||
radeon_ring_write(ring, 1 << vm_id);
|
||||
|
||||
/* wait for the invalidate to complete */
|
||||
radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
|
||||
radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */
|
||||
WAIT_REG_MEM_FUNCTION(0) | /* always */
|
||||
WAIT_REG_MEM_ENGINE(0))); /* me */
|
||||
radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
|
||||
radeon_ring_write(ring, 0);
|
||||
radeon_ring_write(ring, 0); /* ref */
|
||||
radeon_ring_write(ring, 0); /* mask */
|
||||
radeon_ring_write(ring, 0x20); /* poll interval */
|
||||
|
||||
/* compute doesn't have PFP */
|
||||
if (usepfp) {
|
||||
/* sync PFP to ME, otherwise we might get invalid PFP reads */
|
||||
|
|
|
@ -903,6 +903,9 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib)
|
|||
void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
{
|
||||
u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(0) |
|
||||
SDMA_POLL_REG_MEM_EXTRA_FUNC(0)); /* always */
|
||||
|
||||
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
|
||||
if (vm_id < 8) {
|
||||
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,
|
|||
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
|
||||
radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
|
||||
radeon_ring_write(ring, 1 << vm_id);
|
||||
|
||||
radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
|
||||
radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
|
||||
radeon_ring_write(ring, 0);
|
||||
radeon_ring_write(ring, 0); /* reference */
|
||||
radeon_ring_write(ring, 0); /* mask */
|
||||
radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */
|
||||
}
|
||||
|
||||
|
|
|
@ -2516,6 +2516,16 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
|
|||
radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
|
||||
radeon_ring_write(ring, 1 << vm_id);
|
||||
|
||||
/* wait for the invalidate to complete */
|
||||
radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
|
||||
radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */
|
||||
WAIT_REG_MEM_ENGINE(0))); /* me */
|
||||
radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
|
||||
radeon_ring_write(ring, 0);
|
||||
radeon_ring_write(ring, 0); /* ref */
|
||||
radeon_ring_write(ring, 0); /* mask */
|
||||
radeon_ring_write(ring, 0x20); /* poll interval */
|
||||
|
||||
/* sync PFP to ME, otherwise we might get invalid PFP reads */
|
||||
radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
|
||||
radeon_ring_write(ring, 0x0);
|
||||
|
|
|
@ -463,5 +463,11 @@ void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
|
|||
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
|
||||
radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
|
||||
radeon_ring_write(ring, 1 << vm_id);
|
||||
|
||||
/* wait for invalidate to complete */
|
||||
radeon_ring_write(ring, DMA_SRBM_READ_PACKET);
|
||||
radeon_ring_write(ring, (0xff << 20) | (VM_INVALIDATE_REQUEST >> 2));
|
||||
radeon_ring_write(ring, 0); /* mask */
|
||||
radeon_ring_write(ring, 0); /* value */
|
||||
}
|
||||
|
||||
|
|
|
@ -1133,6 +1133,23 @@
|
|||
#define PACKET3_MEM_SEMAPHORE 0x39
|
||||
#define PACKET3_MPEG_INDEX 0x3A
|
||||
#define PACKET3_WAIT_REG_MEM 0x3C
|
||||
#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0)
|
||||
/* 0 - always
|
||||
* 1 - <
|
||||
* 2 - <=
|
||||
* 3 - ==
|
||||
* 4 - !=
|
||||
* 5 - >=
|
||||
* 6 - >
|
||||
*/
|
||||
#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4)
|
||||
/* 0 - reg
|
||||
* 1 - mem
|
||||
*/
|
||||
#define WAIT_REG_MEM_ENGINE(x) ((x) << 8)
|
||||
/* 0 - me
|
||||
* 1 - pfp
|
||||
*/
|
||||
#define PACKET3_MEM_WRITE 0x3D
|
||||
#define PACKET3_PFP_SYNC_ME 0x42
|
||||
#define PACKET3_SURFACE_SYNC 0x43
|
||||
|
@ -1272,6 +1289,13 @@
|
|||
(1 << 21) | \
|
||||
(((n) & 0xFFFFF) << 0))
|
||||
|
||||
#define DMA_SRBM_POLL_PACKET ((9 << 28) | \
|
||||
(1 << 27) | \
|
||||
(1 << 26))
|
||||
|
||||
#define DMA_SRBM_READ_PACKET ((9 << 28) | \
|
||||
(1 << 27))
|
||||
|
||||
/* async DMA Packet types */
|
||||
#define DMA_PACKET_WRITE 0x2
|
||||
#define DMA_PACKET_COPY 0x3
|
||||
|
|
|
@ -333,6 +333,20 @@ static struct radeon_asic_ring r300_gfx_ring = {
|
|||
.set_wptr = &r100_gfx_set_wptr,
|
||||
};
|
||||
|
||||
static struct radeon_asic_ring rv515_gfx_ring = {
|
||||
.ib_execute = &r100_ring_ib_execute,
|
||||
.emit_fence = &r300_fence_ring_emit,
|
||||
.emit_semaphore = &r100_semaphore_ring_emit,
|
||||
.cs_parse = &r300_cs_parse,
|
||||
.ring_start = &rv515_ring_start,
|
||||
.ring_test = &r100_ring_test,
|
||||
.ib_test = &r100_ib_test,
|
||||
.is_lockup = &r100_gpu_is_lockup,
|
||||
.get_rptr = &r100_gfx_get_rptr,
|
||||
.get_wptr = &r100_gfx_get_wptr,
|
||||
.set_wptr = &r100_gfx_set_wptr,
|
||||
};
|
||||
|
||||
static struct radeon_asic r300_asic = {
|
||||
.init = &r300_init,
|
||||
.fini = &r300_fini,
|
||||
|
@ -748,7 +762,7 @@ static struct radeon_asic rv515_asic = {
|
|||
.set_page = &rv370_pcie_gart_set_page,
|
||||
},
|
||||
.ring = {
|
||||
[RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring
|
||||
[RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring
|
||||
},
|
||||
.irq = {
|
||||
.set = &rs600_irq_set,
|
||||
|
@ -814,7 +828,7 @@ static struct radeon_asic r520_asic = {
|
|||
.set_page = &rv370_pcie_gart_set_page,
|
||||
},
|
||||
.ring = {
|
||||
[RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring
|
||||
[RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring
|
||||
},
|
||||
.irq = {
|
||||
.set = &rs600_irq_set,
|
||||
|
|
|
@ -576,7 +576,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev,
|
|||
error_free:
|
||||
drm_free_large(vm_bos);
|
||||
|
||||
if (r)
|
||||
if (r && r != -ERESTARTSYS)
|
||||
DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
|
||||
}
|
||||
|
||||
|
|
|
@ -1287,8 +1287,39 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct radeon_dpm_quirk {
|
||||
u32 chip_vendor;
|
||||
u32 chip_device;
|
||||
u32 subsys_vendor;
|
||||
u32 subsys_device;
|
||||
};
|
||||
|
||||
/* cards with dpm stability problems */
|
||||
static struct radeon_dpm_quirk radeon_dpm_quirk_list[] = {
|
||||
/* TURKS - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 */
|
||||
{ PCI_VENDOR_ID_ATI, 0x6759, 0x1682, 0x3195 },
|
||||
/* TURKS - https://bugzilla.kernel.org/show_bug.cgi?id=83731 */
|
||||
{ PCI_VENDOR_ID_ATI, 0x6840, 0x1179, 0xfb81 },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
int radeon_pm_init(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_dpm_quirk *p = radeon_dpm_quirk_list;
|
||||
bool disable_dpm = false;
|
||||
|
||||
/* Apply dpm quirks */
|
||||
while (p && p->chip_device != 0) {
|
||||
if (rdev->pdev->vendor == p->chip_vendor &&
|
||||
rdev->pdev->device == p->chip_device &&
|
||||
rdev->pdev->subsystem_vendor == p->subsys_vendor &&
|
||||
rdev->pdev->subsystem_device == p->subsys_device) {
|
||||
disable_dpm = true;
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
|
||||
/* enable dpm on rv6xx+ */
|
||||
switch (rdev->family) {
|
||||
case CHIP_RV610:
|
||||
|
@ -1344,6 +1375,8 @@ int radeon_pm_init(struct radeon_device *rdev)
|
|||
(!(rdev->flags & RADEON_IS_IGP)) &&
|
||||
(!rdev->smc_fw))
|
||||
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
||||
else if (disable_dpm && (radeon_dpm == -1))
|
||||
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
||||
else if (radeon_dpm == 0)
|
||||
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
||||
else
|
||||
|
|
|
@ -5057,6 +5057,16 @@ void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
|
|||
radeon_ring_write(ring, 0);
|
||||
radeon_ring_write(ring, 1 << vm_id);
|
||||
|
||||
/* wait for the invalidate to complete */
|
||||
radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
|
||||
radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */
|
||||
WAIT_REG_MEM_ENGINE(0))); /* me */
|
||||
radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
|
||||
radeon_ring_write(ring, 0);
|
||||
radeon_ring_write(ring, 0); /* ref */
|
||||
radeon_ring_write(ring, 0); /* mask */
|
||||
radeon_ring_write(ring, 0x20); /* poll interval */
|
||||
|
||||
/* sync PFP to ME, otherwise we might get invalid PFP reads */
|
||||
radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
|
||||
radeon_ring_write(ring, 0x0);
|
||||
|
|
|
@ -206,6 +206,14 @@ void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
|
|||
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0));
|
||||
radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
|
||||
radeon_ring_write(ring, 1 << vm_id);
|
||||
|
||||
/* wait for invalidate to complete */
|
||||
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_POLL_REG_MEM, 0, 0, 0, 0));
|
||||
radeon_ring_write(ring, VM_INVALIDATE_REQUEST);
|
||||
radeon_ring_write(ring, 0xff << 16); /* retry */
|
||||
radeon_ring_write(ring, 1 << vm_id); /* mask */
|
||||
radeon_ring_write(ring, 0); /* value */
|
||||
radeon_ring_write(ring, (0 << 28) | 0x20); /* func(always) | poll interval */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2908,6 +2908,22 @@ static int si_init_smc_spll_table(struct radeon_device *rdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct si_dpm_quirk {
|
||||
u32 chip_vendor;
|
||||
u32 chip_device;
|
||||
u32 subsys_vendor;
|
||||
u32 subsys_device;
|
||||
u32 max_sclk;
|
||||
u32 max_mclk;
|
||||
};
|
||||
|
||||
/* cards with dpm stability problems */
|
||||
static struct si_dpm_quirk si_dpm_quirk_list[] = {
|
||||
/* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */
|
||||
{ PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
||||
struct radeon_ps *rps)
|
||||
{
|
||||
|
@ -2918,7 +2934,22 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
|||
u32 mclk, sclk;
|
||||
u16 vddc, vddci;
|
||||
u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
|
||||
u32 max_sclk = 0, max_mclk = 0;
|
||||
int i;
|
||||
struct si_dpm_quirk *p = si_dpm_quirk_list;
|
||||
|
||||
/* Apply dpm quirks */
|
||||
while (p && p->chip_device != 0) {
|
||||
if (rdev->pdev->vendor == p->chip_vendor &&
|
||||
rdev->pdev->device == p->chip_device &&
|
||||
rdev->pdev->subsystem_vendor == p->subsys_vendor &&
|
||||
rdev->pdev->subsystem_device == p->subsys_device) {
|
||||
max_sclk = p->max_sclk;
|
||||
max_mclk = p->max_mclk;
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
|
||||
if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
|
||||
ni_dpm_vblank_too_short(rdev))
|
||||
|
@ -2972,6 +3003,14 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
|||
if (ps->performance_levels[i].mclk > max_mclk_vddc)
|
||||
ps->performance_levels[i].mclk = max_mclk_vddc;
|
||||
}
|
||||
if (max_mclk) {
|
||||
if (ps->performance_levels[i].mclk > max_mclk)
|
||||
ps->performance_levels[i].mclk = max_mclk;
|
||||
}
|
||||
if (max_sclk) {
|
||||
if (ps->performance_levels[i].sclk > max_sclk)
|
||||
ps->performance_levels[i].sclk = max_sclk;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX validate the min clocks required for display */
|
||||
|
|
|
@ -1632,6 +1632,23 @@
|
|||
#define PACKET3_MPEG_INDEX 0x3A
|
||||
#define PACKET3_COPY_DW 0x3B
|
||||
#define PACKET3_WAIT_REG_MEM 0x3C
|
||||
#define WAIT_REG_MEM_FUNCTION(x) ((x) << 0)
|
||||
/* 0 - always
|
||||
* 1 - <
|
||||
* 2 - <=
|
||||
* 3 - ==
|
||||
* 4 - !=
|
||||
* 5 - >=
|
||||
* 6 - >
|
||||
*/
|
||||
#define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4)
|
||||
/* 0 - reg
|
||||
* 1 - mem
|
||||
*/
|
||||
#define WAIT_REG_MEM_ENGINE(x) ((x) << 8)
|
||||
/* 0 - me
|
||||
* 1 - pfp
|
||||
*/
|
||||
#define PACKET3_MEM_WRITE 0x3D
|
||||
#define PACKET3_COPY_DATA 0x40
|
||||
#define PACKET3_CP_DMA 0x41
|
||||
|
@ -1835,6 +1852,7 @@
|
|||
#define DMA_PACKET_TRAP 0x7
|
||||
#define DMA_PACKET_SRBM_WRITE 0x9
|
||||
#define DMA_PACKET_CONSTANT_FILL 0xd
|
||||
#define DMA_PACKET_POLL_REG_MEM 0xe
|
||||
#define DMA_PACKET_NOP 0xf
|
||||
|
||||
#define VCE_STATUS 0x20004
|
||||
|
|
Loading…
Reference in a new issue