drm/radeon: dpm updates for KV
This updates dpm support for KV asics. Notably there are some changes in acp handling and forcing performance levels. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									8c5c6fad61
								
							
						
					
					
						commit
						136de91ea7
					
				| @ -40,6 +40,7 @@ static int kv_calculate_dpm_settings(struct radeon_device *rdev); | ||||
| static void kv_enable_new_levels(struct radeon_device *rdev); | ||||
| static void kv_program_nbps_index_settings(struct radeon_device *rdev, | ||||
| 					   struct radeon_ps *new_rps); | ||||
| static int kv_set_enabled_level(struct radeon_device *rdev, u32 level); | ||||
| static int kv_set_enabled_levels(struct radeon_device *rdev); | ||||
| static int kv_force_dpm_highest(struct radeon_device *rdev); | ||||
| static int kv_force_dpm_lowest(struct radeon_device *rdev); | ||||
| @ -519,7 +520,7 @@ static int kv_set_dpm_boot_state(struct radeon_device *rdev) | ||||
| 
 | ||||
| static void kv_program_vc(struct radeon_device *rdev) | ||||
| { | ||||
| 	WREG32_SMC(CG_FTV_0, 0x3FFFC000); | ||||
| 	WREG32_SMC(CG_FTV_0, 0x3FFFC100); | ||||
| } | ||||
| 
 | ||||
| static void kv_clear_vc(struct radeon_device *rdev) | ||||
| @ -638,7 +639,10 @@ static int kv_force_lowest_valid(struct radeon_device *rdev) | ||||
| 
 | ||||
| static int kv_unforce_levels(struct radeon_device *rdev) | ||||
| { | ||||
| 	return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel); | ||||
| 	if (rdev->family == CHIP_KABINI) | ||||
| 		return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel); | ||||
| 	else | ||||
| 		return kv_set_enabled_levels(rdev); | ||||
| } | ||||
| 
 | ||||
| static int kv_update_sclk_t(struct radeon_device *rdev) | ||||
| @ -1076,6 +1080,13 @@ static int kv_enable_ulv(struct radeon_device *rdev, bool enable) | ||||
| 					PPSMC_MSG_EnableULV : PPSMC_MSG_DisableULV); | ||||
| } | ||||
| 
 | ||||
| static void kv_reset_acp_boot_level(struct radeon_device *rdev) | ||||
| { | ||||
| 	struct kv_power_info *pi = kv_get_pi(rdev); | ||||
| 
 | ||||
| 	pi->acp_boot_level = 0xff; | ||||
| } | ||||
| 
 | ||||
| static void kv_update_current_ps(struct radeon_device *rdev, | ||||
| 				 struct radeon_ps *rps) | ||||
| { | ||||
| @ -1190,6 +1201,8 @@ int kv_dpm_enable(struct radeon_device *rdev) | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	kv_reset_acp_boot_level(rdev); | ||||
| 
 | ||||
| 	if (rdev->irq.installed && | ||||
| 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { | ||||
| 		ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); | ||||
| @ -1448,6 +1461,39 @@ static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate) | ||||
| 	return kv_enable_samu_dpm(rdev, !gate); | ||||
| } | ||||
| 
 | ||||
| static u8 kv_get_acp_boot_level(struct radeon_device *rdev) | ||||
| { | ||||
| 	u8 i; | ||||
| 	struct radeon_clock_voltage_dependency_table *table = | ||||
| 		&rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table; | ||||
| 
 | ||||
| 	for (i = 0; i < table->count; i++) { | ||||
| 		if (table->entries[i].clk >= 0) /* XXX */ | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (i >= table->count) | ||||
| 		i = table->count - 1; | ||||
| 
 | ||||
| 	return i; | ||||
| } | ||||
| 
 | ||||
| static void kv_update_acp_boot_level(struct radeon_device *rdev) | ||||
| { | ||||
| 	struct kv_power_info *pi = kv_get_pi(rdev); | ||||
| 	u8 acp_boot_level; | ||||
| 
 | ||||
| 	if (!pi->caps_stable_p_state) { | ||||
| 		acp_boot_level = kv_get_acp_boot_level(rdev); | ||||
| 		if (acp_boot_level != pi->acp_boot_level) { | ||||
| 			pi->acp_boot_level = acp_boot_level; | ||||
| 			kv_send_msg_to_smc_with_parameter(rdev, | ||||
| 							  PPSMC_MSG_ACPDPM_SetEnabledMask, | ||||
| 							  (1 << pi->acp_boot_level)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate) | ||||
| { | ||||
| 	struct kv_power_info *pi = kv_get_pi(rdev); | ||||
| @ -1459,7 +1505,7 @@ static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate) | ||||
| 		if (pi->caps_stable_p_state) | ||||
| 			pi->acp_boot_level = table->count - 1; | ||||
| 		else | ||||
| 			pi->acp_boot_level = 0; | ||||
| 			pi->acp_boot_level = kv_get_acp_boot_level(rdev); | ||||
| 
 | ||||
| 		ret = kv_copy_bytes_to_smc(rdev, | ||||
| 					   pi->dpm_table_start + | ||||
| @ -1769,6 +1815,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | ||||
| 				return ret; | ||||
| 			} | ||||
| #endif | ||||
| 			kv_update_acp_boot_level(rdev); | ||||
| 			kv_update_sclk_t(rdev); | ||||
| 			kv_enable_nb_dpm(rdev); | ||||
| 		} | ||||
| @ -1800,12 +1847,23 @@ void kv_dpm_setup_asic(struct radeon_device *rdev) | ||||
| 
 | ||||
| void kv_dpm_reset_asic(struct radeon_device *rdev) | ||||
| { | ||||
| 	kv_force_lowest_valid(rdev); | ||||
| 	kv_init_graphics_levels(rdev); | ||||
| 	kv_program_bootup_state(rdev); | ||||
| 	kv_upload_dpm_settings(rdev); | ||||
| 	kv_force_lowest_valid(rdev); | ||||
| 	kv_unforce_levels(rdev); | ||||
| 	struct kv_power_info *pi = kv_get_pi(rdev); | ||||
| 
 | ||||
| 	if (rdev->family == CHIP_KABINI) { | ||||
| 		kv_force_lowest_valid(rdev); | ||||
| 		kv_init_graphics_levels(rdev); | ||||
| 		kv_program_bootup_state(rdev); | ||||
| 		kv_upload_dpm_settings(rdev); | ||||
| 		kv_force_lowest_valid(rdev); | ||||
| 		kv_unforce_levels(rdev); | ||||
| 	} else { | ||||
| 		kv_init_graphics_levels(rdev); | ||||
| 		kv_program_bootup_state(rdev); | ||||
| 		kv_freeze_sclk_dpm(rdev, true); | ||||
| 		kv_upload_dpm_settings(rdev); | ||||
| 		kv_freeze_sclk_dpm(rdev, false); | ||||
| 		kv_set_enabled_level(rdev, pi->graphics_boot_level); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //XXX use sumo_dpm_display_configuration_changed
 | ||||
| @ -1870,7 +1928,10 @@ static int kv_force_dpm_highest(struct radeon_device *rdev) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | ||||
| 	if (rdev->family == CHIP_KABINI) | ||||
| 		return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | ||||
| 	else | ||||
| 		return kv_set_enabled_level(rdev, i); | ||||
| } | ||||
| 
 | ||||
| static int kv_force_dpm_lowest(struct radeon_device *rdev) | ||||
| @ -1887,7 +1948,10 @@ static int kv_force_dpm_lowest(struct radeon_device *rdev) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | ||||
| 	if (rdev->family == CHIP_KABINI) | ||||
| 		return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | ||||
| 	else | ||||
| 		return kv_set_enabled_level(rdev, i); | ||||
| } | ||||
| 
 | ||||
| static u8 kv_get_sleep_divider_id_from_clock(struct radeon_device *rdev, | ||||
| @ -2033,12 +2097,12 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, | ||||
| 		ps->dpmx_nb_ps_lo = 0x1; | ||||
| 		ps->dpmx_nb_ps_hi = 0x0; | ||||
| 	} else { | ||||
| 		ps->dpm0_pg_nb_ps_lo = 0x1; | ||||
| 		ps->dpm0_pg_nb_ps_lo = 0x3; | ||||
| 		ps->dpm0_pg_nb_ps_hi = 0x0; | ||||
| 		ps->dpmx_nb_ps_lo = 0x2; | ||||
| 		ps->dpmx_nb_ps_hi = 0x1; | ||||
| 		ps->dpmx_nb_ps_lo = 0x3; | ||||
| 		ps->dpmx_nb_ps_hi = 0x0; | ||||
| 
 | ||||
| 		if (pi->sys_info.nb_dpm_enable && pi->battery_state) { | ||||
| 		if (pi->sys_info.nb_dpm_enable) { | ||||
| 			force_high = (mclk >= pi->sys_info.nbp_memory_clock[3]) || | ||||
| 				pi->video_start || (rdev->pm.dpm.new_active_crtc_count >= 3) || | ||||
| 				pi->disable_nb_ps3_in_battery; | ||||
| @ -2204,6 +2268,15 @@ static void kv_enable_new_levels(struct radeon_device *rdev) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int kv_set_enabled_level(struct radeon_device *rdev, u32 level) | ||||
| { | ||||
| 	u32 new_mask = (1 << level); | ||||
| 
 | ||||
| 	return kv_send_msg_to_smc_with_parameter(rdev, | ||||
| 						 PPSMC_MSG_SCLKDPM_SetEnabledMask, | ||||
| 						 new_mask); | ||||
| } | ||||
| 
 | ||||
| static int kv_set_enabled_levels(struct radeon_device *rdev) | ||||
| { | ||||
| 	struct kv_power_info *pi = kv_get_pi(rdev); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user