diff options
Diffstat (limited to 'drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c')
-rw-r--r-- | drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 102 |
1 files changed, 63 insertions, 39 deletions
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 505d2fb94fd9..201563072189 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -25,6 +25,7 @@ #include <linux/firmware.h> #include "amdgpu.h" +#include "amdgpu_dpm.h" #include "amdgpu_smu.h" #include "atomfirmware.h" #include "amdgpu_atomfirmware.h" @@ -33,7 +34,6 @@ #include "smu11_driver_if_arcturus.h" #include "soc15_common.h" #include "atom.h" -#include "power_state.h" #include "arcturus_ppt.h" #include "smu_v11_0_pptable.h" #include "arcturus_ppsmc.h" @@ -57,8 +57,6 @@ #undef pr_info #undef pr_debug -#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) - #define ARCTURUS_FEA_MAP(smu_feature, arcturus_feature) \ [smu_feature] = {1, (arcturus_feature)} @@ -603,15 +601,11 @@ static int arcturus_get_smu_metrics_data(struct smu_context *smu, SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; - mutex_lock(&smu->metrics_lock); - - ret = smu_cmn_get_metrics_table_locked(smu, - NULL, - false); - if (ret) { - mutex_unlock(&smu->metrics_lock); + ret = smu_cmn_get_metrics_table(smu, + NULL, + false); + if (ret) return ret; - } switch (member) { case METRICS_CURR_GFXCLK: @@ -694,8 +688,6 @@ static int arcturus_get_smu_metrics_data(struct smu_context *smu, break; } - mutex_unlock(&smu->metrics_lock); - return ret; } @@ -1120,7 +1112,6 @@ static int arcturus_read_sensor(struct smu_context *smu, if (!data || !size) return -EINVAL; - mutex_lock(&smu->sensor_lock); switch (sensor) { case AMDGPU_PP_SENSOR_MAX_FAN_RPM: *(uint32_t *)data = pptable->FanMaximumRpm; @@ -1181,7 +1172,6 @@ static int arcturus_read_sensor(struct smu_context *smu, ret = -EOPNOTSUPP; break; } - mutex_unlock(&smu->sensor_lock); return ret; } @@ -2031,15 +2021,12 @@ static void arcturus_dump_pptable(struct smu_context *smu) static bool arcturus_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint32_t feature_mask[2]; uint64_t feature_enabled; - ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); + ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; - return !!(feature_enabled & SMC_DPM_FEATURE); } @@ -2071,18 +2058,23 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable) static int arcturus_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msg, int num_msgs) { - struct amdgpu_device *adev = to_amdgpu_device(i2c_adap); - struct smu_table_context *smu_table = &adev->smu.smu_table; + struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(i2c_adap); + struct amdgpu_device *adev = smu_i2c->adev; + struct smu_context *smu = adev->powerplay.pp_handle; + struct smu_table_context *smu_table = &smu->smu_table; struct smu_table *table = &smu_table->driver_table; SwI2cRequest_t *req, *res = (SwI2cRequest_t *)table->cpu_addr; int i, j, r, c; u16 dir; + if (!adev->pm.dpm_enabled) + return -EBUSY; + req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; - req->I2CcontrollerPort = 0; + req->I2CcontrollerPort = smu_i2c->port; req->I2CSpeed = I2C_SPEED_FAST_400K; req->SlaveAddress = msg[0].addr << 1; /* wants an 8-bit address */ dir = msg[0].flags & I2C_M_RD; @@ -2118,9 +2110,9 @@ static int arcturus_i2c_xfer(struct i2c_adapter *i2c_adap, } } } - mutex_lock(&adev->smu.mutex); - r = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, req, true); - mutex_unlock(&adev->smu.mutex); + mutex_lock(&adev->pm.mutex); + r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true); + mutex_unlock(&adev->pm.mutex); if (r) goto fail; @@ -2161,28 +2153,60 @@ static const struct i2c_adapter_quirks arcturus_i2c_control_quirks = { .max_comb_2nd_msg_len = MAX_SW_I2C_COMMANDS - 2, }; -static int arcturus_i2c_control_init(struct smu_context *smu, struct i2c_adapter *control) +static int arcturus_i2c_control_init(struct smu_context *smu) { - struct amdgpu_device *adev = to_amdgpu_device(control); - int res; + struct amdgpu_device *adev = smu->adev; + int res, i; + + for (i = 0; i < MAX_SMU_I2C_BUSES; i++) { + struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i]; + struct i2c_adapter *control = &smu_i2c->adapter; + + smu_i2c->adev = adev; + smu_i2c->port = i; + mutex_init(&smu_i2c->mutex); + control->owner = THIS_MODULE; + control->class = I2C_CLASS_HWMON; + control->dev.parent = &adev->pdev->dev; + control->algo = &arcturus_i2c_algo; + control->quirks = &arcturus_i2c_control_quirks; + snprintf(control->name, sizeof(control->name), "AMDGPU SMU %d", i); + i2c_set_adapdata(control, smu_i2c); + + res = i2c_add_adapter(control); + if (res) { + DRM_ERROR("Failed to register hw i2c, err: %d\n", res); + goto Out_err; + } + } - control->owner = THIS_MODULE; - control->class = I2C_CLASS_HWMON; - control->dev.parent = &adev->pdev->dev; - control->algo = &arcturus_i2c_algo; - control->quirks = &arcturus_i2c_control_quirks; - snprintf(control->name, sizeof(control->name), "AMDGPU SMU"); + adev->pm.ras_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter; + adev->pm.fru_eeprom_i2c_bus = &adev->pm.smu_i2c[1].adapter; - res = i2c_add_adapter(control); - if (res) - DRM_ERROR("Failed to register hw i2c, err: %d\n", res); + return 0; +Out_err: + for ( ; i >= 0; i--) { + struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i]; + struct i2c_adapter *control = &smu_i2c->adapter; + i2c_del_adapter(control); + } return res; } -static void arcturus_i2c_control_fini(struct smu_context *smu, struct i2c_adapter *control) +static void arcturus_i2c_control_fini(struct smu_context *smu) { - i2c_del_adapter(control); + struct amdgpu_device *adev = smu->adev; + int i; + + for (i = 0; i < MAX_SMU_I2C_BUSES; i++) { + struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i]; + struct i2c_adapter *control = &smu_i2c->adapter; + + i2c_del_adapter(control); + } + adev->pm.ras_eeprom_i2c_bus = NULL; + adev->pm.fru_eeprom_i2c_bus = NULL; } static void arcturus_get_unique_id(struct smu_context *smu) |