diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
24 files changed, 254 insertions, 215 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ead851413c0a..16fcb56c232b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -700,6 +700,8 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	struct amdgpu_vm_bo_base *bo_base, *tmp;  	int r = 0; +	vm->bulk_moveable &= list_empty(&vm->evicted); +  	list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) {  		struct amdgpu_bo *bo = bo_base->bo; @@ -947,10 +949,6 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,  		if (r)  			return r; -		r = amdgpu_vm_clear_bo(adev, vm, pt, cursor.level, ats); -		if (r) -			goto error_free_pt; -  		if (vm->use_cpu_for_update) {  			r = amdgpu_bo_kmap(pt, NULL);  			if (r) @@ -963,6 +961,10 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,  		pt->parent = amdgpu_bo_ref(cursor.parent->base.bo);  		amdgpu_vm_bo_base_init(&entry->base, vm, pt); + +		r = amdgpu_vm_clear_bo(adev, vm, pt, cursor.level, ats); +		if (r) +			goto error_free_pt;  	}  	return 0; @@ -3033,13 +3035,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	if (r)  		goto error_unreserve; +	amdgpu_vm_bo_base_init(&vm->root.base, vm, root); +  	r = amdgpu_vm_clear_bo(adev, vm, root,  			       adev->vm_manager.root_level,  			       vm->pte_support_ats);  	if (r)  		goto error_unreserve; -	amdgpu_vm_bo_base_init(&vm->root.base, vm, root);  	amdgpu_bo_unreserve(vm->root.base.bo);  	if (pasid) { diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 5533f6e4f4a4..d0309e8c9d12 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -220,6 +220,7 @@ static const struct soc15_reg_golden golden_settings_gc_9_1_rv2[] =  static const struct soc15_reg_golden golden_settings_gc_9_x_common[] =  { +	SOC15_REG_GOLDEN_VALUE(GC, 0, mmCP_SD_CNTL, 0xffffffff, 0x000001ff),  	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_INDEX, 0xffffffff, 0x00000000),  	SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2544c382)  }; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 600259b4e291..2fe8397241ea 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -742,7 +742,7 @@ static int gmc_v9_0_allocate_vm_inv_eng(struct amdgpu_device *adev)  		}  		ring->vm_inv_eng = inv_eng - 1; -		change_bit(inv_eng - 1, (unsigned long *)(&vm_inv_engs[vmhub])); +		vm_inv_engs[vmhub] &= ~(1 << ring->vm_inv_eng);  		dev_info(adev->dev, "ring %s uses VM inv eng %u on hub %u\n",  			 ring->name, ring->vm_inv_eng, ring->funcs->vmhub); diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index c63de945c021..0487e3a4e9e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c @@ -500,9 +500,7 @@ static bool psp_v3_1_smu_reload_quirk(struct psp_context *psp)  	struct amdgpu_device *adev = psp->adev;  	uint32_t reg; -	reg = smnMP1_FIRMWARE_FLAGS | 0x03b00000; -	WREG32_SOC15(NBIO, 0, mmPCIE_INDEX2, reg); -	reg = RREG32_SOC15(NBIO, 0, mmPCIE_DATA2); +	reg = RREG32_PCIE(smnMP1_FIRMWARE_FLAGS | 0x03b00000);  	return (reg & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) ? true : false;  } diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 99ebcf29dcb0..ed89a101f73f 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -461,7 +461,6 @@ static int soc15_asic_reset(struct amdgpu_device *adev)  	switch (adev->asic_type) {  	case CHIP_VEGA10: -	case CHIP_VEGA20:  		soc15_asic_get_baco_capability(adev, &baco_reset);  		break;  	default: diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index 47243165a082..ae90a99909ef 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c @@ -323,57 +323,7 @@ static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,  		struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,  		struct queue_properties *q)  { -	uint64_t addr; -	struct cik_mqd *m; -	int retval; - -	retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd), -					mqd_mem_obj); - -	if (retval != 0) -		return -ENOMEM; - -	m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr; -	addr = (*mqd_mem_obj)->gpu_addr; - -	memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256)); - -	m->header = 0xC0310800; -	m->compute_pipelinestat_enable = 1; -	m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF; -	m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF; -	m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF; -	m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF; - -	m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE | -					PRELOAD_REQ; -	m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS | -				QUANTUM_DURATION(10); - -	m->cp_mqd_control             = MQD_CONTROL_PRIV_STATE_EN; -	m->cp_mqd_base_addr_lo        = lower_32_bits(addr); -	m->cp_mqd_base_addr_hi        = upper_32_bits(addr); - -	m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE; - -	/* -	 * Pipe Priority -	 * Identifies the pipe relative priority when this queue is connected -	 * to the pipeline. The pipe priority is against the GFX pipe and HP3D. -	 * In KFD we are using a fixed pipe priority set to CS_MEDIUM. -	 * 0 = CS_LOW (typically below GFX) -	 * 1 = CS_MEDIUM (typically between HP3D and GFX -	 * 2 = CS_HIGH (typically above HP3D) -	 */ -	m->cp_hqd_pipe_priority = 1; -	m->cp_hqd_queue_priority = 15; - -	*mqd = m; -	if (gart_addr) -		*gart_addr = addr; -	retval = mm->update_mqd(mm, m, q); - -	return retval; +	return init_mqd(mm, mqd, mqd_mem_obj, gart_addr, q);  }  static int update_mqd_hiq(struct mqd_manager *mm, void *mqd, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 2f26581b93ff..81127f7d6ed1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -886,6 +886,7 @@ static void emulated_link_detect(struct dc_link *link)  		return;  	} +	/* dc_sink_create returns a new reference */  	link->local_sink = sink;  	edid_status = dm_helpers_read_local_edid( @@ -952,6 +953,8 @@ static int dm_resume(void *handle)  		if (aconnector->fake_enable && aconnector->dc_link->local_sink)  			aconnector->fake_enable = false; +		if (aconnector->dc_sink) +			dc_sink_release(aconnector->dc_sink);  		aconnector->dc_sink = NULL;  		amdgpu_dm_update_connector_after_detect(aconnector);  		mutex_unlock(&aconnector->hpd_lock); @@ -1061,6 +1064,8 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)  	sink = aconnector->dc_link->local_sink; +	if (sink) +		dc_sink_retain(sink);  	/*  	 * Edid mgmt connector gets first update only in mode_valid hook and then @@ -1085,21 +1090,24 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)  				 * to it anymore after disconnect, so on next crtc to connector  				 * reshuffle by UMD we will get into unwanted dc_sink release  				 */ -				if (aconnector->dc_sink != aconnector->dc_em_sink) -					dc_sink_release(aconnector->dc_sink); +				dc_sink_release(aconnector->dc_sink);  			}  			aconnector->dc_sink = sink; +			dc_sink_retain(aconnector->dc_sink);  			amdgpu_dm_update_freesync_caps(connector,  					aconnector->edid);  		} else {  			amdgpu_dm_update_freesync_caps(connector, NULL); -			if (!aconnector->dc_sink) +			if (!aconnector->dc_sink) {  				aconnector->dc_sink = aconnector->dc_em_sink; -			else if (aconnector->dc_sink != aconnector->dc_em_sink)  				dc_sink_retain(aconnector->dc_sink); +			}  		}  		mutex_unlock(&dev->mode_config.mutex); + +		if (sink) +			dc_sink_release(sink);  		return;  	} @@ -1107,8 +1115,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)  	 * TODO: temporary guard to look for proper fix  	 * if this sink is MST sink, we should not do anything  	 */ -	if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) +	if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { +		dc_sink_release(sink);  		return; +	}  	if (aconnector->dc_sink == sink) {  		/* @@ -1117,6 +1127,8 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)  		 */  		DRM_DEBUG_DRIVER("DCHPD: connector_id=%d: dc_sink didn't change.\n",  				aconnector->connector_id); +		if (sink) +			dc_sink_release(sink);  		return;  	} @@ -1138,6 +1150,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)  			amdgpu_dm_update_freesync_caps(connector, NULL);  		aconnector->dc_sink = sink; +		dc_sink_retain(aconnector->dc_sink);  		if (sink->dc_edid.length == 0) {  			aconnector->edid = NULL;  			drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux); @@ -1158,11 +1171,15 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)  		amdgpu_dm_update_freesync_caps(connector, NULL);  		drm_connector_update_edid_property(connector, NULL);  		aconnector->num_modes = 0; +		dc_sink_release(aconnector->dc_sink);  		aconnector->dc_sink = NULL;  		aconnector->edid = NULL;  	}  	mutex_unlock(&dev->mode_config.mutex); + +	if (sink) +		dc_sink_release(sink);  }  static void handle_hpd_irq(void *param) @@ -2977,6 +2994,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,  			return stream;  	} else {  		sink = aconnector->dc_sink; +		dc_sink_retain(sink);  	}  	stream = dc_create_stream_for_sink(sink); @@ -3042,8 +3060,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,  	update_stream_signal(stream, sink);  finish: -	if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON) -		dc_sink_release(sink); +	dc_sink_release(sink);  	return stream;  } @@ -3301,6 +3318,14 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)  		dm->backlight_dev = NULL;  	}  #endif + +	if (aconnector->dc_em_sink) +		dc_sink_release(aconnector->dc_em_sink); +	aconnector->dc_em_sink = NULL; +	if (aconnector->dc_sink) +		dc_sink_release(aconnector->dc_sink); +	aconnector->dc_sink = NULL; +  	drm_dp_cec_unregister_connector(&aconnector->dm_dp_aux.aux);  	drm_connector_unregister(connector);  	drm_connector_cleanup(connector); @@ -3398,10 +3423,12 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)  		(edid->extensions + 1) * EDID_LENGTH,  		&init_params); -	if (aconnector->base.force == DRM_FORCE_ON) +	if (aconnector->base.force == DRM_FORCE_ON) {  		aconnector->dc_sink = aconnector->dc_link->local_sink ?  		aconnector->dc_link->local_sink :  		aconnector->dc_em_sink; +		dc_sink_retain(aconnector->dc_sink); +	}  }  static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector) @@ -5402,9 +5429,11 @@ static void get_freesync_config_for_crtc(  	struct amdgpu_dm_connector *aconnector =  			to_amdgpu_dm_connector(new_con_state->base.connector);  	struct drm_display_mode *mode = &new_crtc_state->base.mode; +	int vrefresh = drm_mode_vrefresh(mode);  	new_crtc_state->vrr_supported = new_con_state->freesync_capable && -		aconnector->min_vfreq <= drm_mode_vrefresh(mode); +					vrefresh >= aconnector->min_vfreq && +					vrefresh <= aconnector->max_vfreq;  	if (new_crtc_state->vrr_supported) {  		new_crtc_state->stream->ignore_msa_timing_param = true; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index f51d52eb52e6..c4ea3a91f17a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -191,6 +191,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)  			&init_params);  		dc_sink->priv = aconnector; +		/* dc_link_add_remote_sink returns a new reference */  		aconnector->dc_sink = dc_sink;  		if (aconnector->dc_sink) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 12d1842079ae..eb62d10bb65c 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1348,12 +1348,12 @@ void dcn_bw_update_from_pplib(struct dc *dc)  	struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};  	bool res; -	kernel_fpu_begin(); -  	/* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */  	res = dm_pp_get_clock_levels_by_type_with_voltage(  			ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks); +	kernel_fpu_begin(); +  	if (res)  		res = verify_clock_values(&fclks); @@ -1372,9 +1372,13 @@ void dcn_bw_update_from_pplib(struct dc *dc)  	} else  		BREAK_TO_DEBUGGER(); +	kernel_fpu_end(); +  	res = dm_pp_get_clock_levels_by_type_with_voltage(  			ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks); +	kernel_fpu_begin(); +  	if (res)  		res = verify_clock_values(&dcfclks); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 7f5a947ad31d..4eba3c4800b6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -794,6 +794,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)  		sink->link->dongle_max_pix_clk = sink_caps.max_hdmi_pixel_clock;  		sink->converter_disable_audio = converter_disable_audio; +		/* dc_sink_create returns a new reference */  		link->local_sink = sink;  		edid_status = dm_helpers_read_local_edid( @@ -2037,6 +2038,9 @@ static enum dc_status enable_link(  		break;  	} +	if (status == DC_OK) +		pipe_ctx->stream->link->link_status.link_active = true; +  	return status;  } @@ -2060,6 +2064,14 @@ static void disable_link(struct dc_link *link, enum signal_type signal)  			dp_disable_link_phy_mst(link, signal);  	} else  		link->link_enc->funcs->disable_output(link->link_enc, signal); + +	if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { +		/* MST disable link only when no stream use the link */ +		if (link->mst_stream_alloc_table.stream_count <= 0) +			link->link_status.link_active = false; +	} else { +		link->link_status.link_active = false; +	}  }  static bool dp_active_dongle_validate_timing( @@ -2623,8 +2635,6 @@ void core_link_enable_stream(  			}  		} -		stream->link->link_status.link_active = true; -  		core_dc->hwss.enable_audio_stream(pipe_ctx);  		/* turn off otg test pattern if enable */ @@ -2659,8 +2669,6 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)  	core_dc->hwss.disable_stream(pipe_ctx, option);  	disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); - -	pipe_ctx->stream->link->link_status.link_active = false;  }  void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 94a84bc57c7a..bfd27f10879e 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -724,7 +724,7 @@ static void build_vrr_infopacket_v1(enum signal_type signal,  static void build_vrr_infopacket_v2(enum signal_type signal,  		const struct mod_vrr_params *vrr, -		const enum color_transfer_func *app_tf, +		enum color_transfer_func app_tf,  		struct dc_info_packet *infopacket)  {  	unsigned int payload_size = 0; @@ -732,8 +732,7 @@ static void build_vrr_infopacket_v2(enum signal_type signal,  	build_vrr_infopacket_header_v2(signal, infopacket, &payload_size);  	build_vrr_infopacket_data(vrr, infopacket); -	if (app_tf != NULL) -		build_vrr_infopacket_fs2_data(*app_tf, infopacket); +	build_vrr_infopacket_fs2_data(app_tf, infopacket);  	build_vrr_infopacket_checksum(&payload_size, infopacket); @@ -757,7 +756,7 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,  		const struct dc_stream_state *stream,  		const struct mod_vrr_params *vrr,  		enum vrr_packet_type packet_type, -		const enum color_transfer_func *app_tf, +		enum color_transfer_func app_tf,  		struct dc_info_packet *infopacket)  {  	/* SPD info packet for FreeSync diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h index 4222e403b151..dcef85994c45 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h @@ -145,7 +145,7 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,  		const struct dc_stream_state *stream,  		const struct mod_vrr_params *vrr,  		enum vrr_packet_type packet_type, -		const enum color_transfer_func *app_tf, +		enum color_transfer_func app_tf,  		struct dc_info_packet *infopacket);  void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c index ce177d7f04cb..6bf48934fdc4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_psm.c @@ -277,8 +277,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set  	if (!skip_display_settings)  		phm_notify_smc_display_config_after_ps_adjustment(hwmgr); -	if ((hwmgr->request_dpm_level != hwmgr->dpm_level) && -	    !phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level)) +	if (!phm_force_dpm_levels(hwmgr, hwmgr->request_dpm_level))  		hwmgr->dpm_level = hwmgr->request_dpm_level;  	if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c index 4588bddf8b33..615cf2c09e54 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c @@ -489,15 +489,16 @@ int pp_atomfwctrl_get_gpio_information(struct pp_hwmgr *hwmgr,  }  int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, -					       uint8_t id, uint32_t *frequency) +					       uint8_t clk_id, uint8_t syspll_id, +					       uint32_t *frequency)  {  	struct amdgpu_device *adev = hwmgr->adev;  	struct atom_get_smu_clock_info_parameters_v3_1   parameters;  	struct atom_get_smu_clock_info_output_parameters_v3_1 *output;  	uint32_t ix; -	parameters.clk_id = id; -	parameters.syspll_id = 0; +	parameters.clk_id = clk_id; +	parameters.syspll_id = syspll_id;  	parameters.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ;  	parameters.dfsdid = 0; @@ -530,20 +531,23 @@ static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr,  	boot_values->ulSocClk   = 0;  	boot_values->ulDCEFClk   = 0; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, SMU11_SYSPLL0_ID, &frequency))  		boot_values->ulSocClk   = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, SMU11_SYSPLL0_ID, &frequency))  		boot_values->ulDCEFClk  = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, SMU11_SYSPLL0_ID, &frequency))  		boot_values->ulEClk     = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, SMU11_SYSPLL0_ID, &frequency))  		boot_values->ulVClk     = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, SMU11_SYSPLL0_ID, &frequency))  		boot_values->ulDClk     = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL1_0_FCLK_ID, SMU11_SYSPLL1_2_ID, &frequency)) +		boot_values->ulFClk     = frequency;  }  static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr, @@ -563,19 +567,19 @@ static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr,  	boot_values->ulSocClk   = 0;  	boot_values->ulDCEFClk   = 0; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, 0, &frequency))  		boot_values->ulSocClk   = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, 0, &frequency))  		boot_values->ulDCEFClk  = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, 0, &frequency))  		boot_values->ulEClk     = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, 0, &frequency))  		boot_values->ulVClk     = frequency; -	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, &frequency)) +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, 0, &frequency))  		boot_values->ulDClk     = frequency;  } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h index fe9e8ceef50e..b7e2651b570b 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h @@ -139,6 +139,7 @@ struct pp_atomfwctrl_bios_boot_up_values {  	uint32_t   ulEClk;  	uint32_t   ulVClk;  	uint32_t   ulDClk; +	uint32_t   ulFClk;  	uint16_t   usVddc;  	uint16_t   usVddci;  	uint16_t   usMvddc; @@ -236,7 +237,8 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,  int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,  			struct pp_atomfwctrl_smc_dpm_parameters *param);  int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, -					uint8_t id, uint32_t *frequency); +					uint8_t clk_id, uint8_t syspll_id, +					uint32_t *frequency);  #endif diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 48187acac59e..83d3d935f3ac 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -3491,14 +3491,14 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr, u32 *query)  	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogStart);  	cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, -							ixSMU_PM_STATUS_94, 0); +							ixSMU_PM_STATUS_95, 0);  	for (i = 0; i < 10; i++) { -		mdelay(1); +		mdelay(500);  		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PmStatusLogSample);  		tmp = cgs_read_ind_register(hwmgr->device,  						CGS_IND_REG__SMC, -						ixSMU_PM_STATUS_94); +						ixSMU_PM_STATUS_95);  		if (tmp != 0)  			break;  	} diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 5479125ff4f6..5c4f701939ea 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -2575,10 +2575,10 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)  		data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk;  		data->vbios_boot_state.mem_clock = boot_up_values.ulUClk;  		pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, -				SMU9_SYSPLL0_SOCCLK_ID, &boot_up_values.ulSocClk); +				SMU9_SYSPLL0_SOCCLK_ID, 0, &boot_up_values.ulSocClk);  		pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, -				SMU9_SYSPLL0_DCEFCLK_ID, &boot_up_values.ulDCEFClk); +				SMU9_SYSPLL0_DCEFCLK_ID, 0, &boot_up_values.ulDCEFClk);  		data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;  		data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk; @@ -4407,9 +4407,9 @@ static int vega10_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe  		return ret;  	features_to_disable = -		(features_enabled ^ new_ppfeature_masks) & features_enabled; +		features_enabled & ~new_ppfeature_masks;  	features_to_enable = -		(features_enabled ^ new_ppfeature_masks) ^ features_to_disable; +		~features_enabled & new_ppfeature_masks;  	pr_debug("features_to_disable 0x%llx\n", features_to_disable);  	pr_debug("features_to_enable 0x%llx\n", features_to_enable); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 6c8e78611c03..bdb48e94eff6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -2009,9 +2009,9 @@ static int vega12_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe  		return ret;  	features_to_disable = -		(features_enabled ^ new_ppfeature_masks) & features_enabled; +		features_enabled & ~new_ppfeature_masks;  	features_to_enable = -		(features_enabled ^ new_ppfeature_masks) ^ features_to_disable; +		~features_enabled & new_ppfeature_masks;  	pr_debug("features_to_disable 0x%llx\n", features_to_disable);  	pr_debug("features_to_enable 0x%llx\n", features_to_enable); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index aad79affb081..9aa7bec1b5fe 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -463,9 +463,9 @@ static int vega20_setup_asic_task(struct pp_hwmgr *hwmgr)  static void vega20_init_dpm_state(struct vega20_dpm_state *dpm_state)  {  	dpm_state->soft_min_level = 0x0; -	dpm_state->soft_max_level = 0xffff; +	dpm_state->soft_max_level = VG20_CLOCK_MAX_DEFAULT;  	dpm_state->hard_min_level = 0x0; -	dpm_state->hard_max_level = 0xffff; +	dpm_state->hard_max_level = VG20_CLOCK_MAX_DEFAULT;  }  static int vega20_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, @@ -711,8 +711,10 @@ static int vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)  		PP_ASSERT_WITH_CODE(!ret,  				"[SetupDefaultDpmTable] failed to get fclk dpm levels!",  				return ret); -	} else -		dpm_table->count = 0; +	} else { +		dpm_table->count = 1; +		dpm_table->dpm_levels[0].value = data->vbios_boot_state.fclock / 100; +	}  	vega20_init_dpm_state(&(dpm_table->dpm_state));  	/* save a copy of the default DPM table */ @@ -754,6 +756,7 @@ static int vega20_init_smc_table(struct pp_hwmgr *hwmgr)  	data->vbios_boot_state.eclock = boot_up_values.ulEClk;  	data->vbios_boot_state.vclock = boot_up_values.ulVClk;  	data->vbios_boot_state.dclock = boot_up_values.ulDClk; +	data->vbios_boot_state.fclock = boot_up_values.ulFClk;  	data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID;  	smum_send_msg_to_smc_with_parameter(hwmgr, @@ -780,6 +783,8 @@ static int vega20_init_smc_table(struct pp_hwmgr *hwmgr)  static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)  {  	struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); +	struct vega20_hwmgr *data = +			(struct vega20_hwmgr *)(hwmgr->backend);  	uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;  	int ret; @@ -816,6 +821,10 @@ static int vega20_override_pcie_parameters(struct pp_hwmgr *hwmgr)  		"[OverridePcieParameters] Attempt to override pcie params failed!",  		return ret); +	data->pcie_parameters_override = 1; +	data->pcie_gen_level1 = pcie_gen; +	data->pcie_width_level1 = pcie_width; +  	return 0;  } @@ -979,6 +988,8 @@ static int vega20_od8_set_feature_capabilities(  	}  	if (data->smu_features[GNLD_DPM_UCLK].enabled) { +		pptable_information->od_settings_min[OD8_SETTING_UCLK_FMAX] = +			data->dpm_table.mem_table.dpm_levels[data->dpm_table.mem_table.count - 2].value;  		if (pptable_information->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_UCLK_MAX] &&  		    pptable_information->od_settings_min[OD8_SETTING_UCLK_FMAX] > 0 &&  		    pptable_information->od_settings_max[OD8_SETTING_UCLK_FMAX] > 0 && @@ -2314,32 +2325,8 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr)  static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr)  { -	struct vega20_hwmgr *data = -			(struct vega20_hwmgr *)(hwmgr->backend); -	uint32_t soft_min_level, soft_max_level;  	int ret = 0; -	soft_min_level = vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); -	soft_max_level = vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table)); -	data->dpm_table.gfx_table.dpm_state.soft_min_level = -		data->dpm_table.gfx_table.dpm_levels[soft_min_level].value; -	data->dpm_table.gfx_table.dpm_state.soft_max_level = -		data->dpm_table.gfx_table.dpm_levels[soft_max_level].value; - -	soft_min_level = vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table)); -	soft_max_level = vega20_find_highest_dpm_level(&(data->dpm_table.mem_table)); -	data->dpm_table.mem_table.dpm_state.soft_min_level = -		data->dpm_table.mem_table.dpm_levels[soft_min_level].value; -	data->dpm_table.mem_table.dpm_state.soft_max_level = -		data->dpm_table.mem_table.dpm_levels[soft_max_level].value; - -	soft_min_level = vega20_find_lowest_dpm_level(&(data->dpm_table.soc_table)); -	soft_max_level = vega20_find_highest_dpm_level(&(data->dpm_table.soc_table)); -	data->dpm_table.soc_table.dpm_state.soft_min_level = -		data->dpm_table.soc_table.dpm_levels[soft_min_level].value; -	data->dpm_table.soc_table.dpm_state.soft_max_level = -		data->dpm_table.soc_table.dpm_levels[soft_max_level].value; -  	ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);  	PP_ASSERT_WITH_CODE(!ret,  			"Failed to upload DPM Bootup Levels!", @@ -2641,9 +2628,8 @@ static int vega20_get_sclks(struct pp_hwmgr *hwmgr,  	struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table);  	int i, count; -	PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_GFXCLK].enabled, -		"[GetSclks]: gfxclk dpm not enabled!\n", -		return -EPERM); +	if (!data->smu_features[GNLD_DPM_GFXCLK].enabled) +		return -1;  	count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;  	clocks->num_levels = count; @@ -2670,9 +2656,8 @@ static int vega20_get_memclocks(struct pp_hwmgr *hwmgr,  	struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.mem_table);  	int i, count; -	PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_UCLK].enabled, -		"[GetMclks]: uclk dpm not enabled!\n", -		return -EPERM); +	if (!data->smu_features[GNLD_DPM_UCLK].enabled) +		return -1;  	count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;  	clocks->num_levels = data->mclk_latency_table.count = count; @@ -2696,9 +2681,8 @@ static int vega20_get_dcefclocks(struct pp_hwmgr *hwmgr,  	struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.dcef_table);  	int i, count; -	PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_DCEFCLK].enabled, -		"[GetDcfclocks]: dcefclk dpm not enabled!\n", -		return -EPERM); +	if (!data->smu_features[GNLD_DPM_DCEFCLK].enabled) +		return -1;  	count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;  	clocks->num_levels = count; @@ -2719,9 +2703,8 @@ static int vega20_get_socclocks(struct pp_hwmgr *hwmgr,  	struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.soc_table);  	int i, count; -	PP_ASSERT_WITH_CODE(data->smu_features[GNLD_DPM_SOCCLK].enabled, -		"[GetSocclks]: socclk dpm not enabled!\n", -		return -EPERM); +	if (!data->smu_features[GNLD_DPM_SOCCLK].enabled) +		return -1;  	count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;  	clocks->num_levels = count; @@ -2799,7 +2782,6 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,  			data->od8_settings.od8_settings_array;  	OverDriveTable_t *od_table =  			&(data->smc_state_table.overdrive_table); -	struct pp_clock_levels_with_latency clocks;  	int32_t input_index, input_clk, input_vol, i;  	int od8_id;  	int ret; @@ -2858,11 +2840,6 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,  			return -EOPNOTSUPP;  		} -		ret = vega20_get_memclocks(hwmgr, &clocks); -		PP_ASSERT_WITH_CODE(!ret, -				"Attempt to get memory clk levels failed!", -				return ret); -  		for (i = 0; i < size; i += 2) {  			if (i + 2 > size) {  				pr_info("invalid number of input parameters %d\n", @@ -2879,11 +2856,11 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,  				return -EINVAL;  			} -			if (input_clk < clocks.data[0].clocks_in_khz / 1000 || +			if (input_clk < od8_settings[OD8_SETTING_UCLK_FMAX].min_value ||  			    input_clk > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) {  				pr_info("clock freq %d is not within allowed range [%d - %d]\n",  					input_clk, -					clocks.data[0].clocks_in_khz / 1000, +					od8_settings[OD8_SETTING_UCLK_FMAX].min_value,  					od8_settings[OD8_SETTING_UCLK_FMAX].max_value);  				return -EINVAL;  			} @@ -3088,9 +3065,9 @@ static int vega20_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe  		return ret;  	features_to_disable = -		(features_enabled ^ new_ppfeature_masks) & features_enabled; +		features_enabled & ~new_ppfeature_masks;  	features_to_enable = -		(features_enabled ^ new_ppfeature_masks) ^ features_to_disable; +		~features_enabled & new_ppfeature_masks;  	pr_debug("features_to_disable 0x%llx\n", features_to_disable);  	pr_debug("features_to_enable 0x%llx\n", features_to_enable); @@ -3128,7 +3105,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,  			&(data->dpm_table.fclk_table);  	int i, now, size = 0;  	int ret = 0; -	uint32_t gen_speed, lane_width; +	uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;  	switch (type) {  	case PP_SCLK: @@ -3137,10 +3114,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,  				"Attempt to get current gfx clk Failed!",  				return ret); -		ret = vega20_get_sclks(hwmgr, &clocks); -		PP_ASSERT_WITH_CODE(!ret, -				"Attempt to get gfx clk levels Failed!", -				return ret); +		if (vega20_get_sclks(hwmgr, &clocks)) { +			size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", +				now / 100); +			break; +		}  		for (i = 0; i < clocks.num_levels; i++)  			size += sprintf(buf + size, "%d: %uMhz %s\n", @@ -3154,10 +3132,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,  				"Attempt to get current mclk freq Failed!",  				return ret); -		ret = vega20_get_memclocks(hwmgr, &clocks); -		PP_ASSERT_WITH_CODE(!ret, -				"Attempt to get memory clk levels Failed!", -				return ret); +		if (vega20_get_memclocks(hwmgr, &clocks)) { +			size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", +				now / 100); +			break; +		}  		for (i = 0; i < clocks.num_levels; i++)  			size += sprintf(buf + size, "%d: %uMhz %s\n", @@ -3171,10 +3150,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,  				"Attempt to get current socclk freq Failed!",  				return ret); -		ret = vega20_get_socclocks(hwmgr, &clocks); -		PP_ASSERT_WITH_CODE(!ret, -				"Attempt to get soc clk levels Failed!", -				return ret); +		if (vega20_get_socclocks(hwmgr, &clocks)) { +			size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", +				now / 100); +			break; +		}  		for (i = 0; i < clocks.num_levels; i++)  			size += sprintf(buf + size, "%d: %uMhz %s\n", @@ -3200,10 +3180,11 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,  				"Attempt to get current dcefclk freq Failed!",  				return ret); -		ret = vega20_get_dcefclocks(hwmgr, &clocks); -		PP_ASSERT_WITH_CODE(!ret, -				"Attempt to get dcefclk levels Failed!", -				return ret); +		if (vega20_get_dcefclocks(hwmgr, &clocks)) { +			size += sprintf(buf + size, "0: %uMhz * (DPM disabled)\n", +				now / 100); +			break; +		}  		for (i = 0; i < clocks.num_levels; i++)  			size += sprintf(buf + size, "%d: %uMhz %s\n", @@ -3212,28 +3193,36 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,  		break;  	case PP_PCIE: -		gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & +		current_gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &  			     PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)  			    >> PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; -		lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) & +		current_lane_width = (RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL) &  			      PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK)  			    >> PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT; -		for (i = 0; i < NUM_LINK_LEVELS; i++) +		for (i = 0; i < NUM_LINK_LEVELS; i++) { +			if (i == 1 && data->pcie_parameters_override) { +				gen_speed = data->pcie_gen_level1; +				lane_width = data->pcie_width_level1; +			} else { +				gen_speed = pptable->PcieGenSpeed[i]; +				lane_width = pptable->PcieLaneCount[i]; +			}  			size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, -					(pptable->PcieGenSpeed[i] == 0) ? "2.5GT/s," : -					(pptable->PcieGenSpeed[i] == 1) ? "5.0GT/s," : -					(pptable->PcieGenSpeed[i] == 2) ? "8.0GT/s," : -					(pptable->PcieGenSpeed[i] == 3) ? "16.0GT/s," : "", -					(pptable->PcieLaneCount[i] == 1) ? "x1" : -					(pptable->PcieLaneCount[i] == 2) ? "x2" : -					(pptable->PcieLaneCount[i] == 3) ? "x4" : -					(pptable->PcieLaneCount[i] == 4) ? "x8" : -					(pptable->PcieLaneCount[i] == 5) ? "x12" : -					(pptable->PcieLaneCount[i] == 6) ? "x16" : "", +					(gen_speed == 0) ? "2.5GT/s," : +					(gen_speed == 1) ? "5.0GT/s," : +					(gen_speed == 2) ? "8.0GT/s," : +					(gen_speed == 3) ? "16.0GT/s," : "", +					(lane_width == 1) ? "x1" : +					(lane_width == 2) ? "x2" : +					(lane_width == 3) ? "x4" : +					(lane_width == 4) ? "x8" : +					(lane_width == 5) ? "x12" : +					(lane_width == 6) ? "x16" : "",  					pptable->LclkFreq[i], -					(gen_speed == pptable->PcieGenSpeed[i]) && -					(lane_width == pptable->PcieLaneCount[i]) ? +					(current_gen_speed == gen_speed) && +					(current_lane_width == lane_width) ?  					"*" : ""); +		}  		break;  	case OD_SCLK: @@ -3288,13 +3277,8 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,  		}  		if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) { -			ret = vega20_get_memclocks(hwmgr, &clocks); -			PP_ASSERT_WITH_CODE(!ret, -					"Fail to get memory clk levels!", -					return ret); -  			size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n", -				clocks.data[0].clocks_in_khz / 1000, +				od8_settings[OD8_SETTING_UCLK_FMAX].min_value,  				od8_settings[OD8_SETTING_UCLK_FMAX].max_value);  		} @@ -3356,6 +3340,31 @@ static int vega20_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr,  	return ret;  } +static int vega20_set_fclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr) +{ +	struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); +	struct vega20_single_dpm_table *dpm_table = &(data->dpm_table.fclk_table); +	int ret = 0; + +	if (data->smu_features[GNLD_DPM_FCLK].enabled) { +		PP_ASSERT_WITH_CODE(dpm_table->count > 0, +				"[SetFclkToHightestDpmLevel] Dpm table has no entry!", +				return -EINVAL); +		PP_ASSERT_WITH_CODE(dpm_table->count <= NUM_FCLK_DPM_LEVELS, +				"[SetFclkToHightestDpmLevel] Dpm table has too many entries!", +				return -EINVAL); + +		dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +		PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr, +				PPSMC_MSG_SetSoftMinByFreq, +				(PPCLK_FCLK << 16 ) | dpm_table->dpm_state.soft_min_level)), +				"[SetFclkToHightestDpmLevel] Set soft min fclk failed!", +				return ret); +	} + +	return ret; +} +  static int vega20_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr)  {  	struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); @@ -3366,8 +3375,10 @@ static int vega20_pre_display_configuration_changed_task(struct pp_hwmgr *hwmgr)  	ret = vega20_set_uclk_to_highest_dpm_level(hwmgr,  			&data->dpm_table.mem_table); +	if (ret) +		return ret; -	return ret; +	return vega20_set_fclk_to_highest_dpm_level(hwmgr);  }  static int vega20_display_configuration_changed_task(struct pp_hwmgr *hwmgr) @@ -3461,9 +3472,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)  	/* gfxclk */  	dpm_table = &(data->dpm_table.gfx_table);  	dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;  	dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;  	if (PP_CAP(PHM_PlatformCaps_UMDPState)) {  		if (VEGA20_UMD_PSTATE_GFXCLK_LEVEL < dpm_table->count) { @@ -3485,9 +3496,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)  	/* memclk */  	dpm_table = &(data->dpm_table.mem_table);  	dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;  	dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;  	if (PP_CAP(PHM_PlatformCaps_UMDPState)) {  		if (VEGA20_UMD_PSTATE_MCLK_LEVEL < dpm_table->count) { @@ -3526,12 +3537,21 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)  	if (hwmgr->display_config->nb_pstate_switch_disable)  		dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	/* fclk */ +	dpm_table = &(data->dpm_table.fclk_table); +	dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; +	dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT; +	dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; +	dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT; +	if (hwmgr->display_config->nb_pstate_switch_disable) +		dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +  	/* vclk */  	dpm_table = &(data->dpm_table.vclk_table);  	dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;  	dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;  	if (PP_CAP(PHM_PlatformCaps_UMDPState)) {  		if (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) { @@ -3548,9 +3568,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)  	/* dclk */  	dpm_table = &(data->dpm_table.dclk_table);  	dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;  	dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;  	if (PP_CAP(PHM_PlatformCaps_UMDPState)) {  		if (VEGA20_UMD_PSTATE_UVDCLK_LEVEL < dpm_table->count) { @@ -3567,9 +3587,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)  	/* socclk */  	dpm_table = &(data->dpm_table.soc_table);  	dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;  	dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;  	if (PP_CAP(PHM_PlatformCaps_UMDPState)) {  		if (VEGA20_UMD_PSTATE_SOCCLK_LEVEL < dpm_table->count) { @@ -3586,9 +3606,9 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr)  	/* eclk */  	dpm_table = &(data->dpm_table.eclk_table);  	dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.soft_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT;  	dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; -	dpm_table->dpm_state.hard_max_level = dpm_table->dpm_levels[dpm_table->count - 1].value; +	dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT;  	if (PP_CAP(PHM_PlatformCaps_UMDPState)) {  		if (VEGA20_UMD_PSTATE_VCEMCLK_LEVEL < dpm_table->count) { diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h index 37f5f5e657da..a5bc758ae097 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h @@ -42,6 +42,8 @@  #define AVFS_CURVE 0  #define OD8_HOTCURVE_TEMPERATURE 85 +#define VG20_CLOCK_MAX_DEFAULT 0xFFFF +  typedef uint32_t PP_Clock;  enum { @@ -219,6 +221,7 @@ struct vega20_vbios_boot_state {  	uint32_t    eclock;  	uint32_t    dclock;  	uint32_t    vclock; +	uint32_t    fclock;  };  #define DPMTABLE_OD_UPDATE_SCLK     0x00000001 @@ -523,6 +526,10 @@ struct vega20_hwmgr {  	unsigned long                  metrics_time;  	SmuMetrics_t                   metrics_table; + +	bool                           pcie_parameters_override; +	uint32_t                       pcie_gen_level1; +	uint32_t                       pcie_width_level1;  };  #define VEGA20_DPM2_NEAR_TDP_DEC                      10 diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c index 97f8a1a970c3..7a7f15d0c53a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c @@ -32,6 +32,8 @@  #include "cgs_common.h"  #include "vega20_pptable.h" +#define VEGA20_FAN_TARGET_TEMPERATURE_OVERRIDE 105 +  static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,  		enum phm_platform_caps cap)  { @@ -798,6 +800,17 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable  	return 0;  } +static int override_powerplay_table_fantargettemperature(struct pp_hwmgr *hwmgr) +{ +	struct phm_ppt_v3_information *pptable_information = +		(struct phm_ppt_v3_information *)hwmgr->pptable; +	PPTable_t *ppsmc_pptable = (PPTable_t *)(pptable_information->smc_pptable); + +	ppsmc_pptable->FanTargetTemperature = VEGA20_FAN_TARGET_TEMPERATURE_OVERRIDE; + +	return 0; +} +  #define VEGA20_ENGINECLOCK_HARDMAX 198000  static int init_powerplay_table_information(  		struct pp_hwmgr *hwmgr, @@ -887,6 +900,10 @@ static int init_powerplay_table_information(  	result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable)); +	if (result) +		return result; + +	result = override_powerplay_table_fantargettemperature(hwmgr);  	return result;  } diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index 52abca065764..2d4cfe14f72e 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -2330,6 +2330,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member)  		case DRAM_LOG_BUFF_SIZE:  			return offsetof(SMU74_SoftRegisters, DRAM_LOG_BUFF_SIZE);  		} +		break;  	case SMU_Discrete_DpmTable:  		switch (member) {  		case UvdBootLevel: @@ -2339,6 +2340,7 @@ static uint32_t polaris10_get_offsetof(uint32_t type, uint32_t member)  		case LowSclkInterruptThreshold:  			return offsetof(SMU74_Discrete_DpmTable, LowSclkInterruptThreshold);  		} +		break;  	}  	pr_warn("can't get the offset of type %x member %x\n", type, member);  	return 0; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c index 079fc8e8f709..742b3dc1f6cb 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c @@ -40,10 +40,8 @@ bool smu9_is_smc_ram_running(struct pp_hwmgr *hwmgr)  	struct amdgpu_device *adev = hwmgr->adev;  	uint32_t mp1_fw_flags; -	WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2, -			(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); - -	mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2); +	mp1_fw_flags = RREG32_PCIE(MP1_Public | +				   (smnMP1_FIRMWARE_FLAGS & 0xffffffff));  	if (mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK)  		return true; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c index b7ff7d4d6f44..ba00744c3413 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c @@ -49,10 +49,8 @@ static bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)  	struct amdgpu_device *adev = hwmgr->adev;  	uint32_t mp1_fw_flags; -	WREG32_SOC15(NBIF, 0, mmPCIE_INDEX2, -		     (MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff))); - -	mp1_fw_flags = RREG32_SOC15(NBIF, 0, mmPCIE_DATA2); +	mp1_fw_flags = RREG32_PCIE(MP1_Public | +				   (smnMP1_FIRMWARE_FLAGS & 0xffffffff));  	if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>  	    MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) | 
