diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/si.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/si.c | 437 | 
1 files changed, 283 insertions, 154 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 3e23b757dcf..9e854fd016d 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -39,33 +39,39 @@ MODULE_FIRMWARE("radeon/TAHITI_pfp.bin");  MODULE_FIRMWARE("radeon/TAHITI_me.bin");  MODULE_FIRMWARE("radeon/TAHITI_ce.bin");  MODULE_FIRMWARE("radeon/TAHITI_mc.bin"); +MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");  MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");  MODULE_FIRMWARE("radeon/TAHITI_smc.bin");  MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");  MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");  MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");  MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin"); +MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");  MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");  MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");  MODULE_FIRMWARE("radeon/VERDE_pfp.bin");  MODULE_FIRMWARE("radeon/VERDE_me.bin");  MODULE_FIRMWARE("radeon/VERDE_ce.bin");  MODULE_FIRMWARE("radeon/VERDE_mc.bin"); +MODULE_FIRMWARE("radeon/VERDE_mc2.bin");  MODULE_FIRMWARE("radeon/VERDE_rlc.bin");  MODULE_FIRMWARE("radeon/VERDE_smc.bin");  MODULE_FIRMWARE("radeon/OLAND_pfp.bin");  MODULE_FIRMWARE("radeon/OLAND_me.bin");  MODULE_FIRMWARE("radeon/OLAND_ce.bin");  MODULE_FIRMWARE("radeon/OLAND_mc.bin"); +MODULE_FIRMWARE("radeon/OLAND_mc2.bin");  MODULE_FIRMWARE("radeon/OLAND_rlc.bin");  MODULE_FIRMWARE("radeon/OLAND_smc.bin");  MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");  MODULE_FIRMWARE("radeon/HAINAN_me.bin");  MODULE_FIRMWARE("radeon/HAINAN_ce.bin");  MODULE_FIRMWARE("radeon/HAINAN_mc.bin"); +MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");  MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");  MODULE_FIRMWARE("radeon/HAINAN_smc.bin"); +static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);  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); @@ -78,11 +84,13 @@ extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_  extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev);  extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);  extern bool evergreen_is_display_hung(struct radeon_device *rdev); -extern void si_dma_vm_set_page(struct radeon_device *rdev, -			       struct radeon_ib *ib, -			       uint64_t pe, -			       uint64_t addr, unsigned count, -			       uint32_t incr, uint32_t flags); +static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, +					 bool enable); +static void si_init_pg(struct radeon_device *rdev); +static void si_init_cg(struct radeon_device *rdev); +static void si_fini_pg(struct radeon_device *rdev); +static void si_fini_cg(struct radeon_device *rdev); +static void si_rlc_stop(struct radeon_device *rdev);  static const u32 verde_rlc_save_restore_register_list[] =  { @@ -1460,41 +1468,38 @@ static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {  };  /* ucode loading */ -static int si_mc_load_microcode(struct radeon_device *rdev) +int si_mc_load_microcode(struct radeon_device *rdev)  {  	const __be32 *fw_data;  	u32 running, blackout = 0;  	u32 *io_mc_regs; -	int i, ucode_size, regs_size; +	int i, regs_size, ucode_size;  	if (!rdev->mc_fw)  		return -EINVAL; +	ucode_size = rdev->mc_fw->size / 4; +  	switch (rdev->family) {  	case CHIP_TAHITI:  		io_mc_regs = (u32 *)&tahiti_io_mc_regs; -		ucode_size = SI_MC_UCODE_SIZE;  		regs_size = TAHITI_IO_MC_REGS_SIZE;  		break;  	case CHIP_PITCAIRN:  		io_mc_regs = (u32 *)&pitcairn_io_mc_regs; -		ucode_size = SI_MC_UCODE_SIZE;  		regs_size = TAHITI_IO_MC_REGS_SIZE;  		break;  	case CHIP_VERDE:  	default:  		io_mc_regs = (u32 *)&verde_io_mc_regs; -		ucode_size = SI_MC_UCODE_SIZE;  		regs_size = TAHITI_IO_MC_REGS_SIZE;  		break;  	case CHIP_OLAND:  		io_mc_regs = (u32 *)&oland_io_mc_regs; -		ucode_size = OLAND_MC_UCODE_SIZE;  		regs_size = TAHITI_IO_MC_REGS_SIZE;  		break;  	case CHIP_HAINAN:  		io_mc_regs = (u32 *)&hainan_io_mc_regs; -		ucode_size = OLAND_MC_UCODE_SIZE;  		regs_size = TAHITI_IO_MC_REGS_SIZE;  		break;  	} @@ -1550,7 +1555,7 @@ static int si_init_microcode(struct radeon_device *rdev)  	const char *chip_name;  	const char *rlc_chip_name;  	size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size; -	size_t smc_req_size; +	size_t smc_req_size, mc2_req_size;  	char fw_name[30];  	int err; @@ -1565,6 +1570,7 @@ static int si_init_microcode(struct radeon_device *rdev)  		ce_req_size = SI_CE_UCODE_SIZE * 4;  		rlc_req_size = SI_RLC_UCODE_SIZE * 4;  		mc_req_size = SI_MC_UCODE_SIZE * 4; +		mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;  		smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);  		break;  	case CHIP_PITCAIRN: @@ -1575,6 +1581,7 @@ static int si_init_microcode(struct radeon_device *rdev)  		ce_req_size = SI_CE_UCODE_SIZE * 4;  		rlc_req_size = SI_RLC_UCODE_SIZE * 4;  		mc_req_size = SI_MC_UCODE_SIZE * 4; +		mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;  		smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);  		break;  	case CHIP_VERDE: @@ -1585,6 +1592,7 @@ static int si_init_microcode(struct radeon_device *rdev)  		ce_req_size = SI_CE_UCODE_SIZE * 4;  		rlc_req_size = SI_RLC_UCODE_SIZE * 4;  		mc_req_size = SI_MC_UCODE_SIZE * 4; +		mc2_req_size = VERDE_MC_UCODE_SIZE * 4;  		smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);  		break;  	case CHIP_OLAND: @@ -1594,7 +1602,7 @@ static int si_init_microcode(struct radeon_device *rdev)  		me_req_size = SI_PM4_UCODE_SIZE * 4;  		ce_req_size = SI_CE_UCODE_SIZE * 4;  		rlc_req_size = SI_RLC_UCODE_SIZE * 4; -		mc_req_size = OLAND_MC_UCODE_SIZE * 4; +		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;  		smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);  		break;  	case CHIP_HAINAN: @@ -1604,7 +1612,7 @@ static int si_init_microcode(struct radeon_device *rdev)  		me_req_size = SI_PM4_UCODE_SIZE * 4;  		ce_req_size = SI_CE_UCODE_SIZE * 4;  		rlc_req_size = SI_RLC_UCODE_SIZE * 4; -		mc_req_size = OLAND_MC_UCODE_SIZE * 4; +		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;  		smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);  		break;  	default: BUG(); @@ -1657,16 +1665,22 @@ static int si_init_microcode(struct radeon_device *rdev)  		err = -EINVAL;  	} -	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); +	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);  	err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); -	if (err) -		goto out; -	if (rdev->mc_fw->size != mc_req_size) { +	if (err) { +		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); +		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); +		if (err) +			goto out; +	} +	if ((rdev->mc_fw->size != mc_req_size) && +	    (rdev->mc_fw->size != mc2_req_size)) {  		printk(KERN_ERR  		       "si_mc: Bogus length %zu in firmware \"%s\"\n",  		       rdev->mc_fw->size, fw_name);  		err = -EINVAL;  	} +	DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);  	snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);  	err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); @@ -1676,6 +1690,7 @@ static int si_init_microcode(struct radeon_device *rdev)  		       fw_name);  		release_firmware(rdev->smc_fw);  		rdev->smc_fw = NULL; +		err = 0;  	} else if (rdev->smc_fw->size != smc_req_size) {  		printk(KERN_ERR  		       "si_smc: Bogus length %zu in firmware \"%s\"\n", @@ -2810,7 +2825,7 @@ static void si_setup_spi(struct radeon_device *rdev,  }  static u32 si_get_rb_disabled(struct radeon_device *rdev, -			      u32 max_rb_num, u32 se_num, +			      u32 max_rb_num_per_se,  			      u32 sh_per_se)  {  	u32 data, mask; @@ -2824,14 +2839,14 @@ static u32 si_get_rb_disabled(struct radeon_device *rdev,  	data >>= BACKEND_DISABLE_SHIFT; -	mask = si_create_bitmask(max_rb_num / se_num / sh_per_se); +	mask = si_create_bitmask(max_rb_num_per_se / 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) +			u32 max_rb_num_per_se)  {  	int i, j;  	u32 data, mask; @@ -2841,19 +2856,21 @@ static void si_setup_rb(struct radeon_device *rdev,  	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); +			data = si_get_rb_disabled(rdev, max_rb_num_per_se, 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++) { +	for (i = 0; i < max_rb_num_per_se * se_num; i++) {  		if (!(disabled_rbs & mask))  			enabled_rbs |= mask;  		mask <<= 1;  	} +	rdev->config.si.backend_enable_mask = enabled_rbs; +  	for (i = 0; i < se_num; i++) {  		si_select_se_sh(rdev, i, 0xffffffff);  		data = 0; @@ -2884,7 +2901,7 @@ static void si_gpu_init(struct radeon_device *rdev)  	u32 sx_debug_1;  	u32 hdp_host_path_cntl;  	u32 tmp; -	int i, j; +	int i, j, k;  	switch (rdev->family) {  	case CHIP_TAHITI: @@ -3082,6 +3099,14 @@ static void si_gpu_init(struct radeon_device *rdev)  		     rdev->config.si.max_sh_per_se,  		     rdev->config.si.max_cu_per_sh); +	for (i = 0; i < rdev->config.si.max_shader_engines; i++) { +		for (j = 0; j < rdev->config.si.max_sh_per_se; j++) { +			for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) { +				rdev->config.si.active_cus += +					hweight32(si_get_cu_active_bitmap(rdev, i, j)); +			} +		} +	}  	/* set HW defaults for 3D engine */  	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | @@ -3170,7 +3195,7 @@ void si_fence_ring_emit(struct radeon_device *rdev,  	/* EVENT_WRITE_EOP - flush caches, send int */  	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));  	radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5)); -	radeon_ring_write(ring, addr & 0xffffffff); +	radeon_ring_write(ring, lower_32_bits(addr));  	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));  	radeon_ring_write(ring, fence->seq);  	radeon_ring_write(ring, 0); @@ -3203,7 +3228,7 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)  			radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));  			radeon_ring_write(ring, (1 << 8));  			radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); -			radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff); +			radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr));  			radeon_ring_write(ring, next_rptr);  		} @@ -3244,7 +3269,8 @@ static void si_cp_enable(struct radeon_device *rdev, bool enable)  	if (enable)  		WREG32(CP_ME_CNTL, 0);  	else { -		radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); +		if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) +			radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);  		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));  		WREG32(SCRATCH_UMSK, 0);  		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; @@ -3386,6 +3412,8 @@ static int si_cp_resume(struct radeon_device *rdev)  	u32 rb_bufsz;  	int r; +	si_enable_gui_idle_interrupt(rdev, false); +  	WREG32(CP_SEM_WAIT_TIMER, 0x0);  	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); @@ -3426,8 +3454,6 @@ static int si_cp_resume(struct radeon_device *rdev)  	WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); -	ring->rptr = RREG32(CP_RB0_RPTR); -  	/* ring1  - compute only */  	/* Set ring buffer size */  	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; @@ -3452,8 +3478,6 @@ static int si_cp_resume(struct radeon_device *rdev)  	WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); -	ring->rptr = RREG32(CP_RB1_RPTR); -  	/* ring2 - compute only */  	/* Set ring buffer size */  	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; @@ -3478,8 +3502,6 @@ static int si_cp_resume(struct radeon_device *rdev)  	WREG32(CP_RB2_BASE, ring->gpu_addr >> 8); -	ring->rptr = RREG32(CP_RB2_RPTR); -  	/* start the rings */  	si_cp_start(rdev);  	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; @@ -3501,6 +3523,11 @@ static int si_cp_resume(struct radeon_device *rdev)  		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;  	} +	si_enable_gui_idle_interrupt(rdev, true); + +	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) +		radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); +  	return 0;  } @@ -3602,6 +3629,13 @@ static void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)  	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",  		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); +	/* disable PG/CG */ +	si_fini_pg(rdev); +	si_fini_cg(rdev); + +	/* stop the rlc */ +	si_rlc_stop(rdev); +  	/* Disable CP parsing/prefetching */  	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); @@ -3710,6 +3744,106 @@ static void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)  	evergreen_print_gpu_status_regs(rdev);  } +static void si_set_clk_bypass_mode(struct radeon_device *rdev) +{ +	u32 tmp, i; + +	tmp = RREG32(CG_SPLL_FUNC_CNTL); +	tmp |= SPLL_BYPASS_EN; +	WREG32(CG_SPLL_FUNC_CNTL, tmp); + +	tmp = RREG32(CG_SPLL_FUNC_CNTL_2); +	tmp |= SPLL_CTLREQ_CHG; +	WREG32(CG_SPLL_FUNC_CNTL_2, tmp); + +	for (i = 0; i < rdev->usec_timeout; i++) { +		if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS) +			break; +		udelay(1); +	} + +	tmp = RREG32(CG_SPLL_FUNC_CNTL_2); +	tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE); +	WREG32(CG_SPLL_FUNC_CNTL_2, tmp); + +	tmp = RREG32(MPLL_CNTL_MODE); +	tmp &= ~MPLL_MCLK_SEL; +	WREG32(MPLL_CNTL_MODE, tmp); +} + +static void si_spll_powerdown(struct radeon_device *rdev) +{ +	u32 tmp; + +	tmp = RREG32(SPLL_CNTL_MODE); +	tmp |= SPLL_SW_DIR_CONTROL; +	WREG32(SPLL_CNTL_MODE, tmp); + +	tmp = RREG32(CG_SPLL_FUNC_CNTL); +	tmp |= SPLL_RESET; +	WREG32(CG_SPLL_FUNC_CNTL, tmp); + +	tmp = RREG32(CG_SPLL_FUNC_CNTL); +	tmp |= SPLL_SLEEP; +	WREG32(CG_SPLL_FUNC_CNTL, tmp); + +	tmp = RREG32(SPLL_CNTL_MODE); +	tmp &= ~SPLL_SW_DIR_CONTROL; +	WREG32(SPLL_CNTL_MODE, tmp); +} + +static void si_gpu_pci_config_reset(struct radeon_device *rdev) +{ +	struct evergreen_mc_save save; +	u32 tmp, i; + +	dev_info(rdev->dev, "GPU pci config reset\n"); + +	/* disable dpm? */ + +	/* disable cg/pg */ +	si_fini_pg(rdev); +	si_fini_cg(rdev); + +	/* Disable CP parsing/prefetching */ +	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); +	/* dma0 */ +	tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); +	tmp &= ~DMA_RB_ENABLE; +	WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); +	/* dma1 */ +	tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); +	tmp &= ~DMA_RB_ENABLE; +	WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); +	/* XXX other engines? */ + +	/* halt the rlc, disable cp internal ints */ +	si_rlc_stop(rdev); + +	udelay(50); + +	/* disable mem access */ +	evergreen_mc_stop(rdev, &save); +	if (evergreen_mc_wait_for_idle(rdev)) { +		dev_warn(rdev->dev, "Wait for MC idle timed out !\n"); +	} + +	/* set mclk/sclk to bypass */ +	si_set_clk_bypass_mode(rdev); +	/* powerdown spll */ +	si_spll_powerdown(rdev); +	/* disable BM */ +	pci_clear_master(rdev->pdev); +	/* reset */ +	radeon_pci_config_reset(rdev); +	/* wait for asic to come out of reset */ +	for (i = 0; i < rdev->usec_timeout; i++) { +		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff) +			break; +		udelay(1); +	} +} +  int si_asic_reset(struct radeon_device *rdev)  {  	u32 reset_mask; @@ -3719,10 +3853,17 @@ int si_asic_reset(struct radeon_device *rdev)  	if (reset_mask)  		r600_set_bios_scratch_engine_hung(rdev, true); +	/* try soft reset */  	si_gpu_soft_reset(rdev, reset_mask);  	reset_mask = si_gpu_check_soft_reset(rdev); +	/* try pci config reset */ +	if (reset_mask && radeon_hard_reset) +		si_gpu_pci_config_reset(rdev); + +	reset_mask = si_gpu_check_soft_reset(rdev); +  	if (!reset_mask)  		r600_set_bios_scratch_engine_hung(rdev, false); @@ -3745,11 +3886,9 @@ bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)  	if (!(reset_mask & (RADEON_RESET_GFX |  			    RADEON_RESET_COMPUTE |  			    RADEON_RESET_CP))) { -		radeon_ring_lockup_update(ring); +		radeon_ring_lockup_update(rdev, ring);  		return false;  	} -	/* force CP activities */ -	radeon_ring_force_activity(rdev, ring);  	return radeon_ring_test_lockup(rdev, ring);  } @@ -3870,8 +4009,15 @@ static int si_mc_init(struct radeon_device *rdev)  	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);  	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);  	/* size in MB on si */ -	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; -	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; +	tmp = RREG32(CONFIG_MEMSIZE); +	/* some boards may have garbage in the upper 16 bits */ +	if (tmp & 0xffff0000) { +		DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); +		if (tmp & 0xffff) +			tmp &= 0xffff; +	} +	rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL; +	rdev->mc.real_vram_size = rdev->mc.mc_vram_size;  	rdev->mc.visible_vram_size = rdev->mc.aper_size;  	si_vram_gtt_location(rdev, &rdev->mc);  	radeon_update_bandwidth_info(rdev); @@ -3907,18 +4053,21 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)  	WREG32(MC_VM_MX_L1_TLB_CNTL,  	       (0xA << 7) |  	       ENABLE_L1_TLB | +	       ENABLE_L1_FRAGMENT_PROCESSING |  	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |  	       ENABLE_ADVANCED_DRIVER_MODEL |  	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);  	/* Setup L2 cache */  	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | +	       ENABLE_L2_FRAGMENT_PROCESSING |  	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |  	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |  	       EFFECTIVE_L2_QUEUE_SIZE(7) |  	       CONTEXT1_IDENTITY_ACCESS_MODE(1));  	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);  	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | -	       L2_CACHE_BIGK_FRAGMENT_SIZE(0)); +	       BANK_SELECT(4) | +	       L2_CACHE_BIGK_FRAGMENT_SIZE(4));  	/* setup context0 */  	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);  	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); @@ -3955,6 +4104,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)  	       (u32)(rdev->dummy_page.addr >> 12));  	WREG32(VM_CONTEXT1_CNTL2, 4);  	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | +				PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |  				RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |  				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |  				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT | @@ -4656,61 +4806,6 @@ static void si_vm_decode_fault(struct radeon_device *rdev,  	       block, mc_id);  } -/** - * si_vm_set_page - update the page tables using the CP - * - * @rdev: radeon_device pointer - * @ib: indirect buffer to fill with commands - * @pe: addr of the page entry - * @addr: dst addr to write into pe - * @count: number of page entries to update - * @incr: increase next addr by incr bytes - * @flags: access flags - * - * Update the page tables using the CP (SI). - */ -void si_vm_set_page(struct radeon_device *rdev, -		    struct radeon_ib *ib, -		    uint64_t pe, -		    uint64_t addr, unsigned count, -		    uint32_t incr, uint32_t flags) -{ -	uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); -	uint64_t value; -	unsigned ndw; - -	if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { -		while (count) { -			ndw = 2 + count * 2; -			if (ndw > 0x3FFE) -				ndw = 0x3FFE; - -			ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw); -			ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) | -					WRITE_DATA_DST_SEL(1)); -			ib->ptr[ib->length_dw++] = pe; -			ib->ptr[ib->length_dw++] = upper_32_bits(pe); -			for (; ndw > 2; ndw -= 2, --count, pe += 8) { -				if (flags & RADEON_VM_PAGE_SYSTEM) { -					value = radeon_vm_map_gart(rdev, addr); -					value &= 0xFFFFFFFFFFFFF000ULL; -				} else if (flags & RADEON_VM_PAGE_VALID) { -					value = addr; -				} else { -					value = 0; -				} -				addr += incr; -				value |= r600_flags; -				ib->ptr[ib->length_dw++] = value; -				ib->ptr[ib->length_dw++] = upper_32_bits(value); -			} -		} -	} else { -		/* DMA */ -		si_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); -	} -} -  void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)  {  	struct radeon_ring *ring = &rdev->ring[ridx]; @@ -4888,7 +4983,7 @@ static void si_enable_gfx_cgpg(struct radeon_device *rdev,  {  	u32 tmp; -	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_CG)) { +	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) {  		tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10);  		WREG32(RLC_TTOP_D, tmp); @@ -5246,10 +5341,11 @@ static void si_enable_hdp_ls(struct radeon_device *rdev,  		WREG32(HDP_MEM_POWER_LS, data);  } -void si_update_cg(struct radeon_device *rdev, -		  u32 block, bool enable) +static void si_update_cg(struct radeon_device *rdev, +			 u32 block, bool enable)  {  	if (block & RADEON_CG_BLOCK_GFX) { +		si_enable_gui_idle_interrupt(rdev, false);  		/* order matters! */  		if (enable) {  			si_enable_mgcg(rdev, true); @@ -5258,6 +5354,7 @@ void si_update_cg(struct radeon_device *rdev,  			si_enable_cgcg(rdev, false);  			si_enable_mgcg(rdev, false);  		} +		si_enable_gui_idle_interrupt(rdev, true);  	}  	if (block & RADEON_CG_BLOCK_MC) { @@ -5353,52 +5450,53 @@ void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)  	if (buffer == NULL)  		return; -	buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); -	buffer[count++] = PACKET3_PREAMBLE_BEGIN_CLEAR_STATE; +	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); +	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); -	buffer[count++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1); -	buffer[count++] = 0x80000000; -	buffer[count++] = 0x80000000; +	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); +	buffer[count++] = cpu_to_le32(0x80000000); +	buffer[count++] = cpu_to_le32(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; +				buffer[count++] = +					cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); +				buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);  				for (i = 0; i < ext->reg_count; i++) -					buffer[count++] = ext->extent[i]; +					buffer[count++] = cpu_to_le32(ext->extent[i]);  			} else {  				return;  			}  		}  	} -	buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); -	buffer[count++] = PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START; +	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1)); +	buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);  	switch (rdev->family) {  	case CHIP_TAHITI:  	case CHIP_PITCAIRN: -		buffer[count++] = 0x2a00126a; +		buffer[count++] = cpu_to_le32(0x2a00126a);  		break;  	case CHIP_VERDE: -		buffer[count++] = 0x0000124a; +		buffer[count++] = cpu_to_le32(0x0000124a);  		break;  	case CHIP_OLAND: -		buffer[count++] = 0x00000082; +		buffer[count++] = cpu_to_le32(0x00000082);  		break;  	case CHIP_HAINAN: -		buffer[count++] = 0x00000000; +		buffer[count++] = cpu_to_le32(0x00000000);  		break;  	default: -		buffer[count++] = 0x00000000; +		buffer[count++] = cpu_to_le32(0x00000000);  		break;  	} -	buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); -	buffer[count++] = PACKET3_PREAMBLE_END_CLEAR_STATE; +	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); +	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); -	buffer[count++] = PACKET3(PACKET3_CLEAR_STATE, 0); -	buffer[count++] = 0; +	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); +	buffer[count++] = cpu_to_le32(0);  }  static void si_init_pg(struct radeon_device *rdev) @@ -5408,8 +5506,11 @@ static void si_init_pg(struct radeon_device *rdev)  			si_init_dma_pg(rdev);  		}  		si_init_ao_cu_mask(rdev); -		if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_CG) { +		if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) {  			si_init_gfx_cgpg(rdev); +		} else { +			WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); +			WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);  		}  		si_enable_dma_pg(rdev, true);  		si_enable_gfx_cgpg(rdev, true); @@ -5560,7 +5661,9 @@ static void si_disable_interrupt_state(struct radeon_device *rdev)  {  	u32 tmp; -	WREG32(CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); +	tmp = RREG32(CP_INT_CNTL_RING0) & +		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); +	WREG32(CP_INT_CNTL_RING0, tmp);  	WREG32(CP_INT_CNTL_RING1, 0);  	WREG32(CP_INT_CNTL_RING2, 0);  	tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; @@ -5595,7 +5698,7 @@ static void si_disable_interrupt_state(struct radeon_device *rdev)  	}  	if (!ASIC_IS_NODCE(rdev)) { -		WREG32(DACA_AUTODETECT_INT_CONTROL, 0); +		WREG32(DAC_AUTODETECT_INT_CONTROL, 0);  		tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;  		WREG32(DC_HPD1_INT_CONTROL, tmp); @@ -5685,12 +5788,11 @@ static int si_irq_init(struct radeon_device *rdev)  int si_irq_set(struct radeon_device *rdev)  { -	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; +	u32 cp_int_cntl;  	u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;  	u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;  	u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0;  	u32 grbm_int_cntl = 0; -	u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;  	u32 dma_cntl, dma_cntl1;  	u32 thermal_int = 0; @@ -5706,6 +5808,9 @@ int si_irq_set(struct radeon_device *rdev)  		return 0;  	} +	cp_int_cntl = RREG32(CP_INT_CNTL_RING0) & +		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); +  	if (!ASIC_IS_NODCE(rdev)) {  		hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;  		hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; @@ -5826,16 +5931,22 @@ int si_irq_set(struct radeon_device *rdev)  	}  	if (rdev->num_crtc >= 2) { -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); +		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, +		       GRPH_PFLIP_INT_MASK); +		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, +		       GRPH_PFLIP_INT_MASK);  	}  	if (rdev->num_crtc >= 4) { -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); +		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, +		       GRPH_PFLIP_INT_MASK); +		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, +		       GRPH_PFLIP_INT_MASK);  	}  	if (rdev->num_crtc >= 6) { -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); -		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); +		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, +		       GRPH_PFLIP_INT_MASK); +		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, +		       GRPH_PFLIP_INT_MASK);  	}  	if (!ASIC_IS_NODCE(rdev)) { @@ -5992,6 +6103,7 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev)  		tmp = RREG32(IH_RB_CNTL);  		tmp |= IH_WPTR_OVERFLOW_CLEAR;  		WREG32(IH_RB_CNTL, tmp); +		wptr &= ~RB_OVERFLOW;  	}  	return (wptr & rdev->ih.ptr_mask);  } @@ -6053,7 +6165,7 @@ restart_ih:  						wake_up(&rdev->irq.vblank_queue);  					}  					if (atomic_read(&rdev->irq.pflip[0])) -						radeon_crtc_handle_flip(rdev, 0); +						radeon_crtc_handle_vblank(rdev, 0);  					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D1 vblank\n");  				} @@ -6079,7 +6191,7 @@ restart_ih:  						wake_up(&rdev->irq.vblank_queue);  					}  					if (atomic_read(&rdev->irq.pflip[1])) -						radeon_crtc_handle_flip(rdev, 1); +						radeon_crtc_handle_vblank(rdev, 1);  					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D2 vblank\n");  				} @@ -6105,7 +6217,7 @@ restart_ih:  						wake_up(&rdev->irq.vblank_queue);  					}  					if (atomic_read(&rdev->irq.pflip[2])) -						radeon_crtc_handle_flip(rdev, 2); +						radeon_crtc_handle_vblank(rdev, 2);  					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D3 vblank\n");  				} @@ -6131,7 +6243,7 @@ restart_ih:  						wake_up(&rdev->irq.vblank_queue);  					}  					if (atomic_read(&rdev->irq.pflip[3])) -						radeon_crtc_handle_flip(rdev, 3); +						radeon_crtc_handle_vblank(rdev, 3);  					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D4 vblank\n");  				} @@ -6157,7 +6269,7 @@ restart_ih:  						wake_up(&rdev->irq.vblank_queue);  					}  					if (atomic_read(&rdev->irq.pflip[4])) -						radeon_crtc_handle_flip(rdev, 4); +						radeon_crtc_handle_vblank(rdev, 4);  					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D5 vblank\n");  				} @@ -6183,7 +6295,7 @@ restart_ih:  						wake_up(&rdev->irq.vblank_queue);  					}  					if (atomic_read(&rdev->irq.pflip[5])) -						radeon_crtc_handle_flip(rdev, 5); +						radeon_crtc_handle_vblank(rdev, 5);  					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D6 vblank\n");  				} @@ -6199,6 +6311,15 @@ restart_ih:  				break;  			}  			break; +		case 8: /* D1 page flip */ +		case 10: /* D2 page flip */ +		case 12: /* D3 page flip */ +		case 14: /* D4 page flip */ +		case 16: /* D5 page flip */ +		case 18: /* D6 page flip */ +			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); +			radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); +			break;  		case 42: /* HPD hotplug */  			switch (src_data) {  			case 0: @@ -6248,18 +6369,24 @@ restart_ih:  				break;  			}  			break; +		case 124: /* UVD */ +			DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); +			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); +			break;  		case 146:  		case 147:  			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);  			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); +			/* reset addr and status */ +			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); +			if (addr == 0x0 && status == 0x0) +				break;  			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);  			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",  				addr);  			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",  				status);  			si_vm_decode_fault(rdev, status, addr); -			/* reset addr and status */ -			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);  			break;  		case 176: /* RINGID0 CP_INT */  			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); @@ -6350,21 +6477,14 @@ static int si_startup(struct radeon_device *rdev)  	si_mc_program(rdev); -	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || -	    !rdev->rlc_fw || !rdev->mc_fw) { -		r = si_init_microcode(rdev); +	if (!rdev->pm.dpm_enabled) { +		r = si_mc_load_microcode(rdev);  		if (r) { -			DRM_ERROR("Failed to load firmware!\n"); +			DRM_ERROR("Failed to load MC firmware!\n");  			return r;  		}  	} -	r = si_mc_load_microcode(rdev); -	if (r) { -		DRM_ERROR("Failed to load MC firmware!\n"); -		return r; -	} -  	r = si_pcie_gart_enable(rdev);  	if (r)  		return r; @@ -6447,37 +6567,30 @@ static int si_startup(struct radeon_device *rdev)  	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];  	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, -			     CP_RB0_RPTR, CP_RB0_WPTR,  			     RADEON_CP_PACKET2);  	if (r)  		return r;  	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];  	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET, -			     CP_RB1_RPTR, CP_RB1_WPTR,  			     RADEON_CP_PACKET2);  	if (r)  		return r;  	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];  	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET, -			     CP_RB2_RPTR, CP_RB2_WPTR,  			     RADEON_CP_PACKET2);  	if (r)  		return r;  	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];  	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, -			     DMA_RB_RPTR + DMA0_REGISTER_OFFSET, -			     DMA_RB_WPTR + DMA0_REGISTER_OFFSET,  			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));  	if (r)  		return r;  	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];  	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, -			     DMA_RB_RPTR + DMA1_REGISTER_OFFSET, -			     DMA_RB_WPTR + DMA1_REGISTER_OFFSET,  			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));  	if (r)  		return r; @@ -6497,7 +6610,6 @@ static int si_startup(struct radeon_device *rdev)  		ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];  		if (ring->ring_size) {  			r = radeon_ring_init(rdev, ring, ring->ring_size, 0, -					     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,  					     RADEON_CP_PACKET2);  			if (!r)  				r = uvd_v1_0_init(rdev); @@ -6539,6 +6651,9 @@ int si_resume(struct radeon_device *rdev)  	/* init golden registers */  	si_init_golden_registers(rdev); +	if (rdev->pm.pm_method == PM_METHOD_DPM) +		radeon_pm_resume(rdev); +  	rdev->accel_working = true;  	r = si_startup(rdev);  	if (r) { @@ -6553,6 +6668,7 @@ int si_resume(struct radeon_device *rdev)  int si_suspend(struct radeon_device *rdev)  { +	radeon_pm_suspend(rdev);  	dce6_audio_fini(rdev);  	radeon_vm_manager_fini(rdev);  	si_cp_enable(rdev, false); @@ -6626,6 +6742,18 @@ int si_init(struct radeon_device *rdev)  	if (r)  		return r; +	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || +	    !rdev->rlc_fw || !rdev->mc_fw) { +		r = si_init_microcode(rdev); +		if (r) { +			DRM_ERROR("Failed to load firmware!\n"); +			return r; +		} +	} + +	/* Initialize power management */ +	radeon_pm_init(rdev); +  	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];  	ring->ring_obj = NULL;  	r600_ring_init(rdev, ring, 1024 * 1024); @@ -6692,6 +6820,7 @@ int si_init(struct radeon_device *rdev)  void si_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	si_cp_fini(rdev);  	cayman_dma_fini(rdev);  	si_fini_pg(rdev);  | 
