|
@@ -68,6 +68,8 @@ MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
|
|
|
|
|
|
static void si_pcie_gen3_enable(struct radeon_device *rdev);
|
|
|
static void si_program_aspm(struct radeon_device *rdev);
|
|
|
+extern void sumo_rlc_fini(struct radeon_device *rdev);
|
|
|
+extern int sumo_rlc_init(struct radeon_device *rdev);
|
|
|
extern int r600_ih_ring_alloc(struct radeon_device *rdev);
|
|
|
extern void r600_ih_ring_fini(struct radeon_device *rdev);
|
|
|
extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
|
|
@@ -5275,166 +5277,6 @@ static void si_fini_pg(struct radeon_device *rdev)
|
|
|
/*
|
|
|
* RLC
|
|
|
*/
|
|
|
-void si_rlc_fini(struct radeon_device *rdev)
|
|
|
-{
|
|
|
- int r;
|
|
|
-
|
|
|
- /* save restore block */
|
|
|
- if (rdev->rlc.save_restore_obj) {
|
|
|
- r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
|
|
|
- if (unlikely(r != 0))
|
|
|
- dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r);
|
|
|
- radeon_bo_unpin(rdev->rlc.save_restore_obj);
|
|
|
- radeon_bo_unreserve(rdev->rlc.save_restore_obj);
|
|
|
-
|
|
|
- radeon_bo_unref(&rdev->rlc.save_restore_obj);
|
|
|
- rdev->rlc.save_restore_obj = NULL;
|
|
|
- }
|
|
|
-
|
|
|
- /* clear state block */
|
|
|
- if (rdev->rlc.clear_state_obj) {
|
|
|
- r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
|
|
|
- if (unlikely(r != 0))
|
|
|
- dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r);
|
|
|
- radeon_bo_unpin(rdev->rlc.clear_state_obj);
|
|
|
- radeon_bo_unreserve(rdev->rlc.clear_state_obj);
|
|
|
-
|
|
|
- radeon_bo_unref(&rdev->rlc.clear_state_obj);
|
|
|
- rdev->rlc.clear_state_obj = NULL;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#define RLC_CLEAR_STATE_END_MARKER 0x00000001
|
|
|
-
|
|
|
-int si_rlc_init(struct radeon_device *rdev)
|
|
|
-{
|
|
|
- volatile u32 *dst_ptr;
|
|
|
- u32 dws, data, i, j, k, reg_num;
|
|
|
- u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index;
|
|
|
- u64 reg_list_mc_addr;
|
|
|
- const struct cs_section_def *cs_data = si_cs_data;
|
|
|
- int r;
|
|
|
-
|
|
|
- /* save restore block */
|
|
|
- if (rdev->rlc.save_restore_obj == NULL) {
|
|
|
- r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
|
|
|
- RADEON_GEM_DOMAIN_VRAM, NULL,
|
|
|
- &rdev->rlc.save_restore_obj);
|
|
|
- if (r) {
|
|
|
- dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
|
|
|
- return r;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
|
|
|
- if (unlikely(r != 0)) {
|
|
|
- si_rlc_fini(rdev);
|
|
|
- return r;
|
|
|
- }
|
|
|
- r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
|
|
|
- &rdev->rlc.save_restore_gpu_addr);
|
|
|
- if (r) {
|
|
|
- radeon_bo_unreserve(rdev->rlc.save_restore_obj);
|
|
|
- dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
|
|
|
- si_rlc_fini(rdev);
|
|
|
- return r;
|
|
|
- }
|
|
|
-
|
|
|
- if (rdev->family == CHIP_VERDE) {
|
|
|
- r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
|
|
|
- if (r) {
|
|
|
- dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
|
|
|
- si_rlc_fini(rdev);
|
|
|
- return r;
|
|
|
- }
|
|
|
- /* write the sr buffer */
|
|
|
- dst_ptr = rdev->rlc.sr_ptr;
|
|
|
- for (i = 0; i < ARRAY_SIZE(verde_rlc_save_restore_register_list); i++) {
|
|
|
- dst_ptr[i] = verde_rlc_save_restore_register_list[i];
|
|
|
- }
|
|
|
- radeon_bo_kunmap(rdev->rlc.save_restore_obj);
|
|
|
- }
|
|
|
- radeon_bo_unreserve(rdev->rlc.save_restore_obj);
|
|
|
-
|
|
|
- /* clear state block */
|
|
|
- reg_list_num = 0;
|
|
|
- dws = 0;
|
|
|
- for (i = 0; cs_data[i].section != NULL; i++) {
|
|
|
- for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
|
|
|
- reg_list_num++;
|
|
|
- dws += cs_data[i].section[j].reg_count;
|
|
|
- }
|
|
|
- }
|
|
|
- reg_list_blk_index = (3 * reg_list_num + 2);
|
|
|
- dws += reg_list_blk_index;
|
|
|
-
|
|
|
- if (rdev->rlc.clear_state_obj == NULL) {
|
|
|
- r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
|
|
|
- RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.clear_state_obj);
|
|
|
- if (r) {
|
|
|
- dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
|
|
|
- si_rlc_fini(rdev);
|
|
|
- return r;
|
|
|
- }
|
|
|
- }
|
|
|
- r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
|
|
|
- if (unlikely(r != 0)) {
|
|
|
- si_rlc_fini(rdev);
|
|
|
- return r;
|
|
|
- }
|
|
|
- r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
|
|
|
- &rdev->rlc.clear_state_gpu_addr);
|
|
|
- if (r) {
|
|
|
-
|
|
|
- radeon_bo_unreserve(rdev->rlc.clear_state_obj);
|
|
|
- dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
|
|
|
- si_rlc_fini(rdev);
|
|
|
- return r;
|
|
|
- }
|
|
|
- r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
|
|
|
- if (r) {
|
|
|
- dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
|
|
|
- si_rlc_fini(rdev);
|
|
|
- return r;
|
|
|
- }
|
|
|
- /* set up the cs buffer */
|
|
|
- dst_ptr = rdev->rlc.cs_ptr;
|
|
|
- reg_list_hdr_blk_index = 0;
|
|
|
- reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
|
|
|
- data = upper_32_bits(reg_list_mc_addr);
|
|
|
- dst_ptr[reg_list_hdr_blk_index] = data;
|
|
|
- reg_list_hdr_blk_index++;
|
|
|
- for (i = 0; cs_data[i].section != NULL; i++) {
|
|
|
- for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
|
|
|
- reg_num = cs_data[i].section[j].reg_count;
|
|
|
- data = reg_list_mc_addr & 0xffffffff;
|
|
|
- dst_ptr[reg_list_hdr_blk_index] = data;
|
|
|
- reg_list_hdr_blk_index++;
|
|
|
-
|
|
|
- data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
|
|
|
- dst_ptr[reg_list_hdr_blk_index] = data;
|
|
|
- reg_list_hdr_blk_index++;
|
|
|
-
|
|
|
- data = 0x08000000 | (reg_num * 4);
|
|
|
- dst_ptr[reg_list_hdr_blk_index] = data;
|
|
|
- reg_list_hdr_blk_index++;
|
|
|
-
|
|
|
- for (k = 0; k < reg_num; k++) {
|
|
|
- data = cs_data[i].section[j].extent[k];
|
|
|
- dst_ptr[reg_list_blk_index + k] = data;
|
|
|
- }
|
|
|
- reg_list_mc_addr += reg_num * 4;
|
|
|
- reg_list_blk_index += reg_num;
|
|
|
- }
|
|
|
- }
|
|
|
- dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER;
|
|
|
-
|
|
|
- radeon_bo_kunmap(rdev->rlc.clear_state_obj);
|
|
|
- radeon_bo_unreserve(rdev->rlc.clear_state_obj);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
void si_rlc_reset(struct radeon_device *rdev)
|
|
|
{
|
|
|
u32 tmp = RREG32(GRBM_SOFT_RESET);
|
|
@@ -6449,7 +6291,13 @@ static int si_startup(struct radeon_device *rdev)
|
|
|
si_gpu_init(rdev);
|
|
|
|
|
|
/* allocate rlc buffers */
|
|
|
- r = si_rlc_init(rdev);
|
|
|
+ if (rdev->family == CHIP_VERDE) {
|
|
|
+ rdev->rlc.reg_list = verde_rlc_save_restore_register_list;
|
|
|
+ rdev->rlc.reg_list_size =
|
|
|
+ (u32)ARRAY_SIZE(verde_rlc_save_restore_register_list);
|
|
|
+ }
|
|
|
+ rdev->rlc.cs_data = si_cs_data;
|
|
|
+ r = sumo_rlc_init(rdev);
|
|
|
if (r) {
|
|
|
DRM_ERROR("Failed to init rlc BOs!\n");
|
|
|
return r;
|
|
@@ -6735,7 +6583,7 @@ int si_init(struct radeon_device *rdev)
|
|
|
si_cp_fini(rdev);
|
|
|
cayman_dma_fini(rdev);
|
|
|
si_irq_fini(rdev);
|
|
|
- si_rlc_fini(rdev);
|
|
|
+ sumo_rlc_fini(rdev);
|
|
|
radeon_wb_fini(rdev);
|
|
|
radeon_ib_pool_fini(rdev);
|
|
|
radeon_vm_manager_fini(rdev);
|
|
@@ -6761,7 +6609,7 @@ void si_fini(struct radeon_device *rdev)
|
|
|
si_cp_fini(rdev);
|
|
|
cayman_dma_fini(rdev);
|
|
|
si_irq_fini(rdev);
|
|
|
- si_rlc_fini(rdev);
|
|
|
+ sumo_rlc_fini(rdev);
|
|
|
si_fini_cg(rdev);
|
|
|
si_fini_pg(rdev);
|
|
|
radeon_wb_fini(rdev);
|