mirror of https://gitee.com/openkylin/linux.git
Merge branch 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux into drm-next
* 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: fix fence driver for dma ring when wb is disabled drm/radeon/si: add VM CS checker support for CP DMA drm/radeon/cayman: add VM CS checker support for CP DMA drm/radeon: add support for CP DMA packet to evergreen CS checker drm/radeon: add support for CP DMA packet to r6xx/r7xx CS checker drm/radeon: add register headers for CP DMA on r6xx-SI drm/radeon: improve mc_stop/mc_resume on r5xx-r7xx drm/radeon: fix amd afusion gpu setup aka sumo v2 drm/radeon: do not move bo to different placement at each cs
This commit is contained in:
commit
9add1ac3dd
|
@ -1821,7 +1821,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
|||
case CHIP_SUMO:
|
||||
rdev->config.evergreen.num_ses = 1;
|
||||
rdev->config.evergreen.max_pipes = 4;
|
||||
rdev->config.evergreen.max_tile_pipes = 2;
|
||||
rdev->config.evergreen.max_tile_pipes = 4;
|
||||
if (rdev->pdev->device == 0x9648)
|
||||
rdev->config.evergreen.max_simds = 3;
|
||||
else if ((rdev->pdev->device == 0x9647) ||
|
||||
|
@ -1844,7 +1844,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
|||
rdev->config.evergreen.sc_prim_fifo_size = 0x40;
|
||||
rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
|
||||
rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
|
||||
gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
|
||||
gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN;
|
||||
break;
|
||||
case CHIP_SUMO2:
|
||||
rdev->config.evergreen.num_ses = 1;
|
||||
|
@ -1866,7 +1866,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
|||
rdev->config.evergreen.sc_prim_fifo_size = 0x40;
|
||||
rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
|
||||
rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
|
||||
gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
|
||||
gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN;
|
||||
break;
|
||||
case CHIP_BARTS:
|
||||
rdev->config.evergreen.num_ses = 2;
|
||||
|
@ -1914,7 +1914,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
|||
break;
|
||||
case CHIP_CAICOS:
|
||||
rdev->config.evergreen.num_ses = 1;
|
||||
rdev->config.evergreen.max_pipes = 4;
|
||||
rdev->config.evergreen.max_pipes = 2;
|
||||
rdev->config.evergreen.max_tile_pipes = 2;
|
||||
rdev->config.evergreen.max_simds = 2;
|
||||
rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
|
||||
|
|
|
@ -2232,6 +2232,95 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
|
|||
ib[idx+2] = upper_32_bits(offset) & 0xff;
|
||||
}
|
||||
break;
|
||||
case PACKET3_CP_DMA:
|
||||
{
|
||||
u32 command, size, info;
|
||||
u64 offset, tmp;
|
||||
if (pkt->count != 4) {
|
||||
DRM_ERROR("bad CP DMA\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
command = radeon_get_ib_value(p, idx+4);
|
||||
size = command & 0x1fffff;
|
||||
info = radeon_get_ib_value(p, idx+1);
|
||||
if (command & PACKET3_CP_DMA_CMD_SAS) {
|
||||
/* src address space is register */
|
||||
/* GDS is ok */
|
||||
if (((info & 0x60000000) >> 29) != 1) {
|
||||
DRM_ERROR("CP DMA SAS not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (command & PACKET3_CP_DMA_CMD_SAIC) {
|
||||
DRM_ERROR("CP DMA SAIC only supported for registers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* src address space is memory */
|
||||
if (((info & 0x60000000) >> 29) == 0) {
|
||||
r = evergreen_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("bad CP DMA SRC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = radeon_get_ib_value(p, idx) +
|
||||
((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
|
||||
|
||||
offset = reloc->lobj.gpu_offset + tmp;
|
||||
|
||||
if ((tmp + size) > radeon_bo_size(reloc->robj)) {
|
||||
dev_warn(p->dev, "CP DMA src buffer too small (%llu %lu)\n",
|
||||
tmp + size, radeon_bo_size(reloc->robj));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ib[idx] = offset;
|
||||
ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
|
||||
} else if (((info & 0x60000000) >> 29) != 2) {
|
||||
DRM_ERROR("bad CP DMA SRC_SEL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (command & PACKET3_CP_DMA_CMD_DAS) {
|
||||
/* dst address space is register */
|
||||
/* GDS is ok */
|
||||
if (((info & 0x00300000) >> 20) != 1) {
|
||||
DRM_ERROR("CP DMA DAS not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
/* dst address space is memory */
|
||||
if (command & PACKET3_CP_DMA_CMD_DAIC) {
|
||||
DRM_ERROR("CP DMA DAIC only supported for registers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (((info & 0x00300000) >> 20) == 0) {
|
||||
r = evergreen_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("bad CP DMA DST\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = radeon_get_ib_value(p, idx+2) +
|
||||
((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32);
|
||||
|
||||
offset = reloc->lobj.gpu_offset + tmp;
|
||||
|
||||
if ((tmp + size) > radeon_bo_size(reloc->robj)) {
|
||||
dev_warn(p->dev, "CP DMA dst buffer too small (%llu %lu)\n",
|
||||
tmp + size, radeon_bo_size(reloc->robj));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ib[idx+2] = offset;
|
||||
ib[idx+3] = upper_32_bits(offset) & 0xff;
|
||||
} else {
|
||||
DRM_ERROR("bad CP DMA DST_SEL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PACKET3_SURFACE_SYNC:
|
||||
if (pkt->count != 3) {
|
||||
DRM_ERROR("bad SURFACE_SYNC\n");
|
||||
|
@ -2843,6 +2932,7 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev,
|
|||
u32 idx = pkt->idx + 1;
|
||||
u32 idx_value = ib[idx];
|
||||
u32 start_reg, end_reg, reg, i;
|
||||
u32 command, info;
|
||||
|
||||
switch (pkt->opcode) {
|
||||
case PACKET3_NOP:
|
||||
|
@ -2917,6 +3007,52 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case PACKET3_CP_DMA:
|
||||
command = ib[idx + 4];
|
||||
info = ib[idx + 1];
|
||||
if (command & PACKET3_CP_DMA_CMD_SAS) {
|
||||
/* src address space is register */
|
||||
if (((info & 0x60000000) >> 29) == 0) {
|
||||
start_reg = idx_value << 2;
|
||||
if (command & PACKET3_CP_DMA_CMD_SAIC) {
|
||||
reg = start_reg;
|
||||
if (!evergreen_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad SRC register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (command & 0x1fffff); i++) {
|
||||
reg = start_reg + (4 * i);
|
||||
if (!evergreen_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad SRC register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (command & PACKET3_CP_DMA_CMD_DAS) {
|
||||
/* dst address space is register */
|
||||
if (((info & 0x00300000) >> 20) == 0) {
|
||||
start_reg = ib[idx + 2];
|
||||
if (command & PACKET3_CP_DMA_CMD_DAIC) {
|
||||
reg = start_reg;
|
||||
if (!evergreen_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad DST register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (command & 0x1fffff); i++) {
|
||||
reg = start_reg + (4 * i);
|
||||
if (!evergreen_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad DST register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#define TURKS_GB_ADDR_CONFIG_GOLDEN 0x02010002
|
||||
#define CEDAR_GB_ADDR_CONFIG_GOLDEN 0x02010001
|
||||
#define CAICOS_GB_ADDR_CONFIG_GOLDEN 0x02010001
|
||||
#define SUMO_GB_ADDR_CONFIG_GOLDEN 0x02010002
|
||||
#define SUMO2_GB_ADDR_CONFIG_GOLDEN 0x02010002
|
||||
|
||||
/* Registers */
|
||||
|
||||
|
@ -1033,6 +1035,53 @@
|
|||
#define PACKET3_WAIT_REG_MEM 0x3C
|
||||
#define PACKET3_MEM_WRITE 0x3D
|
||||
#define PACKET3_INDIRECT_BUFFER 0x32
|
||||
#define PACKET3_CP_DMA 0x41
|
||||
/* 1. header
|
||||
* 2. SRC_ADDR_LO or DATA [31:0]
|
||||
* 3. CP_SYNC [31] | SRC_SEL [30:29] | ENGINE [27] | DST_SEL [21:20] |
|
||||
* SRC_ADDR_HI [7:0]
|
||||
* 4. DST_ADDR_LO [31:0]
|
||||
* 5. DST_ADDR_HI [7:0]
|
||||
* 6. COMMAND [29:22] | BYTE_COUNT [20:0]
|
||||
*/
|
||||
# define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20)
|
||||
/* 0 - SRC_ADDR
|
||||
* 1 - GDS
|
||||
*/
|
||||
# define PACKET3_CP_DMA_ENGINE(x) ((x) << 27)
|
||||
/* 0 - ME
|
||||
* 1 - PFP
|
||||
*/
|
||||
# define PACKET3_CP_DMA_SRC_SEL(x) ((x) << 29)
|
||||
/* 0 - SRC_ADDR
|
||||
* 1 - GDS
|
||||
* 2 - DATA
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CP_SYNC (1 << 31)
|
||||
/* COMMAND */
|
||||
# define PACKET3_CP_DMA_DIS_WC (1 << 21)
|
||||
# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
|
||||
/* 0 - none
|
||||
* 1 - 8 in 16
|
||||
* 2 - 8 in 32
|
||||
* 3 - 8 in 64
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24)
|
||||
/* 0 - none
|
||||
* 1 - 8 in 16
|
||||
* 2 - 8 in 32
|
||||
* 3 - 8 in 64
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_SAS (1 << 26)
|
||||
/* 0 - memory
|
||||
* 1 - register
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_DAS (1 << 27)
|
||||
/* 0 - memory
|
||||
* 1 - register
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_SAIC (1 << 28)
|
||||
# define PACKET3_CP_DMA_CMD_DAIC (1 << 29)
|
||||
#define PACKET3_SURFACE_SYNC 0x43
|
||||
# define PACKET3_CB0_DEST_BASE_ENA (1 << 6)
|
||||
# define PACKET3_CB1_DEST_BASE_ENA (1 << 7)
|
||||
|
|
|
@ -2533,11 +2533,12 @@ void r600_dma_fence_ring_emit(struct radeon_device *rdev,
|
|||
{
|
||||
struct radeon_ring *ring = &rdev->ring[fence->ring];
|
||||
u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
|
||||
|
||||
/* write the fence */
|
||||
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0));
|
||||
radeon_ring_write(ring, addr & 0xfffffffc);
|
||||
radeon_ring_write(ring, (upper_32_bits(addr) & 0xff));
|
||||
radeon_ring_write(ring, fence->seq);
|
||||
radeon_ring_write(ring, lower_32_bits(fence->seq));
|
||||
/* generate an interrupt */
|
||||
radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0));
|
||||
}
|
||||
|
|
|
@ -1949,6 +1949,78 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
ib[idx+2] = upper_32_bits(offset) & 0xff;
|
||||
}
|
||||
break;
|
||||
case PACKET3_CP_DMA:
|
||||
{
|
||||
u32 command, size;
|
||||
u64 offset, tmp;
|
||||
if (pkt->count != 4) {
|
||||
DRM_ERROR("bad CP DMA\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
command = radeon_get_ib_value(p, idx+4);
|
||||
size = command & 0x1fffff;
|
||||
if (command & PACKET3_CP_DMA_CMD_SAS) {
|
||||
/* src address space is register */
|
||||
DRM_ERROR("CP DMA SAS not supported\n");
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (command & PACKET3_CP_DMA_CMD_SAIC) {
|
||||
DRM_ERROR("CP DMA SAIC only supported for registers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* src address space is memory */
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("bad CP DMA SRC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = radeon_get_ib_value(p, idx) +
|
||||
((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
|
||||
|
||||
offset = reloc->lobj.gpu_offset + tmp;
|
||||
|
||||
if ((tmp + size) > radeon_bo_size(reloc->robj)) {
|
||||
dev_warn(p->dev, "CP DMA src buffer too small (%llu %lu)\n",
|
||||
tmp + size, radeon_bo_size(reloc->robj));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ib[idx] = offset;
|
||||
ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
|
||||
}
|
||||
if (command & PACKET3_CP_DMA_CMD_DAS) {
|
||||
/* dst address space is register */
|
||||
DRM_ERROR("CP DMA DAS not supported\n");
|
||||
return -EINVAL;
|
||||
} else {
|
||||
/* dst address space is memory */
|
||||
if (command & PACKET3_CP_DMA_CMD_DAIC) {
|
||||
DRM_ERROR("CP DMA DAIC only supported for registers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("bad CP DMA DST\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = radeon_get_ib_value(p, idx+2) +
|
||||
((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32);
|
||||
|
||||
offset = reloc->lobj.gpu_offset + tmp;
|
||||
|
||||
if ((tmp + size) > radeon_bo_size(reloc->robj)) {
|
||||
dev_warn(p->dev, "CP DMA dst buffer too small (%llu %lu)\n",
|
||||
tmp + size, radeon_bo_size(reloc->robj));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ib[idx+2] = offset;
|
||||
ib[idx+3] = upper_32_bits(offset) & 0xff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PACKET3_SURFACE_SYNC:
|
||||
if (pkt->count != 3) {
|
||||
DRM_ERROR("bad SURFACE_SYNC\n");
|
||||
|
|
|
@ -96,6 +96,15 @@
|
|||
#define R600_CONFIG_F0_BASE 0x542C
|
||||
#define R600_CONFIG_APER_SIZE 0x5430
|
||||
|
||||
#define R600_BIF_FB_EN 0x5490
|
||||
#define R600_FB_READ_EN (1 << 0)
|
||||
#define R600_FB_WRITE_EN (1 << 1)
|
||||
|
||||
#define R600_CITF_CNTL 0x200c
|
||||
#define R600_BLACKOUT_MASK 0x00000003
|
||||
|
||||
#define R700_MC_CITF_CNTL 0x25c0
|
||||
|
||||
#define R600_ROM_CNTL 0x1600
|
||||
# define R600_SCK_OVERWRITE (1 << 1)
|
||||
# define R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT 28
|
||||
|
|
|
@ -1186,6 +1186,38 @@
|
|||
#define PACKET3_WAIT_REG_MEM 0x3C
|
||||
#define PACKET3_MEM_WRITE 0x3D
|
||||
#define PACKET3_INDIRECT_BUFFER 0x32
|
||||
#define PACKET3_CP_DMA 0x41
|
||||
/* 1. header
|
||||
* 2. SRC_ADDR_LO [31:0]
|
||||
* 3. CP_SYNC [31] | SRC_ADDR_HI [7:0]
|
||||
* 4. DST_ADDR_LO [31:0]
|
||||
* 5. DST_ADDR_HI [7:0]
|
||||
* 6. COMMAND [29:22] | BYTE_COUNT [20:0]
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CP_SYNC (1 << 31)
|
||||
/* COMMAND */
|
||||
# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
|
||||
/* 0 - none
|
||||
* 1 - 8 in 16
|
||||
* 2 - 8 in 32
|
||||
* 3 - 8 in 64
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24)
|
||||
/* 0 - none
|
||||
* 1 - 8 in 16
|
||||
* 2 - 8 in 32
|
||||
* 3 - 8 in 64
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_SAS (1 << 26)
|
||||
/* 0 - memory
|
||||
* 1 - register
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_DAS (1 << 27)
|
||||
/* 0 - memory
|
||||
* 1 - register
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_SAIC (1 << 28)
|
||||
# define PACKET3_CP_DMA_CMD_DAIC (1 << 29)
|
||||
#define PACKET3_SURFACE_SYNC 0x43
|
||||
# define PACKET3_CB0_DEST_BASE_ENA (1 << 6)
|
||||
# define PACKET3_TC_ACTION_ENA (1 << 23)
|
||||
|
|
|
@ -318,6 +318,7 @@ struct radeon_bo {
|
|||
struct list_head list;
|
||||
/* Protected by tbo.reserved */
|
||||
u32 placements[3];
|
||||
u32 busy_placements[3];
|
||||
struct ttm_placement placement;
|
||||
struct ttm_buffer_object tbo;
|
||||
struct ttm_bo_kmap_obj kmap;
|
||||
|
|
|
@ -263,6 +263,7 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev);
|
|||
struct rv515_mc_save {
|
||||
u32 vga_render_control;
|
||||
u32 vga_hdp_control;
|
||||
bool crtc_enabled[2];
|
||||
};
|
||||
|
||||
int rv515_init(struct radeon_device *rdev);
|
||||
|
|
|
@ -772,7 +772,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
|
|||
int r;
|
||||
|
||||
radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
|
||||
if (rdev->wb.use_event) {
|
||||
if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) {
|
||||
rdev->fence_drv[ring].scratch_reg = 0;
|
||||
index = R600_WB_EVENT_OFFSET + ring * 4;
|
||||
} else {
|
||||
|
|
|
@ -84,7 +84,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
|
|||
rbo->placement.fpfn = 0;
|
||||
rbo->placement.lpfn = 0;
|
||||
rbo->placement.placement = rbo->placements;
|
||||
rbo->placement.busy_placement = rbo->placements;
|
||||
if (domain & RADEON_GEM_DOMAIN_VRAM)
|
||||
rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
|
||||
TTM_PL_FLAG_VRAM;
|
||||
|
@ -105,6 +104,14 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
|
|||
if (!c)
|
||||
rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
|
||||
rbo->placement.num_placement = c;
|
||||
|
||||
c = 0;
|
||||
rbo->placement.busy_placement = rbo->busy_placements;
|
||||
if (rbo->rdev->flags & RADEON_IS_AGP) {
|
||||
rbo->busy_placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT;
|
||||
} else {
|
||||
rbo->busy_placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT;
|
||||
}
|
||||
rbo->placement.num_busy_placement = c;
|
||||
}
|
||||
|
||||
|
@ -350,7 +357,6 @@ int radeon_bo_list_validate(struct list_head *head)
|
|||
{
|
||||
struct radeon_bo_list *lobj;
|
||||
struct radeon_bo *bo;
|
||||
u32 domain;
|
||||
int r;
|
||||
|
||||
r = ttm_eu_reserve_buffers(head);
|
||||
|
@ -360,17 +366,9 @@ int radeon_bo_list_validate(struct list_head *head)
|
|||
list_for_each_entry(lobj, head, tv.head) {
|
||||
bo = lobj->bo;
|
||||
if (!bo->pin_count) {
|
||||
domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain;
|
||||
|
||||
retry:
|
||||
radeon_ttm_placement_from_domain(bo, domain);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement,
|
||||
true, false);
|
||||
if (unlikely(r)) {
|
||||
if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) {
|
||||
domain |= RADEON_GEM_DOMAIN_GTT;
|
||||
goto retry;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,12 @@ static int rv515_debugfs_ga_info_init(struct radeon_device *rdev);
|
|||
static void rv515_gpu_init(struct radeon_device *rdev);
|
||||
int rv515_mc_wait_for_idle(struct radeon_device *rdev);
|
||||
|
||||
static const u32 crtc_offsets[2] =
|
||||
{
|
||||
0,
|
||||
AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
|
||||
};
|
||||
|
||||
void rv515_debugfs(struct radeon_device *rdev)
|
||||
{
|
||||
if (r100_debugfs_rbbm_init(rdev)) {
|
||||
|
@ -281,30 +287,114 @@ static int rv515_debugfs_ga_info_init(struct radeon_device *rdev)
|
|||
|
||||
void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
|
||||
{
|
||||
u32 crtc_enabled, tmp, frame_count, blackout;
|
||||
int i, j;
|
||||
|
||||
save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL);
|
||||
save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL);
|
||||
|
||||
/* Stop all video */
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
|
||||
/* disable VGA render */
|
||||
WREG32(R_000300_VGA_RENDER_CONTROL, 0);
|
||||
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
|
||||
WREG32(R_006080_D1CRTC_CONTROL, 0);
|
||||
WREG32(R_006880_D2CRTC_CONTROL, 0);
|
||||
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
|
||||
WREG32(R_000330_D1VGA_CONTROL, 0);
|
||||
WREG32(R_000338_D2VGA_CONTROL, 0);
|
||||
/* blank the display controllers */
|
||||
for (i = 0; i < rdev->num_crtc; i++) {
|
||||
crtc_enabled = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]) & AVIVO_CRTC_EN;
|
||||
if (crtc_enabled) {
|
||||
save->crtc_enabled[i] = true;
|
||||
tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]);
|
||||
if (!(tmp & AVIVO_CRTC_DISP_READ_REQUEST_DISABLE)) {
|
||||
radeon_wait_for_vblank(rdev, i);
|
||||
tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE;
|
||||
WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp);
|
||||
}
|
||||
/* wait for the next frame */
|
||||
frame_count = radeon_get_vblank_counter(rdev, i);
|
||||
for (j = 0; j < rdev->usec_timeout; j++) {
|
||||
if (radeon_get_vblank_counter(rdev, i) != frame_count)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
} else {
|
||||
save->crtc_enabled[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
radeon_mc_wait_for_idle(rdev);
|
||||
|
||||
if (rdev->family >= CHIP_R600) {
|
||||
if (rdev->family >= CHIP_RV770)
|
||||
blackout = RREG32(R700_MC_CITF_CNTL);
|
||||
else
|
||||
blackout = RREG32(R600_CITF_CNTL);
|
||||
if ((blackout & R600_BLACKOUT_MASK) != R600_BLACKOUT_MASK) {
|
||||
/* Block CPU access */
|
||||
WREG32(R600_BIF_FB_EN, 0);
|
||||
/* blackout the MC */
|
||||
blackout |= R600_BLACKOUT_MASK;
|
||||
if (rdev->family >= CHIP_RV770)
|
||||
WREG32(R700_MC_CITF_CNTL, blackout);
|
||||
else
|
||||
WREG32(R600_CITF_CNTL, blackout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
|
||||
{
|
||||
WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
|
||||
/* Unlock host access */
|
||||
u32 tmp, frame_count;
|
||||
int i, j;
|
||||
|
||||
/* update crtc base addresses */
|
||||
for (i = 0; i < rdev->num_crtc; i++) {
|
||||
if (rdev->family >= CHIP_RV770) {
|
||||
if (i == 1) {
|
||||
WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
|
||||
upper_32_bits(rdev->mc.vram_start));
|
||||
WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
|
||||
upper_32_bits(rdev->mc.vram_start));
|
||||
} else {
|
||||
WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
|
||||
upper_32_bits(rdev->mc.vram_start));
|
||||
WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
|
||||
upper_32_bits(rdev->mc.vram_start));
|
||||
}
|
||||
}
|
||||
WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
|
||||
(u32)rdev->mc.vram_start);
|
||||
WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
|
||||
(u32)rdev->mc.vram_start);
|
||||
}
|
||||
WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
|
||||
|
||||
if (rdev->family >= CHIP_R600) {
|
||||
/* unblackout the MC */
|
||||
if (rdev->family >= CHIP_RV770)
|
||||
tmp = RREG32(R700_MC_CITF_CNTL);
|
||||
else
|
||||
tmp = RREG32(R600_CITF_CNTL);
|
||||
tmp &= ~R600_BLACKOUT_MASK;
|
||||
if (rdev->family >= CHIP_RV770)
|
||||
WREG32(R700_MC_CITF_CNTL, tmp);
|
||||
else
|
||||
WREG32(R600_CITF_CNTL, tmp);
|
||||
/* allow CPU access */
|
||||
WREG32(R600_BIF_FB_EN, R600_FB_READ_EN | R600_FB_WRITE_EN);
|
||||
}
|
||||
|
||||
for (i = 0; i < rdev->num_crtc; i++) {
|
||||
if (save->crtc_enabled[i]) {
|
||||
tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]);
|
||||
tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE;
|
||||
WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp);
|
||||
/* wait for the next frame */
|
||||
frame_count = radeon_get_vblank_counter(rdev, i);
|
||||
for (j = 0; j < rdev->usec_timeout; j++) {
|
||||
if (radeon_get_vblank_counter(rdev, i) != frame_count)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Unlock vga access */
|
||||
WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
|
||||
mdelay(1);
|
||||
WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
|
||||
|
|
|
@ -2550,6 +2550,7 @@ static int si_vm_packet3_gfx_check(struct radeon_device *rdev,
|
|||
u32 idx = pkt->idx + 1;
|
||||
u32 idx_value = ib[idx];
|
||||
u32 start_reg, end_reg, reg, i;
|
||||
u32 command, info;
|
||||
|
||||
switch (pkt->opcode) {
|
||||
case PACKET3_NOP:
|
||||
|
@ -2649,6 +2650,52 @@ static int si_vm_packet3_gfx_check(struct radeon_device *rdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case PACKET3_CP_DMA:
|
||||
command = ib[idx + 4];
|
||||
info = ib[idx + 1];
|
||||
if (command & PACKET3_CP_DMA_CMD_SAS) {
|
||||
/* src address space is register */
|
||||
if (((info & 0x60000000) >> 29) == 0) {
|
||||
start_reg = idx_value << 2;
|
||||
if (command & PACKET3_CP_DMA_CMD_SAIC) {
|
||||
reg = start_reg;
|
||||
if (!si_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad SRC register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (command & 0x1fffff); i++) {
|
||||
reg = start_reg + (4 * i);
|
||||
if (!si_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad SRC register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (command & PACKET3_CP_DMA_CMD_DAS) {
|
||||
/* dst address space is register */
|
||||
if (((info & 0x00300000) >> 20) == 0) {
|
||||
start_reg = ib[idx + 2];
|
||||
if (command & PACKET3_CP_DMA_CMD_DAIC) {
|
||||
reg = start_reg;
|
||||
if (!si_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad DST register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (command & 0x1fffff); i++) {
|
||||
reg = start_reg + (4 * i);
|
||||
if (!si_vm_reg_valid(reg)) {
|
||||
DRM_ERROR("CP DMA Bad DST register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -849,6 +849,54 @@
|
|||
#define PACKET3_WAIT_REG_MEM 0x3C
|
||||
#define PACKET3_MEM_WRITE 0x3D
|
||||
#define PACKET3_COPY_DATA 0x40
|
||||
#define PACKET3_CP_DMA 0x41
|
||||
/* 1. header
|
||||
* 2. SRC_ADDR_LO or DATA [31:0]
|
||||
* 3. CP_SYNC [31] | SRC_SEL [30:29] | ENGINE [27] | DST_SEL [21:20] |
|
||||
* SRC_ADDR_HI [7:0]
|
||||
* 4. DST_ADDR_LO [31:0]
|
||||
* 5. DST_ADDR_HI [7:0]
|
||||
* 6. COMMAND [30:21] | BYTE_COUNT [20:0]
|
||||
*/
|
||||
# define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20)
|
||||
/* 0 - SRC_ADDR
|
||||
* 1 - GDS
|
||||
*/
|
||||
# define PACKET3_CP_DMA_ENGINE(x) ((x) << 27)
|
||||
/* 0 - ME
|
||||
* 1 - PFP
|
||||
*/
|
||||
# define PACKET3_CP_DMA_SRC_SEL(x) ((x) << 29)
|
||||
/* 0 - SRC_ADDR
|
||||
* 1 - GDS
|
||||
* 2 - DATA
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CP_SYNC (1 << 31)
|
||||
/* COMMAND */
|
||||
# define PACKET3_CP_DMA_DIS_WC (1 << 21)
|
||||
# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
|
||||
/* 0 - none
|
||||
* 1 - 8 in 16
|
||||
* 2 - 8 in 32
|
||||
* 3 - 8 in 64
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24)
|
||||
/* 0 - none
|
||||
* 1 - 8 in 16
|
||||
* 2 - 8 in 32
|
||||
* 3 - 8 in 64
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_SAS (1 << 26)
|
||||
/* 0 - memory
|
||||
* 1 - register
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_DAS (1 << 27)
|
||||
/* 0 - memory
|
||||
* 1 - register
|
||||
*/
|
||||
# define PACKET3_CP_DMA_CMD_SAIC (1 << 28)
|
||||
# define PACKET3_CP_DMA_CMD_DAIC (1 << 29)
|
||||
# define PACKET3_CP_DMA_CMD_RAW_WAIT (1 << 30)
|
||||
#define PACKET3_PFP_SYNC_ME 0x42
|
||||
#define PACKET3_SURFACE_SYNC 0x43
|
||||
# define PACKET3_DEST_BASE_0_ENA (1 << 0)
|
||||
|
|
Loading…
Reference in New Issue