Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4dcf9e6f authored by Eric Huang's avatar Eric Huang Committed by Alex Deucher
Browse files

drm/amd/powerplay: add uploading pptable and resetting powerplay support



Necessary for re-initializing dpm with new pptables at runtime.

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarEric Huang <JinHuiEric.Huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 76ad42c1
Loading
Loading
Loading
Loading
+58 −9
Original line number Diff line number Diff line
@@ -744,12 +744,12 @@ static int pp_dpm_get_pp_table(void *handle, char **table)

	PP_CHECK_HW(hwmgr);

	if (hwmgr->hwmgr_func->get_pp_table == NULL) {
		printk(KERN_INFO "%s was not implemented.\n", __func__);
		return 0;
	}
	if (!hwmgr->soft_pp_table)
		return -EINVAL;

	*table = (char *)hwmgr->soft_pp_table;

	return hwmgr->hwmgr_func->get_pp_table(hwmgr, table);
	return hwmgr->soft_pp_table_size;
}

static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
@@ -763,12 +763,23 @@ static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)

	PP_CHECK_HW(hwmgr);

	if (hwmgr->hwmgr_func->set_pp_table == NULL) {
		printk(KERN_INFO "%s was not implemented.\n", __func__);
		return 0;
	if (!hwmgr->hardcode_pp_table) {
		hwmgr->hardcode_pp_table =
				kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL);

		if (!hwmgr->hardcode_pp_table)
			return -ENOMEM;

		/* to avoid powerplay crash when hardcode pptable is empty */
		memcpy(hwmgr->hardcode_pp_table, hwmgr->soft_pp_table,
				hwmgr->soft_pp_table_size);
	}

	return hwmgr->hwmgr_func->set_pp_table(hwmgr, buf, size);
	memcpy(hwmgr->hardcode_pp_table, buf, size);

	hwmgr->soft_pp_table = hwmgr->hardcode_pp_table;

	return amd_powerplay_reset(handle);
}

static int pp_dpm_force_clock_level(void *handle,
@@ -993,6 +1004,44 @@ int amd_powerplay_fini(void *handle)
	return 0;
}

int amd_powerplay_reset(void *handle)
{
	struct pp_instance *instance = (struct pp_instance *)handle;
	struct pp_eventmgr *eventmgr;
	struct pem_event_data event_data = { {0} };
	int ret;

	if (instance == NULL)
		return -EINVAL;

	eventmgr = instance->eventmgr;
	if (!eventmgr || !eventmgr->pp_eventmgr_fini)
		return -EINVAL;

	eventmgr->pp_eventmgr_fini(eventmgr);

	ret = pp_sw_fini(handle);
	if (ret)
		return ret;

	kfree(instance->hwmgr->ps);

	ret = pp_sw_init(handle);
	if (ret)
		return ret;

	hw_init_power_state_table(instance->hwmgr);

	if (eventmgr == NULL || eventmgr->pp_eventmgr_init == NULL)
		return -EINVAL;

	ret = eventmgr->pp_eventmgr_init(eventmgr);
	if (ret)
		return ret;

	return pem_handle_event(eventmgr, AMD_PP_EVENT_COMPLETE_INIT, &event_data);
}

/* export this function to DAL */

int amd_powerplay_display_configuration_change(void *handle,
+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr)
		return -EINVAL;

	/* do hwmgr finish*/
	kfree(hwmgr->hardcode_pp_table);

	kfree(hwmgr->backend);

	kfree(hwmgr->start_thermal_controller.function_list);
+2 −0
Original line number Diff line number Diff line
@@ -360,6 +360,8 @@ int amd_powerplay_init(struct amd_pp_init *pp_init,

int amd_powerplay_fini(void *handle);

int amd_powerplay_reset(void *handle);

int amd_powerplay_display_configuration_change(void *handle,
		const struct amd_pp_display_configuration *input);

+1 −0
Original line number Diff line number Diff line
@@ -584,6 +584,7 @@ struct pp_hwmgr {
	struct pp_smumgr *smumgr;
	const void *soft_pp_table;
	uint32_t soft_pp_table_size;
	void *hardcode_pp_table;
	bool need_pp_table_upload;
	enum amd_dpm_forced_level dpm_level;
	bool block_hw_access;