From 29d654067a98c1cb8874c774e5fd799a038af8a6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 31 May 2012 18:53:36 -0400 Subject: drm/radeon: fix bank information in tiling config While there are cards with more than 8 mem banks, the max number of banks from a tiling perspective is 8, so cap the tiling config at 8 banks. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=43448 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 9 ++++++--- drivers/gpu/drm/radeon/ni.c | 9 ++++++--- drivers/gpu/drm/radeon/rv770.c | 8 ++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 58991af90502..5d9c2c64a8e2 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2136,9 +2136,12 @@ static void evergreen_gpu_init(struct radeon_device *rdev) /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ if (rdev->flags & RADEON_IS_IGP) rdev->config.evergreen.tile_config |= 1 << 4; - else - rdev->config.evergreen.tile_config |= - ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; + else { + if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + rdev->config.evergreen.tile_config |= 1 << 4; + else + rdev->config.evergreen.tile_config |= 0 << 4; + } rdev->config.evergreen.tile_config |= ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8; rdev->config.evergreen.tile_config |= diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ce4e7cc6c905..15f950c870da 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -866,9 +866,12 @@ static void cayman_gpu_init(struct radeon_device *rdev) /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ if (rdev->flags & RADEON_IS_IGP) rdev->config.cayman.tile_config |= 1 << 4; - else - rdev->config.cayman.tile_config |= - ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; + else { + if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + rdev->config.cayman.tile_config |= 1 << 4; + else + rdev->config.cayman.tile_config |= 0 << 4; + } rdev->config.cayman.tile_config |= ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; rdev->config.cayman.tile_config |= diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index c2f473bc13b8..c824d49305a4 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -689,8 +689,12 @@ static void rv770_gpu_init(struct radeon_device *rdev) if (rdev->family == CHIP_RV770) gb_tiling_config |= BANK_TILING(1); - else - gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); + else { + if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + gb_tiling_config |= BANK_TILING(1); + else + gb_tiling_config |= BANK_TILING(0); + } rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3); gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); if ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) -- cgit v1.2.3-55-g7522 From 0b8c30bc4943137a4a36b9cb059b1cc684f5d702 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 31 May 2012 18:54:43 -0400 Subject: drm/radeon: properly program gart on rv740, juniper, cypress, barts, hemlock Need to program an additional VM register. This doesn't not currently cause any problems, but allows us to program the proper backend map in a subsequent patch which should improve performance on these asics. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 5 +++++ drivers/gpu/drm/radeon/evergreend.h | 1 + drivers/gpu/drm/radeon/rv770.c | 2 ++ drivers/gpu/drm/radeon/rv770d.h | 1 + 4 files changed, 9 insertions(+) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 5d9c2c64a8e2..0408ac27a863 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1029,6 +1029,11 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); + if ((rdev->family == CHIP_JUNIPER) || + (rdev->family == CHIP_CYPRESS) || + (rdev->family == CHIP_HEMLOCK) || + (rdev->family == CHIP_BARTS)) + WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp); } WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 79130bfd1d6f..3dd43e760362 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -452,6 +452,7 @@ #define MC_VM_MD_L1_TLB0_CNTL 0x2654 #define MC_VM_MD_L1_TLB1_CNTL 0x2658 #define MC_VM_MD_L1_TLB2_CNTL 0x265C +#define MC_VM_MD_L1_TLB3_CNTL 0x2698 #define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C #define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index c824d49305a4..c12349dba3a2 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -151,6 +151,8 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); + if (rdev->family == CHIP_RV740) + WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 9c549f702f2f..7addbef54b42 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -174,6 +174,7 @@ #define MC_VM_MD_L1_TLB0_CNTL 0x2654 #define MC_VM_MD_L1_TLB1_CNTL 0x2658 #define MC_VM_MD_L1_TLB2_CNTL 0x265C +#define MC_VM_MD_L1_TLB3_CNTL 0x2698 #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -- cgit v1.2.3-55-g7522 From 95c4b23ec4e2fa5604df229ddf134e31d7b3b378 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 31 May 2012 19:00:24 -0400 Subject: drm/radeon: fix HD6790, HD6570 backend programming Without this bit sets we get broken rendering and lockups. fglrx sets this bit. Bugs that should be fixed by this patch : https://bugs.freedesktop.org/show_bug.cgi?id=49792 https://bugzilla.kernel.org/show_bug.cgi?id=43207 https://bugs.freedesktop.org/show_bug.cgi?id=39282 Signed-off-by: Jerome Glisse Cc: stable@vger.kernel.org Acked-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 0408ac27a863..6a57f0d4dae8 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2178,9 +2178,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(CC_SYS_RB_BACKEND_DISABLE, rb); WREG32(GC_USER_RB_BACKEND_DISABLE, rb); WREG32(CC_GC_SHADER_PIPE_CONFIG, sp); - } + } - grbm_gfx_index |= SE_BROADCAST_WRITES; + grbm_gfx_index = INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES; WREG32(GRBM_GFX_INDEX, grbm_gfx_index); WREG32(RLC_GFX_INDEX, grbm_gfx_index); -- cgit v1.2.3-55-g7522 From 416a2bd274566a6f607a271f524b2dc0b84d9106 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 31 May 2012 19:00:25 -0400 Subject: drm/radeon: fixup tiling group size and backendmap on r6xx-r9xx (v4) Tiling group size is always 256bits on r6xx/r7xx/r8xx/9xx. Also fix and simplify render backend map. This now properly sets up the backend map on r6xx-9xx which should improve 3D performance. Vadim benchmarked also: Some benchmarks on juniper (5750), fullscreen 1920x1080, first result - kernel 3.4.0+ (fb21affa), second - with these patches: Lightsmark: 91 fps => 123 fps +35% Doom3: 74 fps => 101 fps +36% Signed-off-by: Alex Deucher Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 368 +++++------------------------------- drivers/gpu/drm/radeon/evergreend.h | 10 + drivers/gpu/drm/radeon/ni.c | 351 +++------------------------------- drivers/gpu/drm/radeon/nid.h | 11 ++ drivers/gpu/drm/radeon/r600.c | 199 +++++++------------ drivers/gpu/drm/radeon/r600d.h | 2 + drivers/gpu/drm/radeon/radeon.h | 5 + drivers/gpu/drm/radeon/rv770.c | 264 +++++--------------------- drivers/gpu/drm/radeon/rv770d.h | 3 + 9 files changed, 222 insertions(+), 991 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 6a57f0d4dae8..01550d05e273 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1558,163 +1558,10 @@ int evergreen_cp_resume(struct radeon_device *rdev) /* * Core functions */ -static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask = 0; - u32 enabled_backends_count = 0; - u32 cur_pipe; - u32 swizzle_pipe[EVERGREEN_MAX_PIPES]; - u32 cur_backend = 0; - u32 i; - bool force_no_swizzle; - - if (num_tile_pipes > EVERGREEN_MAX_PIPES) - num_tile_pipes = EVERGREEN_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > EVERGREEN_MAX_BACKENDS) - num_backends = EVERGREEN_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - for (i = 0; i < EVERGREEN_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * EVERGREEN_MAX_PIPES); - switch (rdev->family) { - case CHIP_CEDAR: - case CHIP_REDWOOD: - case CHIP_PALM: - case CHIP_SUMO: - case CHIP_SUMO2: - case CHIP_TURKS: - case CHIP_CAICOS: - force_no_swizzle = false; - break; - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - case CHIP_JUNIPER: - case CHIP_BARTS: - default: - force_no_swizzle = true; - break; - } - if (force_no_swizzle) { - bool last_backend_enabled = false; - - force_no_swizzle = false; - for (i = 0; i < EVERGREEN_MAX_BACKENDS; ++i) { - if (((enabled_backends_mask >> i) & 1) == 1) { - if (last_backend_enabled) - force_no_swizzle = true; - last_backend_enabled = true; - } else - last_backend_enabled = false; - } - } - - switch (num_tile_pipes) { - case 1: - case 3: - case 5: - case 7: - DRM_ERROR("odd number of pipes!\n"); - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - swizzle_pipe[3] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - } - break; - } - - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % EVERGREEN_MAX_BACKENDS; - - backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); - - cur_backend = (cur_backend + 1) % EVERGREEN_MAX_BACKENDS; - } - - return backend_map; -} - static void evergreen_gpu_init(struct radeon_device *rdev) { - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_pipe_config; - u32 gb_addr_config = 0; + u32 gb_addr_config; u32 mc_shared_chmap, mc_arb_ramcfg; - u32 gb_backend_map; - u32 grbm_gfx_index; u32 sx_debug_1; u32 smx_dc_ctl0; u32 sq_config; @@ -1729,6 +1576,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) u32 sq_stack_resource_mgmt_3; u32 vgt_cache_invalidation; u32 hdp_host_path_cntl, tmp; + u32 disabled_rb_mask; int i, j, num_shader_engines, ps_thread_count; switch (rdev->family) { @@ -1753,6 +1601,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.sc_prim_fifo_size = 0x100; rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = CYPRESS_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_JUNIPER: rdev->config.evergreen.num_ses = 1; @@ -1774,6 +1623,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.sc_prim_fifo_size = 0x100; rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = JUNIPER_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_REDWOOD: rdev->config.evergreen.num_ses = 1; @@ -1795,6 +1645,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.sc_prim_fifo_size = 0x100; 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; break; case CHIP_CEDAR: default: @@ -1817,6 +1668,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 = CEDAR_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_PALM: rdev->config.evergreen.num_ses = 1; @@ -1838,6 +1690,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 = CEDAR_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_SUMO: rdev->config.evergreen.num_ses = 1; @@ -1865,6 +1718,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; break; case CHIP_SUMO2: rdev->config.evergreen.num_ses = 1; @@ -1886,6 +1740,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; break; case CHIP_BARTS: rdev->config.evergreen.num_ses = 2; @@ -1907,6 +1762,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.sc_prim_fifo_size = 0x100; rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = BARTS_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_TURKS: rdev->config.evergreen.num_ses = 1; @@ -1928,6 +1784,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.sc_prim_fifo_size = 0x100; rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = TURKS_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_CAICOS: rdev->config.evergreen.num_ses = 1; @@ -1949,6 +1806,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 = CAICOS_GB_ADDR_CONFIG_GOLDEN; break; } @@ -1965,20 +1823,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) evergreen_fix_pci_max_read_req_size(rdev); - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; - - cc_gc_shader_pipe_config |= - INACTIVE_QD_PIPES((EVERGREEN_MAX_PIPES_MASK << rdev->config.evergreen.max_pipes) - & EVERGREEN_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - INACTIVE_SIMDS((EVERGREEN_MAX_SIMDS_MASK << rdev->config.evergreen.max_simds) - & EVERGREEN_MAX_SIMDS_MASK); - - cc_rb_backend_disable = - BACKEND_DISABLE((EVERGREEN_MAX_BACKENDS_MASK << rdev->config.evergreen.max_backends) - & EVERGREEN_MAX_BACKENDS_MASK); - - mc_shared_chmap = RREG32(MC_SHARED_CHMAP); if ((rdev->family == CHIP_PALM) || (rdev->family == CHIP_SUMO) || @@ -1987,134 +1831,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) else mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - switch (rdev->config.evergreen.max_tile_pipes) { - case 1: - default: - gb_addr_config |= NUM_PIPES(0); - break; - case 2: - gb_addr_config |= NUM_PIPES(1); - break; - case 4: - gb_addr_config |= NUM_PIPES(2); - break; - case 8: - gb_addr_config |= NUM_PIPES(3); - break; - } - - gb_addr_config |= PIPE_INTERLEAVE_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - gb_addr_config |= BANK_INTERLEAVE_SIZE(0); - gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.evergreen.num_ses - 1); - gb_addr_config |= SHADER_ENGINE_TILE_SIZE(1); - gb_addr_config |= NUM_GPUS(0); /* Hemlock? */ - gb_addr_config |= MULTI_GPU_TILE_SIZE(2); - - if (((mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT) > 2) - gb_addr_config |= ROW_SIZE(2); - else - gb_addr_config |= ROW_SIZE((mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT); - - if (rdev->ddev->pdev->device == 0x689e) { - u32 efuse_straps_4; - u32 efuse_straps_3; - u8 efuse_box_bit_131_124; - - WREG32(RCU_IND_INDEX, 0x204); - efuse_straps_4 = RREG32(RCU_IND_DATA); - WREG32(RCU_IND_INDEX, 0x203); - efuse_straps_3 = RREG32(RCU_IND_DATA); - efuse_box_bit_131_124 = (u8)(((efuse_straps_4 & 0xf) << 4) | ((efuse_straps_3 & 0xf0000000) >> 28)); - - switch(efuse_box_bit_131_124) { - case 0x00: - gb_backend_map = 0x76543210; - break; - case 0x55: - gb_backend_map = 0x77553311; - break; - case 0x56: - gb_backend_map = 0x77553300; - break; - case 0x59: - gb_backend_map = 0x77552211; - break; - case 0x66: - gb_backend_map = 0x77443300; - break; - case 0x99: - gb_backend_map = 0x66552211; - break; - case 0x5a: - gb_backend_map = 0x77552200; - break; - case 0xaa: - gb_backend_map = 0x66442200; - break; - case 0x95: - gb_backend_map = 0x66553311; - break; - default: - DRM_ERROR("bad backend map, using default\n"); - gb_backend_map = - evergreen_get_tile_pipe_to_backend_map(rdev, - rdev->config.evergreen.max_tile_pipes, - rdev->config.evergreen.max_backends, - ((EVERGREEN_MAX_BACKENDS_MASK << - rdev->config.evergreen.max_backends) & - EVERGREEN_MAX_BACKENDS_MASK)); - break; - } - } else if (rdev->ddev->pdev->device == 0x68b9) { - u32 efuse_straps_3; - u8 efuse_box_bit_127_124; - - WREG32(RCU_IND_INDEX, 0x203); - efuse_straps_3 = RREG32(RCU_IND_DATA); - efuse_box_bit_127_124 = (u8)((efuse_straps_3 & 0xF0000000) >> 28); - - switch(efuse_box_bit_127_124) { - case 0x0: - gb_backend_map = 0x00003210; - break; - case 0x5: - case 0x6: - case 0x9: - case 0xa: - gb_backend_map = 0x00003311; - break; - default: - DRM_ERROR("bad backend map, using default\n"); - gb_backend_map = - evergreen_get_tile_pipe_to_backend_map(rdev, - rdev->config.evergreen.max_tile_pipes, - rdev->config.evergreen.max_backends, - ((EVERGREEN_MAX_BACKENDS_MASK << - rdev->config.evergreen.max_backends) & - EVERGREEN_MAX_BACKENDS_MASK)); - break; - } - } else { - switch (rdev->family) { - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - case CHIP_BARTS: - gb_backend_map = 0x66442200; - break; - case CHIP_JUNIPER: - gb_backend_map = 0x00002200; - break; - default: - gb_backend_map = - evergreen_get_tile_pipe_to_backend_map(rdev, - rdev->config.evergreen.max_tile_pipes, - rdev->config.evergreen.max_backends, - ((EVERGREEN_MAX_BACKENDS_MASK << - rdev->config.evergreen.max_backends) & - EVERGREEN_MAX_BACKENDS_MASK)); - } - } - /* setup tiling info dword. gb_addr_config is not adequate since it does * not have bank info, so create a custom tiling dword. * bits 3:0 num_pipes @@ -2147,42 +1863,48 @@ static void evergreen_gpu_init(struct radeon_device *rdev) else rdev->config.evergreen.tile_config |= 0 << 4; } - rdev->config.evergreen.tile_config |= - ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8; + rdev->config.evergreen.tile_config |= 0 << 8; rdev->config.evergreen.tile_config |= ((gb_addr_config & 0x30000000) >> 28) << 12; - rdev->config.evergreen.backend_map = gb_backend_map; - WREG32(GB_BACKEND_MAP, gb_backend_map); - WREG32(GB_ADDR_CONFIG, gb_addr_config); - WREG32(DMIF_ADDR_CONFIG, gb_addr_config); - WREG32(HDP_ADDR_CONFIG, gb_addr_config); - - num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; - grbm_gfx_index = INSTANCE_BROADCAST_WRITES; + num_shader_engines = (gb_addr_config & NUM_SHADER_ENGINES(3) >> 12) + 1; - for (i = 0; i < rdev->config.evergreen.num_ses; i++) { - u32 rb = cc_rb_backend_disable | (0xf0 << 16); - u32 sp = cc_gc_shader_pipe_config; - u32 gfx = grbm_gfx_index | SE_INDEX(i); + if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) { + u32 efuse_straps_4; + u32 efuse_straps_3; - if (i == num_shader_engines) { - rb |= BACKEND_DISABLE(EVERGREEN_MAX_BACKENDS_MASK); - sp |= INACTIVE_SIMDS(EVERGREEN_MAX_SIMDS_MASK); + WREG32(RCU_IND_INDEX, 0x204); + efuse_straps_4 = RREG32(RCU_IND_DATA); + WREG32(RCU_IND_INDEX, 0x203); + efuse_straps_3 = RREG32(RCU_IND_DATA); + tmp = (((efuse_straps_4 & 0xf) << 4) | + ((efuse_straps_3 & 0xf0000000) >> 28)); + } else { + tmp = 0; + for (i = (rdev->config.evergreen.num_ses - 1); i >= 0; i--) { + u32 rb_disable_bitmap; + + WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); + WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); + rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16; + tmp <<= 4; + tmp |= rb_disable_bitmap; } + } + /* enabled rb are just the one not disabled :) */ + disabled_rb_mask = tmp; - WREG32(GRBM_GFX_INDEX, gfx); - WREG32(RLC_GFX_INDEX, gfx); + WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); + WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); - WREG32(CC_RB_BACKEND_DISABLE, rb); - WREG32(CC_SYS_RB_BACKEND_DISABLE, rb); - WREG32(GC_USER_RB_BACKEND_DISABLE, rb); - WREG32(CC_GC_SHADER_PIPE_CONFIG, sp); - } + WREG32(GB_ADDR_CONFIG, gb_addr_config); + WREG32(DMIF_ADDR_CONFIG, gb_addr_config); + WREG32(HDP_ADDR_CONFIG, gb_addr_config); - grbm_gfx_index = INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES; - WREG32(GRBM_GFX_INDEX, grbm_gfx_index); - WREG32(RLC_GFX_INDEX, grbm_gfx_index); + tmp = gb_addr_config & NUM_PIPES_MASK; + tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, + EVERGREEN_MAX_BACKENDS, disabled_rb_mask); + WREG32(GB_BACKEND_MAP, tmp); WREG32(CGTS_SYS_TCC_DISABLE, 0); WREG32(CGTS_TCC_DISABLE, 0); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 3dd43e760362..2773039b4902 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -37,6 +37,15 @@ #define EVERGREEN_MAX_PIPES_MASK 0xFF #define EVERGREEN_MAX_LDS_NUM 0xFFFF +#define CYPRESS_GB_ADDR_CONFIG_GOLDEN 0x02011003 +#define BARTS_GB_ADDR_CONFIG_GOLDEN 0x02011003 +#define CAYMAN_GB_ADDR_CONFIG_GOLDEN 0x02011003 +#define JUNIPER_GB_ADDR_CONFIG_GOLDEN 0x02010002 +#define REDWOOD_GB_ADDR_CONFIG_GOLDEN 0x02010002 +#define TURKS_GB_ADDR_CONFIG_GOLDEN 0x02010002 +#define CEDAR_GB_ADDR_CONFIG_GOLDEN 0x02010001 +#define CAICOS_GB_ADDR_CONFIG_GOLDEN 0x02010001 + /* Registers */ #define RCU_IND_INDEX 0x100 @@ -54,6 +63,7 @@ #define BACKEND_DISABLE(x) ((x) << 16) #define GB_ADDR_CONFIG 0x98F8 #define NUM_PIPES(x) ((x) << 0) +#define NUM_PIPES_MASK 0x0000000f #define PIPE_INTERLEAVE_SIZE(x) ((x) << 4) #define BANK_INTERLEAVE_SIZE(x) ((x) << 8) #define NUM_SHADER_ENGINES(x) ((x) << 12) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 15f950c870da..3df4efa11942 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -417,215 +417,17 @@ out: /* * Core functions */ -static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends_per_asic, - u32 *backend_disable_mask_per_asic, - u32 num_shader_engines) -{ - u32 backend_map = 0; - u32 enabled_backends_mask = 0; - u32 enabled_backends_count = 0; - u32 num_backends_per_se; - u32 cur_pipe; - u32 swizzle_pipe[CAYMAN_MAX_PIPES]; - u32 cur_backend = 0; - u32 i; - bool force_no_swizzle; - - /* force legal values */ - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_tile_pipes > rdev->config.cayman.max_tile_pipes) - num_tile_pipes = rdev->config.cayman.max_tile_pipes; - if (num_shader_engines < 1) - num_shader_engines = 1; - if (num_shader_engines > rdev->config.cayman.max_shader_engines) - num_shader_engines = rdev->config.cayman.max_shader_engines; - if (num_backends_per_asic < num_shader_engines) - num_backends_per_asic = num_shader_engines; - if (num_backends_per_asic > (rdev->config.cayman.max_backends_per_se * num_shader_engines)) - num_backends_per_asic = rdev->config.cayman.max_backends_per_se * num_shader_engines; - - /* make sure we have the same number of backends per se */ - num_backends_per_asic = ALIGN(num_backends_per_asic, num_shader_engines); - /* set up the number of backends per se */ - num_backends_per_se = num_backends_per_asic / num_shader_engines; - if (num_backends_per_se > rdev->config.cayman.max_backends_per_se) { - num_backends_per_se = rdev->config.cayman.max_backends_per_se; - num_backends_per_asic = num_backends_per_se * num_shader_engines; - } - - /* create enable mask and count for enabled backends */ - for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { - if (((*backend_disable_mask_per_asic >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends_per_asic) - break; - } - - /* force the backends mask to match the current number of backends */ - if (enabled_backends_count != num_backends_per_asic) { - u32 this_backend_enabled; - u32 shader_engine; - u32 backend_per_se; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - *backend_disable_mask_per_asic = CAYMAN_MAX_BACKENDS_MASK; - for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { - /* calc the current se */ - shader_engine = i / rdev->config.cayman.max_backends_per_se; - /* calc the backend per se */ - backend_per_se = i % rdev->config.cayman.max_backends_per_se; - /* default to not enabled */ - this_backend_enabled = 0; - if ((shader_engine < num_shader_engines) && - (backend_per_se < num_backends_per_se)) - this_backend_enabled = 1; - if (this_backend_enabled) { - enabled_backends_mask |= (1 << i); - *backend_disable_mask_per_asic &= ~(1 << i); - ++enabled_backends_count; - } - } - } - - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * CAYMAN_MAX_PIPES); - switch (rdev->family) { - case CHIP_CAYMAN: - case CHIP_ARUBA: - force_no_swizzle = true; - break; - default: - force_no_swizzle = false; - break; - } - if (force_no_swizzle) { - bool last_backend_enabled = false; - - force_no_swizzle = false; - for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { - if (((enabled_backends_mask >> i) & 1) == 1) { - if (last_backend_enabled) - force_no_swizzle = true; - last_backend_enabled = true; - } else - last_backend_enabled = false; - } - } - - switch (num_tile_pipes) { - case 1: - case 3: - case 5: - case 7: - DRM_ERROR("odd number of pipes!\n"); - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - swizzle_pipe[3] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - } - break; - } - - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % CAYMAN_MAX_BACKENDS; - - backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); - - cur_backend = (cur_backend + 1) % CAYMAN_MAX_BACKENDS; - } - - return backend_map; -} - -static u32 cayman_get_disable_mask_per_asic(struct radeon_device *rdev, - u32 disable_mask_per_se, - u32 max_disable_mask_per_se, - u32 num_shader_engines) -{ - u32 disable_field_width_per_se = r600_count_pipe_bits(disable_mask_per_se); - u32 disable_mask_per_asic = disable_mask_per_se & max_disable_mask_per_se; - - if (num_shader_engines == 1) - return disable_mask_per_asic; - else if (num_shader_engines == 2) - return disable_mask_per_asic | (disable_mask_per_asic << disable_field_width_per_se); - else - return 0xffffffff; -} - static void cayman_gpu_init(struct radeon_device *rdev) { - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_pipe_config; u32 gb_addr_config = 0; u32 mc_shared_chmap, mc_arb_ramcfg; - u32 gb_backend_map; u32 cgts_tcc_disable; u32 sx_debug_1; u32 smx_dc_ctl0; - u32 gc_user_shader_pipe_config; - u32 gc_user_rb_backend_disable; - u32 cgts_user_tcc_disable; u32 cgts_sm_ctrl_reg; u32 hdp_host_path_cntl; u32 tmp; + u32 disabled_rb_mask; int i, j; switch (rdev->family) { @@ -650,6 +452,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) rdev->config.cayman.sc_prim_fifo_size = 0x100; rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_ARUBA: default: @@ -687,6 +490,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) rdev->config.cayman.sc_prim_fifo_size = 0x40; rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN; break; } @@ -706,39 +510,6 @@ static void cayman_gpu_init(struct radeon_device *rdev) mc_shared_chmap = RREG32(MC_SHARED_CHMAP); mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); - cgts_tcc_disable = 0xffff0000; - for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++) - cgts_tcc_disable &= ~(1 << (16 + i)); - gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); - gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); - cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); - - rdev->config.cayman.num_shader_engines = rdev->config.cayman.max_shader_engines; - tmp = ((~gc_user_shader_pipe_config) & INACTIVE_QD_PIPES_MASK) >> INACTIVE_QD_PIPES_SHIFT; - rdev->config.cayman.num_shader_pipes_per_simd = r600_count_pipe_bits(tmp); - rdev->config.cayman.num_tile_pipes = rdev->config.cayman.max_tile_pipes; - tmp = ((~gc_user_shader_pipe_config) & INACTIVE_SIMDS_MASK) >> INACTIVE_SIMDS_SHIFT; - rdev->config.cayman.num_simds_per_se = r600_count_pipe_bits(tmp); - tmp = ((~gc_user_rb_backend_disable) & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.cayman.num_backends_per_se = r600_count_pipe_bits(tmp); - tmp = (gc_user_rb_backend_disable & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.cayman.backend_disable_mask_per_asic = - cayman_get_disable_mask_per_asic(rdev, tmp, CAYMAN_MAX_BACKENDS_PER_SE_MASK, - rdev->config.cayman.num_shader_engines); - rdev->config.cayman.backend_map = - cayman_get_tile_pipe_to_backend_map(rdev, rdev->config.cayman.num_tile_pipes, - rdev->config.cayman.num_backends_per_se * - rdev->config.cayman.num_shader_engines, - &rdev->config.cayman.backend_disable_mask_per_asic, - rdev->config.cayman.num_shader_engines); - tmp = ((~cgts_user_tcc_disable) & TCC_DISABLE_MASK) >> TCC_DISABLE_SHIFT; - rdev->config.cayman.num_texture_channel_caches = r600_count_pipe_bits(tmp); - tmp = (mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT; - rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256; - if (rdev->config.cayman.mem_max_burst_length_bytes > 512) - rdev->config.cayman.mem_max_burst_length_bytes = 512; tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; if (rdev->config.cayman.mem_row_size_in_kb > 4) @@ -748,73 +519,6 @@ static void cayman_gpu_init(struct radeon_device *rdev) rdev->config.cayman.num_gpus = 1; rdev->config.cayman.multi_gpu_tile_size = 64; - //gb_addr_config = 0x02011003 -#if 0 - gb_addr_config = RREG32(GB_ADDR_CONFIG); -#else - gb_addr_config = 0; - switch (rdev->config.cayman.num_tile_pipes) { - case 1: - default: - gb_addr_config |= NUM_PIPES(0); - break; - case 2: - gb_addr_config |= NUM_PIPES(1); - break; - case 4: - gb_addr_config |= NUM_PIPES(2); - break; - case 8: - gb_addr_config |= NUM_PIPES(3); - break; - } - - tmp = (rdev->config.cayman.mem_max_burst_length_bytes / 256) - 1; - gb_addr_config |= PIPE_INTERLEAVE_SIZE(tmp); - gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.cayman.num_shader_engines - 1); - tmp = (rdev->config.cayman.shader_engine_tile_size / 16) - 1; - gb_addr_config |= SHADER_ENGINE_TILE_SIZE(tmp); - switch (rdev->config.cayman.num_gpus) { - case 1: - default: - gb_addr_config |= NUM_GPUS(0); - break; - case 2: - gb_addr_config |= NUM_GPUS(1); - break; - case 4: - gb_addr_config |= NUM_GPUS(2); - break; - } - switch (rdev->config.cayman.multi_gpu_tile_size) { - case 16: - gb_addr_config |= MULTI_GPU_TILE_SIZE(0); - break; - case 32: - default: - gb_addr_config |= MULTI_GPU_TILE_SIZE(1); - break; - case 64: - gb_addr_config |= MULTI_GPU_TILE_SIZE(2); - break; - case 128: - gb_addr_config |= MULTI_GPU_TILE_SIZE(3); - break; - } - switch (rdev->config.cayman.mem_row_size_in_kb) { - case 1: - default: - gb_addr_config |= ROW_SIZE(0); - break; - case 2: - gb_addr_config |= ROW_SIZE(1); - break; - case 4: - gb_addr_config |= ROW_SIZE(2); - break; - } -#endif - tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT; rdev->config.cayman.num_tile_pipes = (1 << tmp); tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; @@ -828,17 +532,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT; rdev->config.cayman.mem_row_size_in_kb = 1 << tmp; - //gb_backend_map = 0x76541032; -#if 0 - gb_backend_map = RREG32(GB_BACKEND_MAP); -#else - gb_backend_map = - cayman_get_tile_pipe_to_backend_map(rdev, rdev->config.cayman.num_tile_pipes, - rdev->config.cayman.num_backends_per_se * - rdev->config.cayman.num_shader_engines, - &rdev->config.cayman.backend_disable_mask_per_asic, - rdev->config.cayman.num_shader_engines); -#endif + /* setup tiling info dword. gb_addr_config is not adequate since it does * not have bank info, so create a custom tiling dword. * bits 3:0 num_pipes @@ -877,25 +571,38 @@ static void cayman_gpu_init(struct radeon_device *rdev) rdev->config.cayman.tile_config |= ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; - rdev->config.cayman.backend_map = gb_backend_map; - WREG32(GB_BACKEND_MAP, gb_backend_map); + tmp = 0; + for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) { + u32 rb_disable_bitmap; + + WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); + WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); + rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16; + tmp <<= 4; + tmp |= rb_disable_bitmap; + } + /* enabled rb are just the one not disabled :) */ + disabled_rb_mask = tmp; + + WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); + WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); + WREG32(GB_ADDR_CONFIG, gb_addr_config); WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); - /* primary versions */ - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); + tmp = gb_addr_config & NUM_PIPES_MASK; + tmp = r6xx_remap_render_backend(rdev, tmp, + rdev->config.cayman.max_backends_per_se * + rdev->config.cayman.max_shader_engines, + CAYMAN_MAX_BACKENDS, disabled_rb_mask); + WREG32(GB_BACKEND_MAP, tmp); + cgts_tcc_disable = 0xffff0000; + for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++) + cgts_tcc_disable &= ~(1 << (16 + i)); WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable); WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable); - - /* user versions */ - WREG32(GC_USER_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable); WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable); diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 2aa7046ada56..a0b98066e207 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -41,6 +41,9 @@ #define CAYMAN_MAX_TCC 16 #define CAYMAN_MAX_TCC_MASK 0xFF +#define CAYMAN_GB_ADDR_CONFIG_GOLDEN 0x02011003 +#define ARUBA_GB_ADDR_CONFIG_GOLDEN 0x12010001 + #define DMIF_ADDR_CONFIG 0xBD4 #define SRBM_GFX_CNTL 0x0E44 #define RINGID(x) (((x) & 0x3) << 0) @@ -148,6 +151,8 @@ #define CGTS_SYS_TCC_DISABLE 0x3F90 #define CGTS_USER_SYS_TCC_DISABLE 0x3F94 +#define RLC_GFX_INDEX 0x3FC4 + #define CONFIG_MEMSIZE 0x5428 #define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 @@ -212,6 +217,12 @@ #define SOFT_RESET_VGT (1 << 14) #define SOFT_RESET_IA (1 << 15) +#define GRBM_GFX_INDEX 0x802C +#define INSTANCE_INDEX(x) ((x) << 0) +#define SE_INDEX(x) ((x) << 16) +#define INSTANCE_BROADCAST_WRITES (1 << 30) +#define SE_BROADCAST_WRITES (1 << 31) + #define SCRATCH_REG0 0x8500 #define SCRATCH_REG1 0x8504 #define SCRATCH_REG2 0x8508 diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f388a1d73b63..45cfcea63507 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1376,113 +1376,51 @@ int r600_asic_reset(struct radeon_device *rdev) return r600_gpu_soft_reset(rdev); } -static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R6XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - - if (num_tile_pipes > R6XX_MAX_PIPES) - num_tile_pipes = R6XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R6XX_MAX_BACKENDS) - num_backends = R6XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - break; - case 4: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - break; - case 5: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - break; - case 6: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - break; - case 7: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - break; - case 8: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - break; +u32 r6xx_remap_render_backend(struct radeon_device *rdev, + u32 tiling_pipe_num, + u32 max_rb_num, + u32 total_max_rb_num, + u32 disabled_rb_mask) +{ + u32 rendering_pipe_num, rb_num_width, req_rb_num; + u32 pipe_rb_ratio, pipe_rb_remain; + u32 data = 0, mask = 1 << (max_rb_num - 1); + unsigned i, j; + + /* mask out the RBs that don't exist on that asic */ + disabled_rb_mask |= (0xff << max_rb_num) & 0xff; + + rendering_pipe_num = 1 << tiling_pipe_num; + req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask); + BUG_ON(rendering_pipe_num < req_rb_num); + + pipe_rb_ratio = rendering_pipe_num / req_rb_num; + pipe_rb_remain = rendering_pipe_num - pipe_rb_ratio * req_rb_num; + + if (rdev->family <= CHIP_RV740) { + /* r6xx/r7xx */ + rb_num_width = 2; + } else { + /* eg+ */ + rb_num_width = 4; } - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; + for (i = 0; i < max_rb_num; i++) { + if (!(mask & disabled_rb_mask)) { + for (j = 0; j < pipe_rb_ratio; j++) { + data <<= rb_num_width; + data |= max_rb_num - i - 1; + } + if (pipe_rb_remain) { + data <<= rb_num_width; + data |= max_rb_num - i - 1; + pipe_rb_remain--; + } + } + mask >>= 1; } - return backend_map; + return data; } int r600_count_pipe_bits(uint32_t val) @@ -1500,7 +1438,6 @@ void r600_gpu_init(struct radeon_device *rdev) { u32 tiling_config; u32 ramcfg; - u32 backend_map; u32 cc_rb_backend_disable; u32 cc_gc_shader_pipe_config; u32 tmp; @@ -1511,8 +1448,9 @@ void r600_gpu_init(struct radeon_device *rdev) u32 sq_thread_resource_mgmt = 0; u32 sq_stack_resource_mgmt_1 = 0; u32 sq_stack_resource_mgmt_2 = 0; + u32 disabled_rb_mask; - /* FIXME: implement */ + rdev->config.r600.tiling_group_size = 256; switch (rdev->family) { case CHIP_R600: rdev->config.r600.max_pipes = 4; @@ -1616,10 +1554,7 @@ void r600_gpu_init(struct radeon_device *rdev) rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); tiling_config |= GROUP_SIZE((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - if ((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) - rdev->config.r600.tiling_group_size = 512; - else - rdev->config.r600.tiling_group_size = 256; + tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; if (tmp > 3) { tiling_config |= ROW_TILING(3); @@ -1631,32 +1566,36 @@ void r600_gpu_init(struct radeon_device *rdev) tiling_config |= BANK_SWAPS(1); cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; - cc_rb_backend_disable |= - BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); - - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; - cc_gc_shader_pipe_config |= - INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); - - backend_map = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, - (R6XX_MAX_BACKENDS - - r600_count_pipe_bits((cc_rb_backend_disable & - R6XX_MAX_BACKENDS_MASK) >> 16)), - (cc_rb_backend_disable >> 16)); + tmp = R6XX_MAX_BACKENDS - + r600_count_pipe_bits((cc_rb_backend_disable >> 16) & R6XX_MAX_BACKENDS_MASK); + if (tmp < rdev->config.r600.max_backends) { + rdev->config.r600.max_backends = tmp; + } + + cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0x00ffff00; + tmp = R6XX_MAX_PIPES - + r600_count_pipe_bits((cc_gc_shader_pipe_config >> 8) & R6XX_MAX_PIPES_MASK); + if (tmp < rdev->config.r600.max_pipes) { + rdev->config.r600.max_pipes = tmp; + } + tmp = R6XX_MAX_SIMDS - + r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R6XX_MAX_SIMDS_MASK); + if (tmp < rdev->config.r600.max_simds) { + rdev->config.r600.max_simds = tmp; + } + + disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R6XX_MAX_BACKENDS_MASK; + tmp = (tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT; + tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.r600.max_backends, + R6XX_MAX_BACKENDS, disabled_rb_mask); + tiling_config |= tmp << 16; + rdev->config.r600.backend_map = tmp; + rdev->config.r600.tile_config = tiling_config; - rdev->config.r600.backend_map = backend_map; - tiling_config |= BACKEND_MAP(backend_map); WREG32(GB_TILING_CONFIG, tiling_config); WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff); - /* Setup pipes */ - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK); diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 15bd3b216243..a0dbf1fe6a40 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -219,6 +219,8 @@ #define BACKEND_MAP(x) ((x) << 16) #define GB_TILING_CONFIG 0x98F0 +#define PIPE_TILING__SHIFT 1 +#define PIPE_TILING__MASK 0x0000000e #define GC_USER_SHADER_PIPE_CONFIG 0x8954 #define INACTIVE_QD_PIPES(x) ((x) << 8) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 492654f8ee74..e25836b72c73 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1845,6 +1845,11 @@ extern struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock); extern void r600_hdmi_enable(struct drm_encoder *encoder); extern void r600_hdmi_disable(struct drm_encoder *encoder); extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); +extern u32 r6xx_remap_render_backend(struct radeon_device *rdev, + u32 tiling_pipe_num, + u32 max_rb_num, + u32 total_max_rb_num, + u32 enabled_rb_mask); /* * evergreen functions used by radeon_encoder.c diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index c12349dba3a2..04ddc365a908 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -365,180 +365,6 @@ void r700_cp_fini(struct radeon_device *rdev) /* * Core functions */ -static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R7XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - bool force_no_swizzle; - - if (num_tile_pipes > R7XX_MAX_PIPES) - num_tile_pipes = R7XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R7XX_MAX_BACKENDS) - num_backends = R7XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - switch (rdev->family) { - case CHIP_RV770: - case CHIP_RV730: - force_no_swizzle = false; - break; - case CHIP_RV710: - case CHIP_RV740: - default: - force_no_swizzle = true; - break; - } - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - } - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 3; - swizzle_pipe[3] = 1; - } - break; - case 5: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - } - break; - case 7: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 7; - swizzle_pipe[7] = 5; - } - break; - } - - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - } - - return backend_map; -} - static void rv770_gpu_init(struct radeon_device *rdev) { int i, j, num_qd_pipes; @@ -554,14 +380,17 @@ static void rv770_gpu_init(struct radeon_device *rdev) u32 sq_thread_resource_mgmt; u32 hdp_host_path_cntl; u32 sq_dyn_gpr_size_simd_ab_0; - u32 backend_map; u32 gb_tiling_config = 0; u32 cc_rb_backend_disable = 0; u32 cc_gc_shader_pipe_config = 0; u32 mc_arb_ramcfg; - u32 db_debug4; + u32 db_debug4, tmp; + u32 inactive_pipes, shader_pipe_config; + u32 disabled_rb_mask; + unsigned active_number; /* setup chip specs */ + rdev->config.rv770.tiling_group_size = 256; switch (rdev->family) { case CHIP_RV770: rdev->config.rv770.max_pipes = 4; @@ -672,23 +501,60 @@ static void rv770_gpu_init(struct radeon_device *rdev) /* setup tiling, simd, pipe config */ mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); + shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); + inactive_pipes = (shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> INACTIVE_QD_PIPES_SHIFT; + for (i = 0, tmp = 1, active_number = 0; i < R7XX_MAX_PIPES; i++) { + if (!(inactive_pipes & tmp)) { + active_number++; + } + tmp <<= 1; + } + if (active_number == 1) { + WREG32(SPI_CONFIG_CNTL, DISABLE_INTERP_1); + } else { + WREG32(SPI_CONFIG_CNTL, 0); + } + + cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; + tmp = R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_rb_backend_disable >> 16); + if (tmp < rdev->config.rv770.max_backends) { + rdev->config.rv770.max_backends = tmp; + } + + cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; + tmp = R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config >> 8) & R7XX_MAX_PIPES_MASK); + if (tmp < rdev->config.rv770.max_pipes) { + rdev->config.rv770.max_pipes = tmp; + } + tmp = R7XX_MAX_SIMDS - r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R7XX_MAX_SIMDS_MASK); + if (tmp < rdev->config.rv770.max_simds) { + rdev->config.rv770.max_simds = tmp; + } + switch (rdev->config.rv770.max_tile_pipes) { case 1: default: - gb_tiling_config |= PIPE_TILING(0); + gb_tiling_config = PIPE_TILING(0); break; case 2: - gb_tiling_config |= PIPE_TILING(1); + gb_tiling_config = PIPE_TILING(1); break; case 4: - gb_tiling_config |= PIPE_TILING(2); + gb_tiling_config = PIPE_TILING(2); break; case 8: - gb_tiling_config |= PIPE_TILING(3); + gb_tiling_config = PIPE_TILING(3); break; } rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes; + disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R7XX_MAX_BACKENDS_MASK; + tmp = (gb_tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT; + tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.rv770.max_backends, + R7XX_MAX_BACKENDS, disabled_rb_mask); + gb_tiling_config |= tmp << 16; + rdev->config.rv770.backend_map = tmp; + if (rdev->family == CHIP_RV770) gb_tiling_config |= BANK_TILING(1); else { @@ -699,10 +565,6 @@ static void rv770_gpu_init(struct radeon_device *rdev) } rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3); gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - if ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) - rdev->config.rv770.tiling_group_size = 512; - else - rdev->config.rv770.tiling_group_size = 256; if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { gb_tiling_config |= ROW_TILING(3); gb_tiling_config |= SAMPLE_SPLIT(3); @@ -714,47 +576,19 @@ static void rv770_gpu_init(struct radeon_device *rdev) } gb_tiling_config |= BANK_SWAPS(1); - - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; - cc_rb_backend_disable |= - BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK); - - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; - cc_gc_shader_pipe_config |= - INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK); - - if (rdev->family == CHIP_RV740) - backend_map = 0x28; - else - backend_map = r700_get_tile_pipe_to_backend_map(rdev, - rdev->config.rv770.max_tile_pipes, - (R7XX_MAX_BACKENDS - - r600_count_pipe_bits((cc_rb_backend_disable & - R7XX_MAX_BACKENDS_MASK) >> 16)), - (cc_rb_backend_disable >> 16)); - rdev->config.rv770.tile_config = gb_tiling_config; - rdev->config.rv770.backend_map = backend_map; - gb_tiling_config |= BACKEND_MAP(backend_map); WREG32(GB_TILING_CONFIG, gb_tiling_config); WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CGTS_SYS_TCC_DISABLE, 0); WREG32(CGTS_TCC_DISABLE, 0); WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); WREG32(CGTS_USER_TCC_DISABLE, 0); - num_qd_pipes = - R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); + + num_qd_pipes = R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK); WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK); @@ -815,8 +649,6 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(VGT_NUM_INSTANCES, 1); - WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0)); - WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); WREG32(CP_PERFMON_CNTL, 0); diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 7addbef54b42..fdc089896011 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -106,10 +106,13 @@ #define BACKEND_MAP(x) ((x) << 16) #define GB_TILING_CONFIG 0x98F0 +#define PIPE_TILING__SHIFT 1 +#define PIPE_TILING__MASK 0x0000000e #define GC_USER_SHADER_PIPE_CONFIG 0x8954 #define INACTIVE_QD_PIPES(x) ((x) << 8) #define INACTIVE_QD_PIPES_MASK 0x0000FF00 +#define INACTIVE_QD_PIPES_SHIFT 8 #define INACTIVE_SIMDS(x) ((x) << 16) #define INACTIVE_SIMDS_MASK 0x00FF0000 -- cgit v1.2.3-55-g7522 From 9b00147d9f2ba137ce74b66b768a8312be0b6781 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 30 May 2012 10:09:30 -0400 Subject: drm/radeon: fix regression in UMS CS ioctl radeon_cs_parser_init is called by both the legacy UMS CS ioctl and the KMS CS ioctl. Protect KMS specific pieces of the code by checking that rdev is not NULL. Reported-by: Michael Burian Signed-off-by: Alex Deucher Reviewed-by: Jerome Glisse Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_cs.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 0137689ed461..142f89462aa4 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -147,6 +147,7 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser *p) sync_to_ring, p->ring); } +/* XXX: note that this is called from the legacy UMS CS ioctl as well */ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) { struct drm_radeon_cs *cs = data; @@ -245,22 +246,24 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) } } - if ((p->cs_flags & RADEON_CS_USE_VM) && - !p->rdev->vm_manager.enabled) { - DRM_ERROR("VM not active on asic!\n"); - return -EINVAL; - } - - /* we only support VM on SI+ */ - if ((p->rdev->family >= CHIP_TAHITI) && - ((p->cs_flags & RADEON_CS_USE_VM) == 0)) { - DRM_ERROR("VM required on SI+!\n"); - return -EINVAL; - } + /* these are KMS only */ + if (p->rdev) { + if ((p->cs_flags & RADEON_CS_USE_VM) && + !p->rdev->vm_manager.enabled) { + DRM_ERROR("VM not active on asic!\n"); + return -EINVAL; + } - if (radeon_cs_get_ring(p, ring, priority)) - return -EINVAL; + /* we only support VM on SI+ */ + if ((p->rdev->family >= CHIP_TAHITI) && + ((p->cs_flags & RADEON_CS_USE_VM) == 0)) { + DRM_ERROR("VM required on SI+!\n"); + return -EINVAL; + } + if (radeon_cs_get_ring(p, ring, priority)) + return -EINVAL; + } /* deal with non-vm */ if ((p->chunk_ib_idx != -1) && -- cgit v1.2.3-55-g7522 From d4e30ef05c9e0fad9782de34f0acd039e238fd43 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 4 Jun 2012 17:18:51 -0400 Subject: drm/radeon: make audio_init consistent across asics Call it in the asic startup callback on all asics. Previously r600 and rv770 called it in the startup and resume callbacks while all the other asics called it in the startup callback. Signed-off-by: Alex Deucher Reviewed-by: Rafał Miłecki Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 15 ++++++--------- drivers/gpu/drm/radeon/rs600.c | 12 ++++++------ drivers/gpu/drm/radeon/rs690.c | 12 ++++++------ drivers/gpu/drm/radeon/rv770.c | 18 ++++++------------ 4 files changed, 24 insertions(+), 33 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 45cfcea63507..f30dc95f83b1 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2426,6 +2426,12 @@ int r600_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) { + DRM_ERROR("radeon: audio init failed\n"); + return r; + } + return 0; } @@ -2462,12 +2468,6 @@ int r600_resume(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); - if (r) { - DRM_ERROR("radeon: audio resume failed\n"); - return r; - } - return r; } @@ -2577,9 +2577,6 @@ int r600_init(struct radeon_device *rdev) rdev->accel_working = false; } - r = r600_audio_init(rdev); - if (r) - return r; /* TODO error handling */ return 0; } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 25f9eef12c42..e95c5e61d4e2 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -908,12 +908,6 @@ static int rs600_startup(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); - return r; - } - r = radeon_ib_pool_start(rdev); if (r) return r; @@ -922,6 +916,12 @@ static int rs600_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + return 0; } diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 3277ddecfe9f..159b6a43fda0 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -637,12 +637,6 @@ static int rs690_startup(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); - return r; - } - r = radeon_ib_pool_start(rdev); if (r) return r; @@ -651,6 +645,12 @@ static int rs690_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + return 0; } diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 04ddc365a908..4ad0281fdc37 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -956,6 +956,12 @@ static int rv770_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) { + DRM_ERROR("radeon: audio init failed\n"); + return r; + } + return 0; } @@ -978,12 +984,6 @@ int rv770_resume(struct radeon_device *rdev) return r; } - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "radeon: audio init failed\n"); - return r; - } - return r; } @@ -1092,12 +1092,6 @@ int rv770_init(struct radeon_device *rdev) rdev->accel_working = false; } - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "radeon: audio init failed\n"); - return r; - } - return 0; } -- cgit v1.2.3-55-g7522 From 0aecb5a4ba1ea4167f31d1790eec027f1e658f2d Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 4 Jun 2012 18:36:58 +0200 Subject: drm/radeon/audio: don't hardcode CRTC id This is based on info released by AMD, should allow using audio in much more cases. Signed-off-by: Rafał Miłecki Reviewed-by: Alex Deucher Cc: Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_audio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 7c4fa77f018f..7479a5c503e4 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -192,6 +192,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); int base_rate = 48000; switch (radeon_encoder->encoder_id) { @@ -217,8 +218,8 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) WREG32(EVERGREEN_AUDIO_PLL1_DIV, clock * 10); WREG32(EVERGREEN_AUDIO_PLL1_UNK, 0x00000071); - /* Some magic trigger or src sel? */ - WREG32_P(0x5ac, 0x01, ~0x77); + /* Select DTO source */ + WREG32(0x5ac, radeon_crtc->crtc_id); } else { switch (dig->dig_encoder) { case 0: -- cgit v1.2.3-55-g7522 From 7838e05a0d29f27f4509290d866e5fc14e642c4c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 4 Jun 2012 20:18:03 +0200 Subject: drm/radeon/hdmi: don't set SEND_MAX_PACKETS bit Many TVs and A/V receivers don't work with this bit set. Problem was confirmed using: Onkyo TX-SR605, Sony BRAVIA KDL-52X3500, Sony BRAVIA KDL-40S40xx. In theory this bit shouldn't affect audio engine when feeding it with data, however it seems it does. Driver fglrx doesn't set that bit in any of the above cases. This fixes a regression introduced by 3.5-rc1. Signed-off-by: Rafał Miłecki Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_hdmi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 226379e00ac1..969c27529dfe 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -348,7 +348,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ - HDMI0_AUDIO_SEND_MAX_PACKETS | /* send NULL packets if no audio is available */ HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ } -- cgit v1.2.3-55-g7522 From 1a8ca7502c22f7a3802f9a207bf80db5439b11c2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 1 Jun 2012 18:58:22 -0400 Subject: drm/radeon: fix gpu_init on si - Properly set up the RBs - Properly set up the SPI - Properly set up gb_addr_config This should fix rendering issues on certain cards. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon.h | 5 +- drivers/gpu/drm/radeon/radeon_kms.c | 2 +- drivers/gpu/drm/radeon/si.c | 477 ++++++++++++------------------------ drivers/gpu/drm/radeon/sid.h | 19 ++ 4 files changed, 184 insertions(+), 319 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 85dac33e3cce..fefcca55c1eb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1374,9 +1374,9 @@ struct cayman_asic { struct si_asic { unsigned max_shader_engines; - unsigned max_pipes_per_simd; unsigned max_tile_pipes; - unsigned max_simds_per_se; + unsigned max_cu_per_sh; + unsigned max_sh_per_se; unsigned max_backends_per_se; unsigned max_texture_channel_caches; unsigned max_gprs; @@ -1387,7 +1387,6 @@ struct si_asic { unsigned sc_hiz_tile_fifo_size; unsigned sc_earlyz_tile_fifo_size; - unsigned num_shader_engines; unsigned num_tile_pipes; unsigned num_backends_per_se; unsigned backend_disable_mask_per_asic; diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index f1016a5820d1..5c58d7d90cb2 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -273,7 +273,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) break; case RADEON_INFO_MAX_PIPES: if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_pipes_per_simd; + value = rdev->config.si.max_cu_per_sh; else if (rdev->family >= CHIP_CAYMAN) value = rdev->config.cayman.max_pipes_per_simd; else if (rdev->family >= CHIP_CEDAR) diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 549732e56ca9..c7b61f16ecfd 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -867,200 +867,6 @@ void dce6_bandwidth_update(struct radeon_device *rdev) /* * Core functions */ -static u32 si_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends_per_asic, - u32 *backend_disable_mask_per_asic, - u32 num_shader_engines) -{ - u32 backend_map = 0; - u32 enabled_backends_mask = 0; - u32 enabled_backends_count = 0; - u32 num_backends_per_se; - u32 cur_pipe; - u32 swizzle_pipe[SI_MAX_PIPES]; - u32 cur_backend = 0; - u32 i; - bool force_no_swizzle; - - /* force legal values */ - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_tile_pipes > rdev->config.si.max_tile_pipes) - num_tile_pipes = rdev->config.si.max_tile_pipes; - if (num_shader_engines < 1) - num_shader_engines = 1; - if (num_shader_engines > rdev->config.si.max_shader_engines) - num_shader_engines = rdev->config.si.max_shader_engines; - if (num_backends_per_asic < num_shader_engines) - num_backends_per_asic = num_shader_engines; - if (num_backends_per_asic > (rdev->config.si.max_backends_per_se * num_shader_engines)) - num_backends_per_asic = rdev->config.si.max_backends_per_se * num_shader_engines; - - /* make sure we have the same number of backends per se */ - num_backends_per_asic = ALIGN(num_backends_per_asic, num_shader_engines); - /* set up the number of backends per se */ - num_backends_per_se = num_backends_per_asic / num_shader_engines; - if (num_backends_per_se > rdev->config.si.max_backends_per_se) { - num_backends_per_se = rdev->config.si.max_backends_per_se; - num_backends_per_asic = num_backends_per_se * num_shader_engines; - } - - /* create enable mask and count for enabled backends */ - for (i = 0; i < SI_MAX_BACKENDS; ++i) { - if (((*backend_disable_mask_per_asic >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends_per_asic) - break; - } - - /* force the backends mask to match the current number of backends */ - if (enabled_backends_count != num_backends_per_asic) { - u32 this_backend_enabled; - u32 shader_engine; - u32 backend_per_se; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - *backend_disable_mask_per_asic = SI_MAX_BACKENDS_MASK; - for (i = 0; i < SI_MAX_BACKENDS; ++i) { - /* calc the current se */ - shader_engine = i / rdev->config.si.max_backends_per_se; - /* calc the backend per se */ - backend_per_se = i % rdev->config.si.max_backends_per_se; - /* default to not enabled */ - this_backend_enabled = 0; - if ((shader_engine < num_shader_engines) && - (backend_per_se < num_backends_per_se)) - this_backend_enabled = 1; - if (this_backend_enabled) { - enabled_backends_mask |= (1 << i); - *backend_disable_mask_per_asic &= ~(1 << i); - ++enabled_backends_count; - } - } - } - - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * SI_MAX_PIPES); - switch (rdev->family) { - case CHIP_TAHITI: - case CHIP_PITCAIRN: - case CHIP_VERDE: - force_no_swizzle = true; - break; - default: - force_no_swizzle = false; - break; - } - if (force_no_swizzle) { - bool last_backend_enabled = false; - - force_no_swizzle = false; - for (i = 0; i < SI_MAX_BACKENDS; ++i) { - if (((enabled_backends_mask >> i) & 1) == 1) { - if (last_backend_enabled) - force_no_swizzle = true; - last_backend_enabled = true; - } else - last_backend_enabled = false; - } - } - - switch (num_tile_pipes) { - case 1: - case 3: - case 5: - case 7: - DRM_ERROR("odd number of pipes!\n"); - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - swizzle_pipe[3] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - } - break; - } - - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS; - - backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); - - cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS; - } - - return backend_map; -} - -static u32 si_get_disable_mask_per_asic(struct radeon_device *rdev, - u32 disable_mask_per_se, - u32 max_disable_mask_per_se, - u32 num_shader_engines) -{ - u32 disable_field_width_per_se = r600_count_pipe_bits(disable_mask_per_se); - u32 disable_mask_per_asic = disable_mask_per_se & max_disable_mask_per_se; - - if (num_shader_engines == 1) - return disable_mask_per_asic; - else if (num_shader_engines == 2) - return disable_mask_per_asic | (disable_mask_per_asic << disable_field_width_per_se); - else - return 0xffffffff; -} - static void si_tiling_mode_table_init(struct radeon_device *rdev) { const u32 num_tile_mode_states = 32; @@ -1562,18 +1368,151 @@ static void si_tiling_mode_table_init(struct radeon_device *rdev) DRM_ERROR("unknown asic: 0x%x\n", rdev->family); } +static void si_select_se_sh(struct radeon_device *rdev, + u32 se_num, u32 sh_num) +{ + u32 data = INSTANCE_BROADCAST_WRITES; + + if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) + data = SH_BROADCAST_WRITES | SE_BROADCAST_WRITES; + else if (se_num == 0xffffffff) + data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num); + else if (sh_num == 0xffffffff) + data |= SH_BROADCAST_WRITES | SE_INDEX(se_num); + else + data |= SH_INDEX(sh_num) | SE_INDEX(se_num); + WREG32(GRBM_GFX_INDEX, data); +} + +static u32 si_create_bitmask(u32 bit_width) +{ + u32 i, mask = 0; + + for (i = 0; i < bit_width; i++) { + mask <<= 1; + mask |= 1; + } + return mask; +} + +static u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh) +{ + u32 data, mask; + + data = RREG32(CC_GC_SHADER_ARRAY_CONFIG); + if (data & 1) + data &= INACTIVE_CUS_MASK; + else + data = 0; + data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG); + + data >>= INACTIVE_CUS_SHIFT; + + mask = si_create_bitmask(cu_per_sh); + + return ~data & mask; +} + +static void si_setup_spi(struct radeon_device *rdev, + u32 se_num, u32 sh_per_se, + u32 cu_per_sh) +{ + int i, j, k; + u32 data, mask, active_cu; + + for (i = 0; i < se_num; i++) { + for (j = 0; j < sh_per_se; j++) { + si_select_se_sh(rdev, i, j); + data = RREG32(SPI_STATIC_THREAD_MGMT_3); + active_cu = si_get_cu_enabled(rdev, cu_per_sh); + + mask = 1; + for (k = 0; k < 16; k++) { + mask <<= k; + if (active_cu & mask) { + data &= ~mask; + WREG32(SPI_STATIC_THREAD_MGMT_3, data); + break; + } + } + } + } + si_select_se_sh(rdev, 0xffffffff, 0xffffffff); +} + +static u32 si_get_rb_disabled(struct radeon_device *rdev, + u32 max_rb_num, u32 se_num, + u32 sh_per_se) +{ + u32 data, mask; + + data = RREG32(CC_RB_BACKEND_DISABLE); + if (data & 1) + data &= BACKEND_DISABLE_MASK; + else + data = 0; + data |= RREG32(GC_USER_RB_BACKEND_DISABLE); + + data >>= BACKEND_DISABLE_SHIFT; + + mask = si_create_bitmask(max_rb_num / se_num / sh_per_se); + + return data & mask; +} + +static void si_setup_rb(struct radeon_device *rdev, + u32 se_num, u32 sh_per_se, + u32 max_rb_num) +{ + int i, j; + u32 data, mask; + u32 disabled_rbs = 0; + u32 enabled_rbs = 0; + + for (i = 0; i < se_num; i++) { + for (j = 0; j < sh_per_se; j++) { + si_select_se_sh(rdev, i, j); + data = si_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); + disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH); + } + } + si_select_se_sh(rdev, 0xffffffff, 0xffffffff); + + mask = 1; + for (i = 0; i < max_rb_num; i++) { + if (!(disabled_rbs & mask)) + enabled_rbs |= mask; + mask <<= 1; + } + + for (i = 0; i < se_num; i++) { + si_select_se_sh(rdev, i, 0xffffffff); + data = 0; + for (j = 0; j < sh_per_se; j++) { + switch (enabled_rbs & 3) { + case 1: + data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2); + break; + case 2: + data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2); + break; + case 3: + default: + data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2); + break; + } + enabled_rbs >>= 2; + } + WREG32(PA_SC_RASTER_CONFIG, data); + } + si_select_se_sh(rdev, 0xffffffff, 0xffffffff); +} + static void si_gpu_init(struct radeon_device *rdev) { - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_array_config; u32 gb_addr_config = 0; u32 mc_shared_chmap, mc_arb_ramcfg; - u32 gb_backend_map; - u32 cgts_tcc_disable; u32 sx_debug_1; - u32 gc_user_shader_array_config; - u32 gc_user_rb_backend_disable; - u32 cgts_user_tcc_disable; u32 hdp_host_path_cntl; u32 tmp; int i, j; @@ -1581,9 +1520,9 @@ static void si_gpu_init(struct radeon_device *rdev) switch (rdev->family) { case CHIP_TAHITI: rdev->config.si.max_shader_engines = 2; - rdev->config.si.max_pipes_per_simd = 4; rdev->config.si.max_tile_pipes = 12; - rdev->config.si.max_simds_per_se = 8; + rdev->config.si.max_cu_per_sh = 8; + rdev->config.si.max_sh_per_se = 2; rdev->config.si.max_backends_per_se = 4; rdev->config.si.max_texture_channel_caches = 12; rdev->config.si.max_gprs = 256; @@ -1594,12 +1533,13 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.sc_prim_fifo_size_backend = 0x100; rdev->config.si.sc_hiz_tile_fifo_size = 0x30; rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_PITCAIRN: rdev->config.si.max_shader_engines = 2; - rdev->config.si.max_pipes_per_simd = 4; rdev->config.si.max_tile_pipes = 8; - rdev->config.si.max_simds_per_se = 5; + rdev->config.si.max_cu_per_sh = 5; + rdev->config.si.max_sh_per_se = 2; rdev->config.si.max_backends_per_se = 4; rdev->config.si.max_texture_channel_caches = 8; rdev->config.si.max_gprs = 256; @@ -1610,13 +1550,14 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.sc_prim_fifo_size_backend = 0x100; rdev->config.si.sc_hiz_tile_fifo_size = 0x30; rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN; break; case CHIP_VERDE: default: rdev->config.si.max_shader_engines = 1; - rdev->config.si.max_pipes_per_simd = 4; rdev->config.si.max_tile_pipes = 4; - rdev->config.si.max_simds_per_se = 2; + rdev->config.si.max_cu_per_sh = 2; + rdev->config.si.max_sh_per_se = 2; rdev->config.si.max_backends_per_se = 4; rdev->config.si.max_texture_channel_caches = 4; rdev->config.si.max_gprs = 256; @@ -1627,6 +1568,7 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.sc_prim_fifo_size_backend = 0x40; rdev->config.si.sc_hiz_tile_fifo_size = 0x30; rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN; break; } @@ -1648,31 +1590,7 @@ static void si_gpu_init(struct radeon_device *rdev) mc_shared_chmap = RREG32(MC_SHARED_CHMAP); mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); - cc_gc_shader_array_config = RREG32(CC_GC_SHADER_ARRAY_CONFIG); - cgts_tcc_disable = 0xffff0000; - for (i = 0; i < rdev->config.si.max_texture_channel_caches; i++) - cgts_tcc_disable &= ~(1 << (16 + i)); - gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); - gc_user_shader_array_config = RREG32(GC_USER_SHADER_ARRAY_CONFIG); - cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); - - rdev->config.si.num_shader_engines = rdev->config.si.max_shader_engines; rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes; - tmp = ((~gc_user_rb_backend_disable) & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.si.num_backends_per_se = r600_count_pipe_bits(tmp); - tmp = (gc_user_rb_backend_disable & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.si.backend_disable_mask_per_asic = - si_get_disable_mask_per_asic(rdev, tmp, SI_MAX_BACKENDS_PER_SE_MASK, - rdev->config.si.num_shader_engines); - rdev->config.si.backend_map = - si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes, - rdev->config.si.num_backends_per_se * - rdev->config.si.num_shader_engines, - &rdev->config.si.backend_disable_mask_per_asic, - rdev->config.si.num_shader_engines); - tmp = ((~cgts_user_tcc_disable) & TCC_DISABLE_MASK) >> TCC_DISABLE_SHIFT; - rdev->config.si.num_texture_channel_caches = r600_count_pipe_bits(tmp); rdev->config.si.mem_max_burst_length_bytes = 256; tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; @@ -1683,55 +1601,8 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.num_gpus = 1; rdev->config.si.multi_gpu_tile_size = 64; - gb_addr_config = 0; - switch (rdev->config.si.num_tile_pipes) { - case 1: - gb_addr_config |= NUM_PIPES(0); - break; - case 2: - gb_addr_config |= NUM_PIPES(1); - break; - case 4: - gb_addr_config |= NUM_PIPES(2); - break; - case 8: - default: - gb_addr_config |= NUM_PIPES(3); - break; - } - - tmp = (rdev->config.si.mem_max_burst_length_bytes / 256) - 1; - gb_addr_config |= PIPE_INTERLEAVE_SIZE(tmp); - gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.si.num_shader_engines - 1); - tmp = (rdev->config.si.shader_engine_tile_size / 16) - 1; - gb_addr_config |= SHADER_ENGINE_TILE_SIZE(tmp); - switch (rdev->config.si.num_gpus) { - case 1: - default: - gb_addr_config |= NUM_GPUS(0); - break; - case 2: - gb_addr_config |= NUM_GPUS(1); - break; - case 4: - gb_addr_config |= NUM_GPUS(2); - break; - } - switch (rdev->config.si.multi_gpu_tile_size) { - case 16: - gb_addr_config |= MULTI_GPU_TILE_SIZE(0); - break; - case 32: - default: - gb_addr_config |= MULTI_GPU_TILE_SIZE(1); - break; - case 64: - gb_addr_config |= MULTI_GPU_TILE_SIZE(2); - break; - case 128: - gb_addr_config |= MULTI_GPU_TILE_SIZE(3); - break; - } + /* fix up row size */ + gb_addr_config &= ~ROW_SIZE_MASK; switch (rdev->config.si.mem_row_size_in_kb) { case 1: default: @@ -1745,26 +1616,6 @@ static void si_gpu_init(struct radeon_device *rdev) break; } - tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT; - rdev->config.si.num_tile_pipes = (1 << tmp); - tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; - rdev->config.si.mem_max_burst_length_bytes = (tmp + 1) * 256; - tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT; - rdev->config.si.num_shader_engines = tmp + 1; - tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT; - rdev->config.si.num_gpus = tmp + 1; - tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT; - rdev->config.si.multi_gpu_tile_size = 1 << tmp; - tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT; - rdev->config.si.mem_row_size_in_kb = 1 << tmp; - - gb_backend_map = - si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes, - rdev->config.si.num_backends_per_se * - rdev->config.si.num_shader_engines, - &rdev->config.si.backend_disable_mask_per_asic, - rdev->config.si.num_shader_engines); - /* setup tiling info dword. gb_addr_config is not adequate since it does * not have bank info, so create a custom tiling dword. * bits 3:0 num_pipes @@ -1789,33 +1640,29 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.tile_config |= (3 << 0); break; } - rdev->config.si.tile_config |= - ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; + if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + rdev->config.si.tile_config |= 1 << 4; + else + rdev->config.si.tile_config |= 0 << 4; rdev->config.si.tile_config |= ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; rdev->config.si.tile_config |= ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; - rdev->config.si.backend_map = gb_backend_map; WREG32(GB_ADDR_CONFIG, gb_addr_config); WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); - /* primary versions */ - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config); - - WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable); + si_tiling_mode_table_init(rdev); - /* user versions */ - WREG32(GC_USER_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config); + si_setup_rb(rdev, rdev->config.si.max_shader_engines, + rdev->config.si.max_sh_per_se, + rdev->config.si.max_backends_per_se); - WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable); + si_setup_spi(rdev, rdev->config.si.max_shader_engines, + rdev->config.si.max_sh_per_se, + rdev->config.si.max_cu_per_sh); - si_tiling_mode_table_init(rdev); /* set HW defaults for 3D engine */ WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 53ea2c42dbd6..db4067962868 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -24,6 +24,11 @@ #ifndef SI_H #define SI_H +#define TAHITI_RB_BITMAP_WIDTH_PER_SH 2 + +#define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003 +#define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002 + #define CG_MULT_THERMAL_STATUS 0x714 #define ASIC_MAX_TEMP(x) ((x) << 0) #define ASIC_MAX_TEMP_MASK 0x000001ff @@ -408,6 +413,12 @@ #define SOFT_RESET_IA (1 << 15) #define GRBM_GFX_INDEX 0x802C +#define INSTANCE_INDEX(x) ((x) << 0) +#define SH_INDEX(x) ((x) << 8) +#define SE_INDEX(x) ((x) << 16) +#define SH_BROADCAST_WRITES (1 << 29) +#define INSTANCE_BROADCAST_WRITES (1 << 30) +#define SE_BROADCAST_WRITES (1 << 31) #define GRBM_INT_CNTL 0x8060 # define RDERR_INT_ENABLE (1 << 0) @@ -480,6 +491,8 @@ #define VGT_TF_MEMORY_BASE 0x89B8 #define CC_GC_SHADER_ARRAY_CONFIG 0x89bc +#define INACTIVE_CUS_MASK 0xFFFF0000 +#define INACTIVE_CUS_SHIFT 16 #define GC_USER_SHADER_ARRAY_CONFIG 0x89c0 #define PA_CL_ENHANCE 0x8A14 @@ -688,6 +701,12 @@ #define RLC_MC_CNTL 0xC344 #define RLC_UCODE_CNTL 0xC348 +#define PA_SC_RASTER_CONFIG 0x28350 +# define RASTER_CONFIG_RB_MAP_0 0 +# define RASTER_CONFIG_RB_MAP_1 1 +# define RASTER_CONFIG_RB_MAP_2 2 +# define RASTER_CONFIG_RB_MAP_3 3 + #define VGT_EVENT_INITIATOR 0x28a90 # define SAMPLE_STREAMOUTSTATS1 (1 << 0) # define SAMPLE_STREAMOUTSTATS2 (2 << 0) -- cgit v1.2.3-55-g7522 From bb4091558228ff4a3e02328c931e683fc7f08722 Mon Sep 17 00:00:00 2001 From: Christian König Date: Sun, 3 Jun 2012 16:09:43 +0200 Subject: drm/radeon: fix vm deadlocks on cayman Locking mutex in different orders just screams for deadlocks, and some testing showed that it is actually quite easy to trigger them. Signed-off-by: Christian König Reviewed-by: Jerome Glisse Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_gart.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 79db56e6c2ac..59d44937dd9f 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -476,12 +476,18 @@ int radeon_vm_bo_add(struct radeon_device *rdev, mutex_lock(&vm->mutex); if (last_pfn > vm->last_pfn) { - /* grow va space 32M by 32M */ - unsigned align = ((32 << 20) >> 12) - 1; + /* release mutex and lock in right order */ + mutex_unlock(&vm->mutex); radeon_mutex_lock(&rdev->cs_mutex); - radeon_vm_unbind_locked(rdev, vm); + mutex_lock(&vm->mutex); + /* and check again */ + if (last_pfn > vm->last_pfn) { + /* grow va space 32M by 32M */ + unsigned align = ((32 << 20) >> 12) - 1; + radeon_vm_unbind_locked(rdev, vm); + vm->last_pfn = (last_pfn + align) & ~align; + } radeon_mutex_unlock(&rdev->cs_mutex); - vm->last_pfn = (last_pfn + align) & ~align; } head = &vm->va; last_offset = 0; @@ -595,8 +601,8 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, if (bo_va == NULL) return 0; - mutex_lock(&vm->mutex); radeon_mutex_lock(&rdev->cs_mutex); + mutex_lock(&vm->mutex); radeon_vm_bo_update_pte(rdev, vm, bo, NULL); radeon_mutex_unlock(&rdev->cs_mutex); list_del(&bo_va->vm_list); @@ -641,9 +647,8 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) struct radeon_bo_va *bo_va, *tmp; int r; - mutex_lock(&vm->mutex); - radeon_mutex_lock(&rdev->cs_mutex); + mutex_lock(&vm->mutex); radeon_vm_unbind_locked(rdev, vm); radeon_mutex_unlock(&rdev->cs_mutex); -- cgit v1.2.3-55-g7522 From d430f7dbf7bd6aaaa40c0660b3204df8cf07b22b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 5 Jun 2012 09:50:28 -0400 Subject: drm/radeon/kms: add new Trinity PCI ids Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/ni.c | 21 +++++++++++++++++---- include/drm/drm_pciids.h | 8 ++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 3df4efa11942..3186522a4458 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -460,15 +460,28 @@ static void cayman_gpu_init(struct radeon_device *rdev) rdev->config.cayman.max_pipes_per_simd = 4; rdev->config.cayman.max_tile_pipes = 2; if ((rdev->pdev->device == 0x9900) || - (rdev->pdev->device == 0x9901)) { + (rdev->pdev->device == 0x9901) || + (rdev->pdev->device == 0x9905) || + (rdev->pdev->device == 0x9906) || + (rdev->pdev->device == 0x9907) || + (rdev->pdev->device == 0x9908) || + (rdev->pdev->device == 0x9909) || + (rdev->pdev->device == 0x9910) || + (rdev->pdev->device == 0x9917)) { rdev->config.cayman.max_simds_per_se = 6; rdev->config.cayman.max_backends_per_se = 2; } else if ((rdev->pdev->device == 0x9903) || - (rdev->pdev->device == 0x9904)) { + (rdev->pdev->device == 0x9904) || + (rdev->pdev->device == 0x990A) || + (rdev->pdev->device == 0x9913) || + (rdev->pdev->device == 0x9918)) { rdev->config.cayman.max_simds_per_se = 4; rdev->config.cayman.max_backends_per_se = 2; - } else if ((rdev->pdev->device == 0x9990) || - (rdev->pdev->device == 0x9991)) { + } else if ((rdev->pdev->device == 0x9919) || + (rdev->pdev->device == 0x9990) || + (rdev->pdev->device == 0x9991) || + (rdev->pdev->device == 0x9994) || + (rdev->pdev->device == 0x99A0)) { rdev->config.cayman.max_simds_per_se = 3; rdev->config.cayman.max_backends_per_se = 1; } else { diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 58d0bdab68dd..961dae0d26e1 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -561,11 +561,19 @@ {0x1002, 0x9909, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x990A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x990F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9910, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9913, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9917, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9918, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9990, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9991, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9993, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9994, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x99A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x99A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x99A4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \ -- cgit v1.2.3-55-g7522 From d26098759cf6d32148649c165f87a7590bc25b89 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sat, 9 Jun 2012 10:57:41 -0400 Subject: drm/radeon: fix tiling and command stream checking on evergreen v3 Fix regresson since the introduction of command stream checking on evergreen (thread referenced below). Issue is cause by ddx allocating bo with formula width*height*bpp while programming the GPU command stream with ALIGN(height, 8). In some case (where page alignment does not hide the extra size bo should be according to height alignment) the kernel will reject the command stream. This patch reprogram the command stream to slice - 1 (slice is a derivative value from height) which avoid rejecting the command stream while keeping the value of command stream checking from a security point of view. This patch also fix wrong computation of layer size for 2D tiled surface. Which should fix issue when 2D color tiling is enabled. This dump the radeon KMS_DRIVER_MINOR so userspace can know if they are on a fixed kernel or not. https://lkml.org/lkml/2012/6/3/80 https://bugs.freedesktop.org/show_bug.cgi?id=50892 https://bugs.freedesktop.org/show_bug.cgi?id=50857 !!! STABLE need a custom version of this patch for 3.4 !!! v2: actually bump the minor version and add comment about stable v3: do compute the height the ddx was trying to use [airlied: drop left over debug] Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_cs.c | 49 ++++++++++++++++++++++++++++++++--- drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- 2 files changed, 47 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 4e7dd2b4843d..c16554122ccd 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -52,6 +52,7 @@ struct evergreen_cs_track { u32 cb_color_view[12]; u32 cb_color_pitch[12]; u32 cb_color_slice[12]; + u32 cb_color_slice_idx[12]; u32 cb_color_attrib[12]; u32 cb_color_cmask_slice[8];/* unused */ u32 cb_color_fmask_slice[8];/* unused */ @@ -127,12 +128,14 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track) track->cb_color_info[i] = 0; track->cb_color_view[i] = 0xFFFFFFFF; track->cb_color_pitch[i] = 0; - track->cb_color_slice[i] = 0; + track->cb_color_slice[i] = 0xfffffff; + track->cb_color_slice_idx[i] = 0; } track->cb_target_mask = 0xFFFFFFFF; track->cb_shader_mask = 0xFFFFFFFF; track->cb_dirty = true; + track->db_depth_slice = 0xffffffff; track->db_depth_view = 0xFFFFC000; track->db_depth_size = 0xFFFFFFFF; track->db_depth_control = 0xFFFFFFFF; @@ -250,10 +253,9 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, { struct evergreen_cs_track *track = p->track; unsigned palign, halign, tileb, slice_pt; + unsigned mtile_pr, mtile_ps, mtileb; tileb = 64 * surf->bpe * surf->nsamples; - palign = track->group_size / (8 * surf->bpe * surf->nsamples); - palign = MAX(8, palign); slice_pt = 1; if (tileb > surf->tsplit) { slice_pt = tileb / surf->tsplit; @@ -262,7 +264,10 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, /* macro tile width & height */ palign = (8 * surf->bankw * track->npipes) * surf->mtilea; halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; - surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt; + mtileb = (palign / 8) * (halign / 8) * tileb;; + mtile_pr = surf->nbx / palign; + mtile_ps = (mtile_pr * surf->nby) / halign; + surf->layer_size = mtile_ps * mtileb * slice_pt; surf->base_align = (palign / 8) * (halign / 8) * tileb; surf->palign = palign; surf->halign = halign; @@ -434,6 +439,39 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i offset += surf.layer_size * mslice; if (offset > radeon_bo_size(track->cb_color_bo[id])) { + /* old ddx are broken they allocate bo with w*h*bpp but + * program slice with ALIGN(h, 8), catch this and patch + * command stream. + */ + if (!surf.mode) { + volatile u32 *ib = p->ib.ptr; + unsigned long tmp, nby, bsize, size, min = 0; + + /* find the height the ddx wants */ + if (surf.nby > 8) { + min = surf.nby - 8; + } + bsize = radeon_bo_size(track->cb_color_bo[id]); + tmp = track->cb_color_bo_offset[id] << 8; + for (nby = surf.nby; nby > min; nby--) { + size = nby * surf.nbx * surf.bpe * surf.nsamples; + if ((tmp + size * mslice) <= bsize) { + break; + } + } + if (nby > min) { + surf.nby = nby; + slice = ((nby * surf.nbx) / 64) - 1; + if (!evergreen_surface_check(p, &surf, "cb")) { + /* check if this one works */ + tmp += surf.layer_size * mslice; + if (tmp <= bsize) { + ib[track->cb_color_slice_idx[id]] = slice; + goto old_ddx_ok; + } + } + } + } dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " "offset %d, max layer %d, bo size %ld, slice %d)\n", __func__, __LINE__, id, surf.layer_size, @@ -446,6 +484,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i surf.tsplit, surf.mtilea); return -EINVAL; } +old_ddx_ok: return 0; } @@ -1532,6 +1571,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR7_SLICE: tmp = (reg - CB_COLOR0_SLICE) / 0x3c; track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_slice_idx[tmp] = idx; track->cb_dirty = true; break; case CB_COLOR8_SLICE: @@ -1540,6 +1580,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR11_SLICE: tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8; track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_slice_idx[tmp] = idx; track->cb_dirty = true; break; case CB_COLOR0_ATTRIB: diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index f0bb2b543b13..03e5f5df40f1 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -57,9 +57,10 @@ * 2.13.0 - virtual memory support, streamout * 2.14.0 - add evergreen tiling informations * 2.15.0 - add max_pipes query + * 2.16.0 - fix evergreen 2D tiled surface calculation */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 15 +#define KMS_DRIVER_MINOR 16 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- cgit v1.2.3-55-g7522 From 0ec0612a80f957000999c3f7b31a84e3558c719d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 15:54:57 -0400 Subject: drm/radeon: fix regression in dynpm due to multi-ring rework Not all asics have all rings, so make sure the ring is ready before attempting to check it in the dynpm work handler. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=43367 Signed-off-by: Alex Deucher Reviewed-by: Jerome Glisse Reviewed-by: Christian König Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_pm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 08825548ee69..5b37e283ec38 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -801,9 +801,13 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) int i; for (i = 0; i < RADEON_NUM_RINGS; ++i) { - not_processed += radeon_fence_count_emitted(rdev, i); - if (not_processed >= 3) - break; + struct radeon_ring *ring = &rdev->ring[i]; + + if (ring->ready) { + not_processed += radeon_fence_count_emitted(rdev, i); + if (not_processed >= 3) + break; + } } if (not_processed >= 3) { /* should upclock */ -- cgit v1.2.3-55-g7522 From 489797d510dfbce15120492d7ef6f956928b99f2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 12 Jun 2012 16:10:39 +0100 Subject: drm/radeon/prime: reserve/unreserve around pin I finally got to test this code a bit more and hit the ttm no reserved assert, so add the reservations around the pinning. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_prime.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index 8ddab4c76710..6bef46ace831 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c @@ -169,11 +169,17 @@ struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, struct radeon_bo *bo = gem_to_radeon_bo(obj); int ret = 0; + ret = radeon_bo_reserve(bo, false); + if (unlikely(ret != 0)) + return ERR_PTR(ret); + /* pin buffer into GTT */ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); - if (ret) + if (ret) { + radeon_bo_unreserve(bo); return ERR_PTR(ret); - + } + radeon_bo_unreserve(bo); return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags); } -- cgit v1.2.3-55-g7522 From 6b53a0507b6e728c53f2fc60912a8511f151e5d8 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 11 Jun 2012 12:34:01 +0200 Subject: drm/radeon: enable HDMI on DCE5 (AKA NI excluding Aruba) After recent changes HDMI code is ready to be enabled on DCE5. This patch just changes conditions to execute already present code on DCE5. Signed-off-by: Rafał Miłecki Reviewed-by: Alex Deucher Tested-by: Christian König Tested-by: Andre Heider Tested-by: Zoltán Böszörményi Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_encoders.c | 4 +++- drivers/gpu/drm/radeon/evergreen_hdmi.c | 3 --- drivers/gpu/drm/radeon/ni.c | 5 +++++ drivers/gpu/drm/radeon/r600_audio.c | 2 +- drivers/gpu/drm/radeon/r600_hdmi.c | 7 ++----- 5 files changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index e7b1ec5ae8c6..486ccdf4aacd 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1926,7 +1926,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { r600_hdmi_enable(encoder); - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE6(rdev)) + ; /* TODO (use pointers instead of if-s?) */ + else if (ASIC_IS_DCE4(rdev)) evergreen_hdmi_setmode(encoder, adjusted_mode); else r600_hdmi_setmode(encoder, adjusted_mode); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index a51f880985f8..65c54160028b 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -156,9 +156,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 3186522a4458..b7bf18e40215 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1303,6 +1303,10 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) + return r; + return 0; } @@ -1329,6 +1333,7 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 7479a5c503e4..79b55916cf90 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -57,7 +57,7 @@ static bool radeon_dig_encoder(struct drm_encoder *encoder) */ static int r600_audio_chipset_supported(struct radeon_device *rdev) { - return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev)) + return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE6(rdev)) || rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740; diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 969c27529dfe..82a0a4c919c0 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -322,9 +322,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; @@ -483,7 +480,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) uint32_t offset; u32 hdmi; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Silent, r600_hdmi_enable will raise WARN for us */ @@ -543,7 +540,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Called for ATOM_ENCODER_MODE_HDMI only */ -- cgit v1.2.3-55-g7522 From b866d1334ba2d544bc575d75357dea6bdcdc7f46 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 22:06:36 +0200 Subject: drm/radeon: add some additional 6xx/7xx/EG register init - SMX_SAR_CTL0 needs to be programmed correctly to prevent problems with memory exports in certain cases. - VC_ENHANCE needs to be initialized on 6xx/7xx. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 3 +++ drivers/gpu/drm/radeon/evergreend.h | 1 + drivers/gpu/drm/radeon/r600.c | 1 + drivers/gpu/drm/radeon/r600d.h | 1 + drivers/gpu/drm/radeon/rv770.c | 5 ++++- drivers/gpu/drm/radeon/rv770d.h | 3 +++ 6 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 01550d05e273..7fb3d2e0434c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1932,6 +1932,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); WREG32(SMX_DC_CTL0, smx_dc_ctl0); + if (rdev->family <= CHIP_SUMO2) + WREG32(SMX_SAR_CTL0, 0x00010000); + WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 2773039b4902..b50b15c70498 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -503,6 +503,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define NUMBER_OF_SETS(x) ((x) << 1) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f30dc95f83b1..bff627293812 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1839,6 +1839,7 @@ void r600_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); + WREG32(VC_ENHANCE, 0); } diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index a0dbf1fe6a40..c6857e8d76f2 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -485,6 +485,7 @@ #define TC_L2_SIZE(x) ((x)<<5) #define L2_DISABLE_LATE_HIT (1<<9) +#define VC_ENHANCE 0x9714 #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4ad0281fdc37..b4f51c569c36 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -616,6 +616,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) ACK_FLUSH_CTL(3) | SYNC_FLUSH_CTL)); + if (rdev->family != CHIP_RV770) + WREG32(SMX_SAR_CTL0, 0x00003f3f); + db_debug3 = RREG32(DB_DEBUG3); db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f); switch (rdev->family) { @@ -792,7 +795,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); - + WREG32(VC_ENHANCE, 0); } void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index fdc089896011..b0adfc595d75 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -211,6 +211,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define CACHE_DEPTH(x) ((x) << 1) @@ -310,6 +311,8 @@ #define TCP_CNTL 0x9610 #define TCP_CHAN_STEER 0x9614 +#define VC_ENHANCE 0x9714 + #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) #define VC_ONLY 0 -- cgit v1.2.3-55-g7522 From 7c77bf2a1a8bf67d580a3b189b37fded0a13ab78 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 22:06:37 +0200 Subject: drm/radeon: add support for STRMOUT_BASE_UPDATE on 7xx Required for streamout. Bump drm minor. Marek v2: fix pkt->count check Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 42 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/r600d.h | 1 + drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- 3 files changed, 45 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0133f5f09bd6..ca87f7afaf23 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -2079,6 +2079,48 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } break; + case PACKET3_STRMOUT_BASE_UPDATE: + if (p->family < CHIP_RV770) { + DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); + return -EINVAL; + } + if (pkt->count != 1) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n"); + return -EINVAL; + } + if (idx_value > 3) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n"); + return -EINVAL; + } + { + u64 offset; + + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n"); + return -EINVAL; + } + + if (reloc->robj != track->vgt_strmout_bo[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n"); + return -EINVAL; + } + + offset = radeon_get_ib_value(p, idx+1) << 8; + if (offset != track->vgt_strmout_bo_offset[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n", + offset, track->vgt_strmout_bo_offset[idx_value]); + return -EINVAL; + } + + if ((offset + 4) > radeon_bo_size(reloc->robj)) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%llx, 0x%lx\n", + offset + 4, radeon_bo_size(reloc->robj)); + return -EINVAL; + } + ib[idx+1] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + } + break; case PACKET3_SURFACE_BASE_UPDATE: if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index c6857e8d76f2..025fd5b6c08c 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -1164,6 +1164,7 @@ #define PACKET3_SET_CTL_CONST 0x6F #define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 #define PACKET3_SET_CTL_CONST_END 0x0003e200 +#define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */ #define PACKET3_SURFACE_BASE_UPDATE 0x73 diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 03e5f5df40f1..2c4d53fd20c5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -58,9 +58,10 @@ * 2.14.0 - add evergreen tiling informations * 2.15.0 - add max_pipes query * 2.16.0 - fix evergreen 2D tiled surface calculation + * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 16 +#define KMS_DRIVER_MINOR 17 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- cgit v1.2.3-55-g7522 From b7019b2f31fe7bec9f6f5dc1bf54cb0e0d73e047 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 14 Jun 2012 15:58:25 -0400 Subject: drm/radeon: SI tiling fixes for display - Use the correct union for getting the tiling info - Properly init the PIPE_CONFIG field for SI Signed-off-by: Alex Deucher Reviewed-by: Michel Dänzer Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 10 ++++- drivers/gpu/drm/radeon/si_reg.h | 72 ++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 01d77d1554f4..3904d7964a4b 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1149,7 +1149,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } if (tiling_flags & RADEON_TILING_MACRO) { - if (rdev->family >= CHIP_CAYMAN) + if (rdev->family >= CHIP_TAHITI) + tmp = rdev->config.si.tile_config; + else if (rdev->family >= CHIP_CAYMAN) tmp = rdev->config.cayman.tile_config; else tmp = rdev->config.evergreen.tile_config; @@ -1177,6 +1179,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } else if (tiling_flags & RADEON_TILING_MICRO) fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); + if ((rdev->family == CHIP_TAHITI) || + (rdev->family == CHIP_PITCAIRN)) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); + else if (rdev->family == CHIP_VERDE) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); + switch (radeon_crtc->crtc_id) { case 0: WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/drivers/gpu/drm/radeon/si_reg.h b/drivers/gpu/drm/radeon/si_reg.h index eda938a7cb6e..501f9d431d57 100644 --- a/drivers/gpu/drm/radeon/si_reg.h +++ b/drivers/gpu/drm/radeon/si_reg.h @@ -30,4 +30,76 @@ #define SI_DC_GPIO_HPD_EN 0x65b8 #define SI_DC_GPIO_HPD_Y 0x65bc +#define SI_GRPH_CONTROL 0x6804 +# define SI_GRPH_DEPTH(x) (((x) & 0x3) << 0) +# define SI_GRPH_DEPTH_8BPP 0 +# define SI_GRPH_DEPTH_16BPP 1 +# define SI_GRPH_DEPTH_32BPP 2 +# define SI_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) +# define SI_ADDR_SURF_2_BANK 0 +# define SI_ADDR_SURF_4_BANK 1 +# define SI_ADDR_SURF_8_BANK 2 +# define SI_ADDR_SURF_16_BANK 3 +# define SI_GRPH_Z(x) (((x) & 0x3) << 4) +# define SI_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) +# define SI_ADDR_SURF_BANK_WIDTH_1 0 +# define SI_ADDR_SURF_BANK_WIDTH_2 1 +# define SI_ADDR_SURF_BANK_WIDTH_4 2 +# define SI_ADDR_SURF_BANK_WIDTH_8 3 +# define SI_GRPH_FORMAT(x) (((x) & 0x7) << 8) +/* 8 BPP */ +# define SI_GRPH_FORMAT_INDEXED 0 +/* 16 BPP */ +# define SI_GRPH_FORMAT_ARGB1555 0 +# define SI_GRPH_FORMAT_ARGB565 1 +# define SI_GRPH_FORMAT_ARGB4444 2 +# define SI_GRPH_FORMAT_AI88 3 +# define SI_GRPH_FORMAT_MONO16 4 +# define SI_GRPH_FORMAT_BGRA5551 5 +/* 32 BPP */ +# define SI_GRPH_FORMAT_ARGB8888 0 +# define SI_GRPH_FORMAT_ARGB2101010 1 +# define SI_GRPH_FORMAT_32BPP_DIG 2 +# define SI_GRPH_FORMAT_8B_ARGB2101010 3 +# define SI_GRPH_FORMAT_BGRA1010102 4 +# define SI_GRPH_FORMAT_8B_BGRA1010102 5 +# define SI_GRPH_FORMAT_RGB111110 6 +# define SI_GRPH_FORMAT_BGR101111 7 +# define SI_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) +# define SI_ADDR_SURF_BANK_HEIGHT_1 0 +# define SI_ADDR_SURF_BANK_HEIGHT_2 1 +# define SI_ADDR_SURF_BANK_HEIGHT_4 2 +# define SI_ADDR_SURF_BANK_HEIGHT_8 3 +# define SI_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) +# define SI_ADDR_SURF_TILE_SPLIT_64B 0 +# define SI_ADDR_SURF_TILE_SPLIT_128B 1 +# define SI_ADDR_SURF_TILE_SPLIT_256B 2 +# define SI_ADDR_SURF_TILE_SPLIT_512B 3 +# define SI_ADDR_SURF_TILE_SPLIT_1KB 4 +# define SI_ADDR_SURF_TILE_SPLIT_2KB 5 +# define SI_ADDR_SURF_TILE_SPLIT_4KB 6 +# define SI_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_1 0 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_2 1 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_4 2 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_8 3 +# define SI_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) +# define SI_GRPH_ARRAY_LINEAR_GENERAL 0 +# define SI_GRPH_ARRAY_LINEAR_ALIGNED 1 +# define SI_GRPH_ARRAY_1D_TILED_THIN1 2 +# define SI_GRPH_ARRAY_2D_TILED_THIN1 4 +# define SI_GRPH_PIPE_CONFIG(x) (((x) & 0x1f) << 24) +# define SI_ADDR_SURF_P2 0 +# define SI_ADDR_SURF_P4_8x16 4 +# define SI_ADDR_SURF_P4_16x16 5 +# define SI_ADDR_SURF_P4_16x32 6 +# define SI_ADDR_SURF_P4_32x32 7 +# define SI_ADDR_SURF_P8_16x16_8x16 8 +# define SI_ADDR_SURF_P8_16x32_8x16 9 +# define SI_ADDR_SURF_P8_32x32_8x16 10 +# define SI_ADDR_SURF_P8_16x32_16x16 11 +# define SI_ADDR_SURF_P8_32x32_16x16 12 +# define SI_ADDR_SURF_P8_32x32_16x32 13 +# define SI_ADDR_SURF_P8_32x64_32x32 14 + #endif -- cgit v1.2.3-55-g7522