diff options
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 93 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 13 |
2 files changed, 103 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 1f088800295d..582f8e4f36d4 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -5622,7 +5622,7 @@ static void cik_init_gfx_cgpg(struct radeon_device *rdev) if (rdev->rlc.cs_data) { WREG32(RLC_GPM_SCRATCH_ADDR, RLC_CLEAR_STATE_DESCRIPTOR_OFFSET); WREG32(RLC_GPM_SCRATCH_DATA, upper_32_bits(rdev->rlc.clear_state_gpu_addr)); - WREG32(RLC_GPM_SCRATCH_DATA, rdev->rlc.clear_state_gpu_addr); + WREG32(RLC_GPM_SCRATCH_DATA, lower_32_bits(rdev->rlc.clear_state_gpu_addr)); WREG32(RLC_GPM_SCRATCH_DATA, rdev->rlc.clear_state_size); } else { WREG32(RLC_GPM_SCRATCH_ADDR, RLC_CLEAR_STATE_DESCRIPTOR_OFFSET); @@ -5670,6 +5670,97 @@ static void cik_update_gfx_pg(struct radeon_device *rdev, bool enable) cik_enable_gfx_dynamic_mgpg(rdev, enable); } +u32 cik_get_csb_size(struct radeon_device *rdev) +{ + u32 count = 0; + const struct cs_section_def *sect = NULL; + const struct cs_extent_def *ext = NULL; + + if (rdev->rlc.cs_data == NULL) + return 0; + + /* begin clear state */ + count += 2; + /* context control state */ + count += 3; + + for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { + for (ext = sect->section; ext->extent != NULL; ++ext) { + if (sect->id == SECT_CONTEXT) + count += 2 + ext->reg_count; + else + return 0; + } + } + /* pa_sc_raster_config/pa_sc_raster_config1 */ + count += 4; + /* end clear state */ + count += 2; + /* clear state */ + count += 2; + + return count; +} + +void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) +{ + u32 count = 0, i; + const struct cs_section_def *sect = NULL; + const struct cs_extent_def *ext = NULL; + + if (rdev->rlc.cs_data == NULL) + return; + if (buffer == NULL) + return; + + buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); + buffer[count++] = PACKET3_PREAMBLE_BEGIN_CLEAR_STATE; + + buffer[count++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1); + buffer[count++] = 0x80000000; + buffer[count++] = 0x80000000; + + for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { + for (ext = sect->section; ext->extent != NULL; ++ext) { + if (sect->id == SECT_CONTEXT) { + buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count); + buffer[count++] = ext->reg_index - 0xa000; + for (i = 0; i < ext->reg_count; i++) + buffer[count++] = ext->extent[i]; + } else { + return; + } + } + } + + buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); + buffer[count++] = PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START; + switch (rdev->family) { + case CHIP_BONAIRE: + buffer[count++] = 0x16000012; + buffer[count++] = 0x00000000; + break; + case CHIP_KAVERI: + buffer[count++] = 0x00000000; /* XXX */ + buffer[count++] = 0x00000000; + break; + case CHIP_KABINI: + buffer[count++] = 0x00000000; /* XXX */ + buffer[count++] = 0x00000000; + break; + default: + buffer[count++] = 0x00000000; + buffer[count++] = 0x00000000; + break; + } + + buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); + buffer[count++] = PACKET3_PREAMBLE_END_CLEAR_STATE; + + buffer[count++] = PACKET3(PACKET3_CLEAR_STATE, 0); + buffer[count++] = 0; +} + static void cik_init_pg(struct radeon_device *rdev) { if (rdev->pg_flags) { diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 536908109001..2ca9f13f2c79 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -144,6 +144,8 @@ void cik_init_cp_pg_table(struct radeon_device *rdev); extern u32 si_get_csb_size(struct radeon_device *rdev); extern void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer); +extern u32 cik_get_csb_size(struct radeon_device *rdev); +extern void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer); static const u32 evergreen_golden_registers[] = { @@ -3903,6 +3905,9 @@ int sumo_rlc_init(struct radeon_device *rdev) src_ptr = rdev->rlc.reg_list; dws = rdev->rlc.reg_list_size; + if (rdev->family >= CHIP_BONAIRE) { + dws += (5 * 16) + 48 + 48 + 64; + } cs_data = rdev->rlc.cs_data; if (src_ptr) { @@ -3966,7 +3971,9 @@ int sumo_rlc_init(struct radeon_device *rdev) if (cs_data) { /* clear state block */ - if (rdev->family >= CHIP_TAHITI) { + if (rdev->family >= CHIP_BONAIRE) { + rdev->rlc.clear_state_size = dws = cik_get_csb_size(rdev); + } else if (rdev->family >= CHIP_TAHITI) { rdev->rlc.clear_state_size = si_get_csb_size(rdev); dws = rdev->rlc.clear_state_size + (256 / 4); } else { @@ -4014,7 +4021,9 @@ int sumo_rlc_init(struct radeon_device *rdev) } /* set up the cs buffer */ dst_ptr = rdev->rlc.cs_ptr; - if (rdev->family >= CHIP_TAHITI) { + if (rdev->family >= CHIP_BONAIRE) { + cik_get_csb_buffer(rdev, dst_ptr); + } else if (rdev->family >= CHIP_TAHITI) { reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + 256; dst_ptr[0] = upper_32_bits(reg_list_mc_addr); dst_ptr[1] = lower_32_bits(reg_list_mc_addr); |