Commit df1e6394 authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher

drm/amd/powerplay: delete eventmgr layer in poweprlay

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent cd00a424
......@@ -383,8 +383,8 @@ struct amdgpu_dpm_funcs {
#define amdgpu_dpm_set_mclk_od(adev, value) \
((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value))
#define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \
(adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output))
#define amdgpu_dpm_dispatch_task(adev, task_id, input, output) \
((adev)->powerplay.pp_funcs->dispatch_tasks)((adev)->powerplay.pp_handle, (task_id), (input), (output))
#define amgdpu_dpm_check_state_equal(adev, cps, rps, equal) (adev)->pm.funcs->check_state_equal((adev), (cps),(rps),(equal))
......
......@@ -119,7 +119,7 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev,
}
if (adev->pp_enabled) {
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_ENABLE_USER_STATE, &state, NULL);
} else {
mutex_lock(&adev->pm.mutex);
adev->pm.dpm.user_state = state;
......@@ -330,7 +330,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,
if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&
state != POWER_STATE_TYPE_DEFAULT) {
amdgpu_dpm_dispatch_task(adev,
AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL);
AMD_PP_TASK_ENABLE_USER_STATE, &state, NULL);
adev->pp_force_state_enabled = true;
}
}
......@@ -559,7 +559,7 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev,
if (adev->pp_enabled) {
amdgpu_dpm_set_sclk_od(adev, (uint32_t)value);
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_READJUST_POWER_STATE, NULL, NULL);
amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL, NULL);
} else if (adev->pm.funcs->set_sclk_od) {
adev->pm.funcs->set_sclk_od(adev, (uint32_t)value);
adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
......@@ -605,7 +605,7 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,
if (adev->pp_enabled) {
amdgpu_dpm_set_mclk_od(adev, (uint32_t)value);
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_READJUST_POWER_STATE, NULL, NULL);
amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL, NULL);
} else if (adev->pm.funcs->set_mclk_od) {
adev->pm.funcs->set_mclk_od(adev, (uint32_t)value);
adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps;
......@@ -1496,7 +1496,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
}
if (adev->pp_enabled) {
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL);
amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL, NULL);
} else {
mutex_lock(&adev->pm.mutex);
adev->pm.dpm.new_active_crtcs = 0;
......
......@@ -128,7 +128,7 @@ static int amdgpu_pp_late_init(void *handle)
if (adev->pp_enabled && adev->pm.dpm_enabled) {
amdgpu_pm_sysfs_init(adev);
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);
amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_COMPLETE_INIT, NULL, NULL);
}
return ret;
......
......@@ -4,12 +4,11 @@ subdir-ccflags-y += \
-I$(FULL_AMD_PATH)/include/asic_reg \
-I$(FULL_AMD_PATH)/include \
-I$(FULL_AMD_PATH)/powerplay/smumgr\
-I$(FULL_AMD_PATH)/powerplay/hwmgr \
-I$(FULL_AMD_PATH)/powerplay/eventmgr
-I$(FULL_AMD_PATH)/powerplay/hwmgr
AMD_PP_PATH = ../powerplay
PP_LIBS = smumgr hwmgr eventmgr
PP_LIBS = smumgr hwmgr
AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix $(FULL_AMD_PATH)/powerplay/,$(PP_LIBS)))
......
......@@ -29,7 +29,6 @@
#include "amd_powerplay.h"
#include "pp_instance.h"
#include "power_state.h"
#include "eventmanager.h"
static inline int pp_check(struct pp_instance *handle)
......@@ -43,8 +42,7 @@ static inline int pp_check(struct pp_instance *handle)
if (handle->pm_en == 0)
return PP_DPM_DISABLED;
if (handle->hwmgr == NULL || handle->hwmgr->hwmgr_func == NULL
|| handle->eventmgr == NULL)
if (handle->hwmgr == NULL || handle->hwmgr->hwmgr_func == NULL)
return PP_DPM_DISABLED;
return 0;
......@@ -69,14 +67,6 @@ static int pp_early_init(void *handle)
return PP_DPM_DISABLED;
}
ret = eventmgr_early_init(pp_handle);
if (ret) {
kfree(pp_handle->hwmgr);
pp_handle->hwmgr = NULL;
pp_handle->pm_en = 0;
return PP_DPM_DISABLED;
}
return 0;
}
......@@ -122,7 +112,6 @@ static int pp_sw_fini(void *handle)
static int pp_hw_init(void *handle)
{
struct pp_smumgr *smumgr;
struct pp_eventmgr *eventmgr;
int ret = 0;
struct pp_instance *pp_handle = (struct pp_instance *)handle;
......@@ -146,38 +135,23 @@ static int pp_hw_init(void *handle)
ret = hwmgr_hw_init(pp_handle);
if (ret)
goto err;
eventmgr = pp_handle->eventmgr;
if (eventmgr->pp_eventmgr_init == NULL ||
eventmgr->pp_eventmgr_init(eventmgr))
goto err;
return 0;
err:
pp_handle->pm_en = 0;
kfree(pp_handle->eventmgr);
kfree(pp_handle->hwmgr);
pp_handle->hwmgr = NULL;
pp_handle->eventmgr = NULL;
return PP_DPM_DISABLED;
}
static int pp_hw_fini(void *handle)
{
struct pp_eventmgr *eventmgr;
struct pp_instance *pp_handle = (struct pp_instance *)handle;
int ret = 0;
ret = pp_check(pp_handle);
if (ret == 0) {
eventmgr = pp_handle->eventmgr;
if (eventmgr->pp_eventmgr_fini != NULL)
eventmgr->pp_eventmgr_fini(eventmgr);
if (ret == 0)
hwmgr_hw_fini(pp_handle);
}
return 0;
}
......@@ -244,8 +218,6 @@ static int pp_set_powergating_state(void *handle,
static int pp_suspend(void *handle)
{
struct pp_eventmgr *eventmgr;
struct pem_event_data event_data = { {0} };
struct pp_instance *pp_handle = (struct pp_instance *)handle;
int ret = 0;
......@@ -256,16 +228,11 @@ static int pp_suspend(void *handle)
else if (ret != 0)
return ret;
eventmgr = pp_handle->eventmgr;
pem_handle_event(eventmgr, AMD_PP_EVENT_SUSPEND, &event_data);
return 0;
return hwmgr_hw_suspend(pp_handle);
}
static int pp_resume(void *handle)
{
struct pp_eventmgr *eventmgr;
struct pem_event_data event_data = { {0} };
struct pp_smumgr *smumgr;
int ret, ret1;
struct pp_instance *pp_handle = (struct pp_instance *)handle;
......@@ -290,11 +257,7 @@ static int pp_resume(void *handle)
if (ret1 == PP_DPM_DISABLED)
return 0;
eventmgr = pp_handle->eventmgr;
pem_handle_event(eventmgr, AMD_PP_EVENT_RESUME, &event_data);
return 0;
return hwmgr_hw_resume(pp_handle);
}
const struct amd_ip_funcs pp_ip_funcs = {
......@@ -344,6 +307,7 @@ static int pp_dpm_force_performance_level(void *handle,
}
mutex_lock(&pp_handle->pp_lock);
hwmgr_handle_task(pp_handle, AMD_PP_TASK_READJUST_POWER_STATE, NULL, NULL);
hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
mutex_unlock(&pp_handle->pp_lock);
return 0;
......@@ -461,60 +425,21 @@ static int pp_dpm_powergate_uvd(void *handle, bool gate)
return ret;
}
static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type state)
{
switch (state) {
case POWER_STATE_TYPE_BATTERY:
return PP_StateUILabel_Battery;
case POWER_STATE_TYPE_BALANCED:
return PP_StateUILabel_Balanced;
case POWER_STATE_TYPE_PERFORMANCE:
return PP_StateUILabel_Performance;
default:
return PP_StateUILabel_None;
}
}
static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id,
static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id,
void *input, void *output)
{
int ret = 0;
struct pem_event_data data = { {0} };
struct pp_instance *pp_handle = (struct pp_instance *)handle;
ret = pp_check(pp_handle);
if (ret != 0)
return ret;
mutex_lock(&pp_handle->pp_lock);
switch (event_id) {
case AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE:
ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
break;
case AMD_PP_EVENT_ENABLE_USER_STATE:
{
enum amd_pm_state_type ps;
if (input == NULL) {
ret = -EINVAL;
break;
}
ps = *(unsigned long *)input;
data.requested_ui_label = power_state_convert(ps);
ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
break;
}
case AMD_PP_EVENT_COMPLETE_INIT:
ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
break;
case AMD_PP_EVENT_READJUST_POWER_STATE:
ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
break;
default:
break;
}
mutex_lock(&pp_handle->pp_lock);
ret = hwmgr_handle_task(pp_handle, task_id, input, output);
mutex_unlock(&pp_handle->pp_lock);
return ret;
}
......@@ -1190,10 +1115,8 @@ int amd_powerplay_destroy(void *handle)
struct pp_instance *instance = (struct pp_instance *)handle;
if (instance->pm_en) {
kfree(instance->eventmgr);
kfree(instance->hwmgr);
instance->hwmgr = NULL;
instance->eventmgr = NULL;
}
kfree(instance->smu_mgr);
......@@ -1206,8 +1129,6 @@ int amd_powerplay_destroy(void *handle)
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 (cgs_is_virtualization_enabled(instance->smu_mgr->device))
......@@ -1217,7 +1138,7 @@ int amd_powerplay_reset(void *handle)
if (ret != 0)
return ret;
ret = pp_hw_fini(handle);
ret = pp_hw_fini(instance);
if (ret)
return ret;
......@@ -1225,16 +1146,7 @@ int amd_powerplay_reset(void *handle)
if (ret)
return PP_DPM_DISABLED;
eventmgr = instance->eventmgr;
if (eventmgr->pp_eventmgr_init == NULL)
return PP_DPM_DISABLED;
ret = eventmgr->pp_eventmgr_init(eventmgr);
if (ret)
return ret;
return pem_handle_event(eventmgr, AMD_PP_EVENT_COMPLETE_INIT, &event_data);
return hwmgr_handle_task(instance, AMD_PP_TASK_COMPLETE_INIT, NULL, NULL);
}
/* export this function to DAL */
......
......@@ -9,7 +9,8 @@ HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \
smu7_hwmgr.o smu7_powertune.o smu7_thermal.o \
smu7_clockpowergating.o \
vega10_processpptables.o vega10_hwmgr.o vega10_powertune.o \
vega10_thermal.o pp_overdriver.o rv_hwmgr.o
vega10_thermal.o rv_hwmgr.o pp_psm.o\
pp_overdriver.o
AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR))
......
......@@ -26,6 +26,10 @@
#include "hardwaremanager.h"
#include "power_state.h"
#define TEMP_RANGE_MIN (90 * 1000)
#define TEMP_RANGE_MAX (120 * 1000)
#define PHM_FUNC_CHECK(hw) \
do { \
if ((hw) == NULL || (hw)->hwmgr_func == NULL) \
......@@ -292,7 +296,19 @@ int phm_register_thermal_interrupt(struct pp_hwmgr *hwmgr, const void *info)
*/
int phm_start_thermal_controller(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *temperature_range)
{
return phm_dispatch_table(hwmgr, &(hwmgr->start_thermal_controller), temperature_range, NULL);
struct PP_TemperatureRange range;
if (temperature_range == NULL) {
range.max = TEMP_RANGE_MAX;
range.min = TEMP_RANGE_MIN;
} else {
range.max = temperature_range->max;
range.min = temperature_range->min;
}
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_ThermalController))
return phm_dispatch_table(hwmgr, &(hwmgr->start_thermal_controller), &range, NULL);
return 0;
}
......
......@@ -35,9 +35,9 @@
#include "ppsmc.h"
#include "pp_acpi.h"
#include "amd_acpi.h"
#include "pp_psm.h"
extern int cz_init_function_pointers(struct pp_hwmgr *hwmgr);
static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);
static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr);
static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr);
......@@ -131,80 +131,6 @@ int hwmgr_early_init(struct pp_instance *handle)
return 0;
}
static int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
{
int result;
unsigned int i;
unsigned int table_entries;
struct pp_power_state *state;
int size;
if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
return -EINVAL;
if (hwmgr->hwmgr_func->get_power_state_size == NULL)
return -EINVAL;
hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
sizeof(struct pp_power_state);
hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
if (hwmgr->ps == NULL)
return -ENOMEM;
hwmgr->request_ps = kzalloc(size, GFP_KERNEL);
if (hwmgr->request_ps == NULL) {
kfree(hwmgr->ps);
hwmgr->ps = NULL;
return -ENOMEM;
}
hwmgr->current_ps = kzalloc(size, GFP_KERNEL);
if (hwmgr->current_ps == NULL) {
kfree(hwmgr->request_ps);
kfree(hwmgr->ps);
hwmgr->request_ps = NULL;
hwmgr->ps = NULL;
return -ENOMEM;
}
state = hwmgr->ps;
for (i = 0; i < table_entries; i++) {
result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
if (state->classification.flags & PP_StateClassificationFlag_Boot) {
hwmgr->boot_ps = state;
memcpy(hwmgr->current_ps, state, size);
memcpy(hwmgr->request_ps, state, size);
}
state->id = i + 1; /* assigned unique num for every power state id */
if (state->classification.flags & PP_StateClassificationFlag_Uvd)
hwmgr->uvd_ps = state;
state = (struct pp_power_state *)((unsigned long)state + size);
}
return 0;
}
static int hw_fini_power_state_table(struct pp_hwmgr *hwmgr)
{
if (hwmgr == NULL)
return -EINVAL;
kfree(hwmgr->current_ps);
kfree(hwmgr->request_ps);
kfree(hwmgr->ps);
hwmgr->request_ps = NULL;
hwmgr->ps = NULL;
hwmgr->current_ps = NULL;
return 0;
}
int hwmgr_hw_init(struct pp_instance *handle)
{
struct pp_hwmgr *hwmgr;
......@@ -228,9 +154,22 @@ int hwmgr_hw_init(struct pp_instance *handle)
if (ret)
goto err1;
ret = hw_init_power_state_table(hwmgr);
ret = psm_init_power_state_table(hwmgr);
if (ret)
goto err2;
ret = phm_setup_asic(hwmgr);
if (ret)
goto err2;
ret = phm_enable_dynamic_state_management(hwmgr);
if (ret)
goto err2;
ret = phm_start_thermal_controller(hwmgr, NULL);
ret |= psm_set_performance_states(hwmgr);
if (ret)
goto err2;
return 0;
err2:
if (hwmgr->hwmgr_func->backend_fini)
......@@ -247,19 +186,138 @@ int hwmgr_hw_fini(struct pp_instance *handle)
{
struct pp_hwmgr *hwmgr;
if (handle == NULL)
if (handle == NULL || handle->hwmgr == NULL)
return -EINVAL;
hwmgr = handle->hwmgr;
phm_stop_thermal_controller(hwmgr);
psm_set_boot_states(hwmgr);
phm_display_configuration_changed(hwmgr);
psm_adjust_power_state_dynamic(hwmgr, false, NULL);
phm_disable_dynamic_state_management(hwmgr);
phm_disable_clock_power_gatings(hwmgr);
if (hwmgr->hwmgr_func->backend_fini)
hwmgr->hwmgr_func->backend_fini(hwmgr);
if (hwmgr->pptable_func->pptable_fini)
hwmgr->pptable_func->pptable_fini(hwmgr);
return hw_fini_power_state_table(hwmgr);
return psm_fini_power_state_table(hwmgr);
}
int hwmgr_hw_suspend(struct pp_instance *handle)
{
struct pp_hwmgr *hwmgr;
int ret = 0;
if (handle == NULL || handle->hwmgr == NULL)
return -EINVAL;
hwmgr = handle->hwmgr;
phm_disable_smc_firmware_ctf(hwmgr);
ret = psm_set_boot_states(hwmgr);
if (ret)
return ret;
ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
if (ret)
return ret;
ret = phm_power_down_asic(hwmgr);
return ret;
}
int hwmgr_hw_resume(struct pp_instance *handle)
{
struct pp_hwmgr *hwmgr;
int ret = 0;
if (handle == NULL || handle->hwmgr == NULL)
return -EINVAL;
hwmgr = handle->hwmgr;
ret = phm_setup_asic(hwmgr);
if (ret)
return ret;
ret = phm_enable_dynamic_state_management(hwmgr);
if (ret)
return ret;
ret = phm_start_thermal_controller(hwmgr, NULL);
if (ret)
return ret;
ret |= psm_set_performance_states(hwmgr);
if (ret)
return ret;
ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
return ret;
}
static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type state)
{
switch (state) {
case POWER_STATE_TYPE_BATTERY:
return PP_StateUILabel_Battery;
case POWER_STATE_TYPE_BALANCED:
return PP_StateUILabel_Balanced;
case POWER_STATE_TYPE_PERFORMANCE:
return PP_StateUILabel_Performance;
default:
return PP_StateUILabel_None;
}
}
int hwmgr_handle_task(struct pp_instance *handle, enum amd_pp_task task_id,
void *input, void *output)
{
int ret = 0;
struct pp_hwmgr *hwmgr;
if (handle == NULL || handle->hwmgr == NULL)
return -EINVAL;
hwmgr = handle->hwmgr;
switch (task_id) {
case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE:
ret = phm_set_cpu_power_state(hwmgr);
if (ret)
return ret;
ret = psm_set_performance_states(hwmgr);
if (ret)
return ret;
ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
break;
case AMD_PP_TASK_ENABLE_USER_STATE:
{
enum amd_pm_state_type ps;
enum PP_StateUILabel requested_ui_label;
struct pp_power_state *requested_ps;
if (input == NULL) {
ret = -EINVAL;
break;
}
ps = *(unsigned long *)input;
requested_ui_label = power_state_convert(ps);
ret = psm_set_user_performance_state(hwmgr, requested_ui_label, requested_ps);
if (ret)
return ret;
ret = psm_adjust_power_state_dynamic(hwmgr, false, requested_ps);
break;
}
case AMD_PP_TASK_COMPLETE_INIT:
case AMD_PP_TASK_READJUST_POWER_STATE:
ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
break;
default:
break;
}
return ret;
}
/**
* Returns once the part of the register indicated by the mask has
* reached the given value.
......
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include "pp_psm.h"
int psm_init_power_state_table(struct pp_hwmgr *hwmgr)
{
int result;
unsigned int i;
unsigned int table_entries;
struct pp_power_state *state;
int size;
if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
return -EINVAL;
if (hwmgr->hwmgr_func->get_power_state_size == NULL)
return -EINVAL;
hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
sizeof(struct pp_power_state);
hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
if (hwmgr->ps == NULL)
return -ENOMEM;
hwmgr->request_ps = kzalloc(size, GFP_KERNEL);
if (hwmgr->request_ps == NULL) {
kfree(hwmgr->ps);
hwmgr->ps = NULL;
return -ENOMEM;
}
hwmgr->current_ps = kzalloc(size, GFP_KERNEL);
if (hwmgr->current_ps == NULL) {
kfree(hwmgr->request_ps);
kfree(hwmgr->ps);
hwmgr->request_ps = NULL;
hwmgr->ps = NULL;
return -ENOMEM;
}
state = hwmgr->ps;
for (i = 0; i < table_entries; i++) {
result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
if (state->classification.flags & PP_StateClassificationFlag_Boot) {
hwmgr->boot_ps = state;
memcpy(hwmgr->current_ps, state, size);
memcpy(hwmgr->request_ps, state, size);
}
state->id = i + 1; /* assigned unique num for every power state id */
if (state->classification.flags & PP_StateClassificationFlag_Uvd)
hwmgr->uvd_ps = state;
state = (struct pp_power_state *)((unsigned long)state + size);
}
return 0;
}
int psm_fini_power_state_table(struct pp_hwmgr *hwmgr)
{
if (hwmgr == NULL)
return -EINVAL;
kfree(hwmgr->current_ps);
kfree(hwmgr->request_ps);
kfree(hwmgr->ps);
hwmgr->request_ps = NULL;
hwmgr->ps = NULL;
hwmgr->current_ps = NULL;
return 0;
}
static int psm_get_ui_state(struct pp_hwmgr *hwmgr,
enum PP_StateUILabel ui_label,
unsigned long *state_id)
{
struct pp_power_state *state;
int table_entries;
int i;
table_entries = hwmgr->num_ps;
state = hwmgr->ps;
for (i = 0; i < table_entries; i++) {
if (state->classification.ui_label & ui_label) {
*state_id = state->id;
return 0;
}
state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
}
return -EINVAL;
}
static int psm_get_state_by_classification(struct pp_hwmgr *hwmgr,
enum PP_StateClassificationFlag flag,
unsigned long *state_id)
{
struct pp_power_state *state;
int table_entries;
int i;
table_entries = hwmgr->num_ps;
state = hwmgr->ps;
for (i = 0; i < table_entries; i++) {
if (state->classification.flags & flag) {
*state_id = state->id;
return 0;
}
state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
}
return -EINVAL;
}
static int psm_set_states(struct pp_hwmgr *hwmgr, unsigned long state_id)
{
struct pp_power_state *state;
int table_entries;
int i;
table_entries = hwmgr->num_ps;
state = hwmgr->ps;
for (i = 0; i < table_entries; i++) {
if (state->id == state_id) {
memcpy(hwmgr->request_ps, state, hwmgr->ps_size);
return 0;
}
state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
}
return -EINVAL;
}
int psm_set_boot_states(struct pp_hwmgr *hwmgr)
{
unsigned long state_id;
int ret = -EINVAL;
if (!psm_get_state_by_classification(hwmgr, PP_StateClassificationFlag_Boot,
&state_id))
ret = psm_set_states(hwmgr, state_id);
return ret;
}
int psm_set_performance_states(struct pp_hwmgr *hwmgr)
{
unsigned long state_id;
int ret = -EINVAL;
if (!psm_get_ui_state(hwmgr, PP_StateUILabel_Performance,
&state_id))
ret = psm_set_states(hwmgr, state_id);
return ret;
}
int psm_set_user_performance_state(struct pp_hwmgr *hwmgr,
enum PP_StateUILabel label_id,
struct pp_power_state *state)
{
int table_entries;
int i;
table_entries = hwmgr->num_ps;
state = hwmgr->ps;
restart_search:
for (i = 0; i < table_entries; i++) {
if (state->classification.ui_label & label_id)
return 0;
state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
}
switch (label_id) {
case PP_StateUILabel_Battery:
case PP_StateUILabel_Balanced:
label_id = PP_StateUILabel_Performance;
goto restart_search;
default:
break;
}
return -EINVAL;
}
int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip,
struct pp_power_state *new_ps)
{
struct pp_power_state *pcurrent;
struct pp_power_state *requested;
bool equal;
if (skip)
return 0;
if (new_ps != NULL)
requested = new_ps;
else
requested = hwmgr->request_ps;
pcurrent = hwmgr->current_ps;
phm_apply_state_adjust_rules(hwmgr, requested, pcurrent);
if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr,
&pcurrent->hardware, &requested->hardware, &equal)))
equal = false;
if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) {
phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware);
memcpy(hwmgr->current_ps, hwmgr->request_ps, hwmgr->ps_size);
}
return 0;
}
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef PP_PSM_H
#define PP_PSM_H
#include "hwmgr.h"
int psm_init_power_state_table(struct pp_hwmgr *hwmgr);
int psm_fini_power_state_table(struct pp_hwmgr *hwmgr);
int psm_set_boot_states(struct pp_hwmgr *hwmgr);
int psm_set_performance_states(struct pp_hwmgr *hwmgr);
int psm_set_user_performance_state(struct pp_hwmgr *hwmgr,
enum PP_StateUILabel label_id,
struct pp_power_state *state);
int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr,
bool skip,
struct pp_power_state *new_ps);
#endif
......@@ -50,94 +50,12 @@ enum amd_pp_sensors {
AMDGPU_PP_SENSOR_GPU_POWER,
};
enum amd_pp_event {
AMD_PP_EVENT_INITIALIZE = 0,
AMD_PP_EVENT_UNINITIALIZE,
AMD_PP_EVENT_POWER_SOURCE_CHANGE,
AMD_PP_EVENT_SUSPEND,
AMD_PP_EVENT_RESUME,
AMD_PP_EVENT_ENTER_REST_STATE,
AMD_PP_EVENT_EXIT_REST_STATE,
AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE,
AMD_PP_EVENT_THERMAL_NOTIFICATION,
AMD_PP_EVENT_VBIOS_NOTIFICATION,
AMD_PP_EVENT_ENTER_THERMAL_STATE,
AMD_PP_EVENT_EXIT_THERMAL_STATE,
AMD_PP_EVENT_ENTER_FORCED_STATE,
AMD_PP_EVENT_EXIT_FORCED_STATE,
AMD_PP_EVENT_ENTER_EXCLUSIVE_MODE,
AMD_PP_EVENT_EXIT_EXCLUSIVE_MODE,
AMD_PP_EVENT_ENTER_SCREEN_SAVER,
AMD_PP_EVENT_EXIT_SCREEN_SAVER,
AMD_PP_EVENT_VPU_RECOVERY_BEGIN,
AMD_PP_EVENT_VPU_RECOVERY_END,
AMD_PP_EVENT_ENABLE_POWER_PLAY,
AMD_PP_EVENT_DISABLE_POWER_PLAY,
AMD_PP_EVENT_CHANGE_POWER_SOURCE_UI_LABEL,
AMD_PP_EVENT_ENABLE_USER2D_PERFORMANCE,
AMD_PP_EVENT_DISABLE_USER2D_PERFORMANCE,
AMD_PP_EVENT_ENABLE_USER3D_PERFORMANCE,
AMD_PP_EVENT_DISABLE_USER3D_PERFORMANCE,
AMD_PP_EVENT_ENABLE_OVER_DRIVE_TEST,
AMD_PP_EVENT_DISABLE_OVER_DRIVE_TEST,
AMD_PP_EVENT_ENABLE_REDUCED_REFRESH_RATE,
AMD_PP_EVENT_DISABLE_REDUCED_REFRESH_RATE,
AMD_PP_EVENT_ENABLE_GFX_CLOCK_GATING,
AMD_PP_EVENT_DISABLE_GFX_CLOCK_GATING,
AMD_PP_EVENT_ENABLE_CGPG,
AMD_PP_EVENT_DISABLE_CGPG,
AMD_PP_EVENT_ENTER_TEXT_MODE,
AMD_PP_EVENT_EXIT_TEXT_MODE,
AMD_PP_EVENT_VIDEO_START,
AMD_PP_EVENT_VIDEO_STOP,
AMD_PP_EVENT_ENABLE_USER_STATE,
AMD_PP_EVENT_DISABLE_USER_STATE,
AMD_PP_EVENT_READJUST_POWER_STATE,
AMD_PP_EVENT_START_INACTIVITY,
AMD_PP_EVENT_STOP_INACTIVITY,
AMD_PP_EVENT_LINKED_ADAPTERS_READY,
AMD_PP_EVENT_ADAPTER_SAFE_TO_DISABLE,
AMD_PP_EVENT_COMPLETE_INIT,
AMD_PP_EVENT_CRITICAL_THERMAL_FAULT,
AMD_PP_EVENT_BACKLIGHT_CHANGED,
AMD_PP_EVENT_ENABLE_VARI_BRIGHT,
AMD_PP_EVENT_DISABLE_VARI_BRIGHT,
AMD_PP_EVENT_ENABLE_VARI_BRIGHT_ON_POWER_XPRESS,
AMD_PP_EVENT_DISABLE_VARI_BRIGHT_ON_POWER_XPRESS,
AMD_PP_EVENT_SET_VARI_BRIGHT_LEVEL,
AMD_PP_EVENT_VARI_BRIGHT_MONITOR_MEASUREMENT,
AMD_PP_EVENT_SCREEN_ON,
AMD_PP_EVENT_SCREEN_OFF,
AMD_PP_EVENT_PRE_DISPLAY_CONFIG_CHANGE,
AMD_PP_EVENT_ENTER_ULP_STATE,
AMD_PP_EVENT_EXIT_ULP_STATE,
AMD_PP_EVENT_REGISTER_IP_STATE,
AMD_PP_EVENT_UNREGISTER_IP_STATE,
AMD_PP_EVENT_ENTER_MGPU_MODE,
AMD_PP_EVENT_EXIT_MGPU_MODE,
AMD_PP_EVENT_ENTER_MULTI_GPU_MODE,
AMD_PP_EVENT_PRE_SUSPEND,
AMD_PP_EVENT_PRE_RESUME,
AMD_PP_EVENT_ENTER_BACOS,
AMD_PP_EVENT_EXIT_BACOS,
AMD_PP_EVENT_RESUME_BACO,
AMD_PP_EVENT_RESET_BACO,
AMD_PP_EVENT_PRE_DISPLAY_PHY_ACCESS,
AMD_PP_EVENT_POST_DISPLAY_PHY_CCESS,
AMD_PP_EVENT_START_COMPUTE_APPLICATION,
AMD_PP_EVENT_STOP_COMPUTE_APPLICATION,
AMD_PP_EVENT_REDUCE_POWER_LIMIT,
AMD_PP_EVENT_ENTER_FRAME_LOCK,
AMD_PP_EVENT_EXIT_FRAME_LOOCK,
AMD_PP_EVENT_LONG_IDLE_REQUEST_BACO,
AMD_PP_EVENT_LONG_IDLE_ENTER_BACO,
AMD_PP_EVENT_LONG_IDLE_EXIT_BACO,
AMD_PP_EVENT_HIBERNATE,
AMD_PP_EVENT_CONNECTED_STANDBY,
AMD_PP_EVENT_ENTER_SELF_REFRESH,
AMD_PP_EVENT_EXIT_SELF_REFRESH,
AMD_PP_EVENT_START_AVFS_BTC,
AMD_PP_EVENT_MAX
enum amd_pp_task {
AMD_PP_TASK_DISPLAY_CONFIG_CHANGE,
AMD_PP_TASK_ENABLE_USER_STATE,
AMD_PP_TASK_READJUST_POWER_STATE,
AMD_PP_TASK_COMPLETE_INIT,
AMD_PP_TASK_MAX
};
struct amd_pp_init {
......@@ -366,7 +284,7 @@ struct amd_powerplay_funcs {
int (*get_mclk)(void *handle, bool low);
int (*powergate_vce)(void *handle, bool gate);
int (*powergate_uvd)(void *handle, bool gate);
int (*dispatch_tasks)(void *handle, enum amd_pp_event event_id,
int (*dispatch_tasks)(void *handle, enum amd_pp_task task_id,
void *input, void *output);
int (*set_fan_control_mode)(void *handle, uint32_t mode);
int (*get_fan_control_mode)(void *handle);
......
......@@ -797,6 +797,11 @@ struct pp_hwmgr {
extern int hwmgr_early_init(struct pp_instance *handle);
extern int hwmgr_hw_init(struct pp_instance *handle);
extern int hwmgr_hw_fini(struct pp_instance *handle);
extern int hwmgr_hw_suspend(struct pp_instance *handle);
extern int hwmgr_hw_resume(struct pp_instance *handle);
extern int hwmgr_handle_task(struct pp_instance *handle,
enum amd_pp_task task_id,
void *input, void *output);
extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
uint32_t value, uint32_t mask);
......
......@@ -25,7 +25,6 @@
#include "smumgr.h"
#include "hwmgr.h"
#include "eventmgr.h"
#define PP_VALID 0x1F1F1F1F
......@@ -38,7 +37,6 @@ struct pp_instance {
void *device;
struct pp_smumgr *smu_mgr;
struct pp_hwmgr *hwmgr;
struct pp_eventmgr *eventmgr;
struct mutex pp_lock;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment