diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/si_dpm.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.c | 129 | 
1 files changed, 68 insertions, 61 deletions
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 5be9b4e7235..58918868f89 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -1738,6 +1738,8 @@ struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);  struct ni_power_info *ni_get_pi(struct radeon_device *rdev);  struct ni_ps *ni_get_ps(struct radeon_ps *rps); +extern int si_mc_load_microcode(struct radeon_device *rdev); +  static int si_populate_voltage_value(struct radeon_device *rdev,  				     const struct atom_voltage_table *table,  				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage); @@ -1753,9 +1755,6 @@ static int si_calculate_sclk_params(struct radeon_device *rdev,  				    u32 engine_clock,  				    SISLANDS_SMC_SCLK_VALUE *sclk); -extern void si_update_cg(struct radeon_device *rdev, -			 u32 block, bool enable); -  static struct si_power_info *si_get_pi(struct radeon_device *rdev)  {          struct si_power_info *pi = rdev->pm.dpm.priv; @@ -1949,6 +1948,10 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev)  			si_pi->cac_weights = cac_weights_cape_verde_pro;  			si_pi->dte_data = dte_data_cape_verde;  			break; +		case 0x682C: +			si_pi->cac_weights = cac_weights_cape_verde_pro; +			si_pi->dte_data = dte_data_sun_xt; +			break;  		case 0x6825:  		case 0x6827:  			si_pi->cac_weights = cac_weights_heathrow; @@ -1972,10 +1975,9 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev)  			si_pi->dte_data = dte_data_venus_xt;  			break;  		case 0x6823: -			si_pi->cac_weights = cac_weights_chelsea_pro; -			si_pi->dte_data = dte_data_venus_pro; -			break;  		case 0x682B: +		case 0x6822: +		case 0x682A:  			si_pi->cac_weights = cac_weights_chelsea_pro;  			si_pi->dte_data = dte_data_venus_pro;  			break; @@ -1989,6 +1991,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev)  		case 0x6601:  		case 0x6621:  		case 0x6603: +		case 0x6605:  			si_pi->cac_weights = cac_weights_mars_pro;  			si_pi->lcac_config = lcac_mars_pro;  			si_pi->cac_override = cac_override_oland; @@ -1999,6 +2002,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev)  		case 0x6600:  		case 0x6606:  		case 0x6620: +		case 0x6604:  			si_pi->cac_weights = cac_weights_mars_xt;  			si_pi->lcac_config = lcac_mars_pro;  			si_pi->cac_override = cac_override_oland; @@ -2007,6 +2011,8 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev)  			update_dte_from_pl2 = true;  			break;  		case 0x6611: +		case 0x6613: +		case 0x6608:  			si_pi->cac_weights = cac_weights_oland_pro;  			si_pi->lcac_config = lcac_mars_pro;  			si_pi->cac_override = cac_override_oland; @@ -2396,7 +2402,7 @@ static int si_populate_sq_ramping_values(struct radeon_device *rdev,  	if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT))  		enable_sq_ramping = false; -	if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) +	if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT))  		enable_sq_ramping = false;  	for (i = 0; i < state->performance_level_count; i++) { @@ -2910,6 +2916,7 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,  	bool disable_sclk_switching = false;  	u32 mclk, sclk;  	u16 vddc, vddci; +	u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;  	int i;  	if ((rdev->pm.dpm.new_active_crtc_count > 1) || @@ -2943,6 +2950,29 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,  		}  	} +	/* limit clocks to max supported clocks based on voltage dependency tables */ +	btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, +							&max_sclk_vddc); +	btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, +							&max_mclk_vddci); +	btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, +							&max_mclk_vddc); + +	for (i = 0; i < ps->performance_level_count; i++) { +		if (max_sclk_vddc) { +			if (ps->performance_levels[i].sclk > max_sclk_vddc) +				ps->performance_levels[i].sclk = max_sclk_vddc; +		} +		if (max_mclk_vddci) { +			if (ps->performance_levels[i].mclk > max_mclk_vddci) +				ps->performance_levels[i].mclk = max_mclk_vddci; +		} +		if (max_mclk_vddc) { +			if (ps->performance_levels[i].mclk > max_mclk_vddc) +				ps->performance_levels[i].mclk = max_mclk_vddc; +		} +	} +  	/* XXX validate the min clocks required for display */  	if (disable_mclk_switching) { @@ -3565,6 +3595,10 @@ static void si_program_display_gap(struct radeon_device *rdev)  		WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);  	} +	/* Setting this to false forces the performance state to low if the crtcs are disabled. +	 * This can be a problem on PowerXpress systems or if you want to use the card +	 * for offscreen rendering or compute if there are no crtcs enabled. +	 */  	si_notify_smc_display_change(rdev, rdev->pm.dpm.new_active_crtc_count > 0);  } @@ -4529,7 +4563,7 @@ static int si_init_smc_table(struct radeon_device *rdev)  		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;  	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY) -		table->systemFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH; +		table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;  	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) {  		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO; @@ -5184,7 +5218,7 @@ static int si_set_mc_special_registers(struct radeon_device *rdev,  					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;  			}  			j++; -			if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) +			if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)  				return -EINVAL;  			if (!pi->mem_gddr5) { @@ -5194,7 +5228,7 @@ static int si_set_mc_special_registers(struct radeon_device *rdev,  					table->mc_reg_table_entry[k].mc_data[j] =  						(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;  				j++; -				if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) +				if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)  					return -EINVAL;  			}  			break; @@ -5207,7 +5241,7 @@ static int si_set_mc_special_registers(struct radeon_device *rdev,  					(temp_reg & 0xffff0000) |  					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);  			j++; -			if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE) +			if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)  				return -EINVAL;  			break;  		default: @@ -5385,7 +5419,7 @@ static void si_populate_mc_reg_addresses(struct radeon_device *rdev,  	for (i = 0, j = 0; j < si_pi->mc_reg_table.last; j++) {  		if (si_pi->mc_reg_table.valid_flag & (1 << j)) { -			if (i >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) +			if (i >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)  				break;  			mc_reg_table->address[i].s0 =  				cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s0); @@ -5725,6 +5759,11 @@ static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev,  void si_dpm_setup_asic(struct radeon_device *rdev)  { +	int r; + +	r = si_mc_load_microcode(rdev); +	if (r) +		DRM_ERROR("Failed to load MC firmware!\n");  	rv770_get_memory_type(rdev);  	si_read_clock_registers(rdev);  	si_enable_acpi_power_management(rdev); @@ -5762,13 +5801,6 @@ int si_dpm_enable(struct radeon_device *rdev)  	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;  	int ret; -	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | -			    RADEON_CG_BLOCK_MC | -			    RADEON_CG_BLOCK_SDMA | -			    RADEON_CG_BLOCK_BIF | -			    RADEON_CG_BLOCK_UVD | -			    RADEON_CG_BLOCK_HDP), false); -  	if (si_is_smc_running(rdev))  		return -EINVAL;  	if (pi->voltage_control) @@ -5871,6 +5903,17 @@ int si_dpm_enable(struct radeon_device *rdev)  	si_enable_sclk_control(rdev, true);  	si_start_dpm(rdev); +	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); + +	ni_update_current_ps(rdev, boot_ps); + +	return 0; +} + +int si_dpm_late_enable(struct radeon_device *rdev) +{ +	int ret; +  	if (rdev->irq.installed &&  	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {  		PPSMC_Result result; @@ -5886,17 +5929,6 @@ int si_dpm_enable(struct radeon_device *rdev)  			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");  	} -	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); - -	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | -			    RADEON_CG_BLOCK_MC | -			    RADEON_CG_BLOCK_SDMA | -			    RADEON_CG_BLOCK_BIF | -			    RADEON_CG_BLOCK_UVD | -			    RADEON_CG_BLOCK_HDP), true); - -	ni_update_current_ps(rdev, boot_ps); -  	return 0;  } @@ -5905,13 +5937,6 @@ void si_dpm_disable(struct radeon_device *rdev)  	struct rv7xx_power_info *pi = rv770_get_pi(rdev);  	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; -	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | -			    RADEON_CG_BLOCK_MC | -			    RADEON_CG_BLOCK_SDMA | -			    RADEON_CG_BLOCK_BIF | -			    RADEON_CG_BLOCK_UVD | -			    RADEON_CG_BLOCK_HDP), false); -  	if (!si_is_smc_running(rdev))  		return;  	si_disable_ulv(rdev); @@ -5976,13 +6001,6 @@ int si_dpm_set_power_state(struct radeon_device *rdev)  	struct radeon_ps *old_ps = &eg_pi->current_rps;  	int ret; -	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | -			    RADEON_CG_BLOCK_MC | -			    RADEON_CG_BLOCK_SDMA | -			    RADEON_CG_BLOCK_BIF | -			    RADEON_CG_BLOCK_UVD | -			    RADEON_CG_BLOCK_HDP), false); -  	ret = si_disable_ulv(rdev);  	if (ret) {  		DRM_ERROR("si_disable_ulv failed\n"); @@ -6075,19 +6093,6 @@ int si_dpm_set_power_state(struct radeon_device *rdev)  		return ret;  	} -	ret = si_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); -	if (ret) { -		DRM_ERROR("si_dpm_force_performance_level failed\n"); -		return ret; -	} - -	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | -			    RADEON_CG_BLOCK_MC | -			    RADEON_CG_BLOCK_SDMA | -			    RADEON_CG_BLOCK_BIF | -			    RADEON_CG_BLOCK_UVD | -			    RADEON_CG_BLOCK_HDP), true); -  	return 0;  } @@ -6273,9 +6278,6 @@ static int si_parse_power_table(struct radeon_device *rdev)  	if (!rdev->pm.dpm.ps)  		return -ENOMEM;  	power_state_offset = (u8 *)state_array->states; -	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); -	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); -	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);  	for (i = 0; i < state_array->ucNumEntries; i++) {  		u8 *idx;  		power_state = (union pplib_power_state *)power_state_offset; @@ -6352,6 +6354,10 @@ int si_dpm_init(struct radeon_device *rdev)  	pi->min_vddc_in_table = 0;  	pi->max_vddc_in_table = 0; +	ret = r600_get_platform_caps(rdev); +	if (ret) +		return ret; +  	ret = si_parse_power_table(rdev);  	if (ret)  		return ret; @@ -6474,7 +6480,8 @@ void si_dpm_fini(struct radeon_device *rdev)  void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,  						    struct seq_file *m)  { -	struct radeon_ps *rps = rdev->pm.dpm.current_ps; +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); +	struct radeon_ps *rps = &eg_pi->current_rps;  	struct ni_ps *ps = ni_get_ps(rps);  	struct rv7xx_pl *pl;  	u32 current_index =  | 
