mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
drm/amd/powerplay: implement sysfs of pp_table for smu11 (v2)
add pp_table sysfs interface for new sw-smu. get: return pptable raw data set: write pptable raw data to pptable, then reset smu (hw_fini -> hw_init) v2: fix mutex lock issue Signed-off-by: Kevin Wang <Kevin1.Wang@amd.com> Reviewed-by: Huang Rui <ray.huang@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4a5a2de666
commit
289921b03f
4 changed files with 89 additions and 8 deletions
|
@ -464,7 +464,12 @@ static ssize_t amdgpu_get_pp_table(struct device *dev,
|
||||||
char *table = NULL;
|
char *table = NULL;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
if (adev->powerplay.pp_funcs->get_pp_table)
|
if (is_support_sw_smu(adev)) {
|
||||||
|
size = smu_sys_get_pp_table(&adev->smu, (void **)&table);
|
||||||
|
if (size < 0)
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
else if (adev->powerplay.pp_funcs->get_pp_table)
|
||||||
size = amdgpu_dpm_get_pp_table(adev, &table);
|
size = amdgpu_dpm_get_pp_table(adev, &table);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -484,8 +489,13 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
|
||||||
{
|
{
|
||||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||||
struct amdgpu_device *adev = ddev->dev_private;
|
struct amdgpu_device *adev = ddev->dev_private;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (adev->powerplay.pp_funcs->set_pp_table)
|
if (is_support_sw_smu(adev)) {
|
||||||
|
ret = smu_sys_set_pp_table(&adev->smu, (void *)buf, count);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
} else if (adev->powerplay.pp_funcs->set_pp_table)
|
||||||
amdgpu_dpm_set_pp_table(adev, buf, count);
|
amdgpu_dpm_set_pp_table(adev, buf, count);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
|
@ -76,6 +76,54 @@ bool is_support_sw_smu(struct amdgpu_device *adev)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smu_sys_get_pp_table(struct smu_context *smu, void **table)
|
||||||
|
{
|
||||||
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
|
|
||||||
|
if (!smu_table->power_play_table && !smu_table->hardcode_pptable)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (smu_table->hardcode_pptable)
|
||||||
|
*table = smu_table->hardcode_pptable;
|
||||||
|
else
|
||||||
|
*table = smu_table->power_play_table;
|
||||||
|
|
||||||
|
return smu_table->power_play_table_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size)
|
||||||
|
{
|
||||||
|
struct smu_table_context *smu_table = &smu->smu_table;
|
||||||
|
ATOM_COMMON_TABLE_HEADER *header = (ATOM_COMMON_TABLE_HEADER *)buf;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (header->usStructureSize != size) {
|
||||||
|
pr_err("pp table size not matched !\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&smu->mutex);
|
||||||
|
if (!smu_table->hardcode_pptable)
|
||||||
|
smu_table->hardcode_pptable = kzalloc(size, GFP_KERNEL);
|
||||||
|
if (!smu_table->hardcode_pptable) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(smu_table->hardcode_pptable, buf, size);
|
||||||
|
smu_table->power_play_table = smu_table->hardcode_pptable;
|
||||||
|
smu_table->power_play_table_size = size;
|
||||||
|
mutex_unlock(&smu->mutex);
|
||||||
|
|
||||||
|
ret = smu_reset(smu);
|
||||||
|
if (ret)
|
||||||
|
pr_info("smu reset failed, ret = %d\n", ret);
|
||||||
|
|
||||||
|
failed:
|
||||||
|
mutex_unlock(&smu->mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int smu_feature_init_dpm(struct smu_context *smu)
|
int smu_feature_init_dpm(struct smu_context *smu)
|
||||||
{
|
{
|
||||||
struct smu_feature *feature = &smu->smu_feature;
|
struct smu_feature *feature = &smu->smu_feature;
|
||||||
|
@ -328,7 +376,7 @@ static int smu_fini_fb_allocations(struct smu_context *smu)
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
if (table_count == 0 || tables == NULL)
|
if (table_count == 0 || tables == NULL)
|
||||||
return -EINVAL;
|
return 0;
|
||||||
|
|
||||||
for (i = 0 ; i < table_count; i++) {
|
for (i = 0 ; i < table_count; i++) {
|
||||||
if (tables[i].size == 0)
|
if (tables[i].size == 0)
|
||||||
|
@ -590,9 +638,10 @@ static int smu_hw_fini(void *handle)
|
||||||
if (!is_support_sw_smu(adev))
|
if (!is_support_sw_smu(adev))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!table_context->driver_pptable)
|
if (table_context->driver_pptable) {
|
||||||
return -EINVAL;
|
|
||||||
kfree(table_context->driver_pptable);
|
kfree(table_context->driver_pptable);
|
||||||
|
table_context->driver_pptable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (table_context->max_sustainable_clocks) {
|
if (table_context->max_sustainable_clocks) {
|
||||||
kfree(table_context->max_sustainable_clocks);
|
kfree(table_context->max_sustainable_clocks);
|
||||||
|
@ -610,6 +659,22 @@ static int smu_hw_fini(void *handle)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smu_reset(struct smu_context *smu)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = smu->adev;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = smu_hw_fini(adev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = smu_hw_init(adev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int smu_suspend(void *handle)
|
static int smu_suspend(void *handle)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||||
|
|
|
@ -158,6 +158,7 @@ struct smu_table_context
|
||||||
{
|
{
|
||||||
void *power_play_table;
|
void *power_play_table;
|
||||||
uint32_t power_play_table_size;
|
uint32_t power_play_table_size;
|
||||||
|
void *hardcode_pptable;
|
||||||
|
|
||||||
void *max_sustainable_clocks;
|
void *max_sustainable_clocks;
|
||||||
struct smu_bios_boot_up_values boot_values;
|
struct smu_bios_boot_up_values boot_values;
|
||||||
|
@ -372,5 +373,8 @@ extern int smu_feature_set_supported(struct smu_context *smu, int feature_id, bo
|
||||||
int smu_update_table(struct smu_context *smu, uint32_t table_id,
|
int smu_update_table(struct smu_context *smu, uint32_t table_id,
|
||||||
void *table_data, bool drv2smu);
|
void *table_data, bool drv2smu);
|
||||||
bool is_support_sw_smu(struct amdgpu_device *adev);
|
bool is_support_sw_smu(struct amdgpu_device *adev);
|
||||||
|
int smu_reset(struct smu_context *smu);
|
||||||
|
int smu_sys_get_pp_table(struct smu_context *smu, void **table);
|
||||||
|
int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -241,7 +241,9 @@ static int smu_v11_0_read_pptable_from_vbios(struct smu_context *smu)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (!smu->smu_table.power_play_table)
|
||||||
smu->smu_table.power_play_table = table;
|
smu->smu_table.power_play_table = table;
|
||||||
|
if (!smu->smu_table.power_play_table_size)
|
||||||
smu->smu_table.power_play_table_size = size;
|
smu->smu_table.power_play_table_size = size;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue