if (adev->flags & AMD_IS_APU)
*states = ATTR_STATE_UNSUPPORTED;
} else if (DEVICE_ATTR_IS(unique_id)) {
- if (!adev->unique_id)
+ if (asic_type != CHIP_VEGA10 &&
+ asic_type != CHIP_VEGA20 &&
+ asic_type != CHIP_ARCTURUS)
*states = ATTR_STATE_UNSUPPORTED;
} else if (DEVICE_ATTR_IS(pp_features)) {
if (adev->flags & AMD_IS_APU || asic_type < CHIP_VEGA10)
i2c_del_adapter(control);
}
+static void arcturus_get_unique_id(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+ uint32_t top32, bottom32, smu_version, size;
+ char sn[16];
+ uint64_t id;
+
+ if (smu_get_smc_version(smu, NULL, &smu_version)) {
+ pr_warn("Failed to get smu version, cannot get unique_id or serial_number\n");
+ return;
+ }
+
+ /* PPSMC_MSG_ReadSerial* is supported by 54.23.0 and onwards */
+ if (smu_version < 0x361700) {
+ pr_warn("ReadSerial is only supported by PMFW 54.23.0 and onwards\n");
+ return;
+ }
+
+ /* Get the SN to turn into a Unique ID */
+ smu_send_smc_msg(smu, SMU_MSG_ReadSerialNumTop32, &top32);
+ smu_send_smc_msg(smu, SMU_MSG_ReadSerialNumBottom32, &bottom32);
+
+ id = ((uint64_t)bottom32 << 32) | top32;
+ adev->unique_id = id;
+ /* For Arcturus-and-later, unique_id == serial_number, so convert it to a
+ * 16-digit HEX string for convenience and backwards-compatibility
+ */
+ size = sprintf(sn, "%llx", id);
+ memcpy(adev->serial, &sn, size);
+}
+
static bool arcturus_is_baco_supported(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
.dpm_set_uvd_enable = arcturus_dpm_set_uvd_enable,
.i2c_eeprom_init = arcturus_i2c_eeprom_control_init,
.i2c_eeprom_fini = arcturus_i2c_eeprom_control_fini,
+ .get_unique_id = arcturus_get_unique_id,
.init_microcode = smu_v11_0_init_microcode,
.load_microcode = smu_v11_0_load_microcode,
.init_smc_tables = smu_v11_0_init_smc_tables,
int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap);
int (*i2c_eeprom_init)(struct i2c_adapter *control);
void (*i2c_eeprom_fini)(struct i2c_adapter *control);
+ void (*get_unique_id)(struct smu_context *smu);
int (*get_dpm_clock_table)(struct smu_context *smu, struct dpm_clocks *clock_table);
int (*init_microcode)(struct smu_context *smu);
int (*load_microcode)(struct smu_context *smu);
((smu)->ppt_funcs->i2c_eeprom_init ? (smu)->ppt_funcs->i2c_eeprom_init((control)) : 0)
#define smu_i2c_eeprom_fini(smu, control) \
((smu)->ppt_funcs->i2c_eeprom_fini ? (smu)->ppt_funcs->i2c_eeprom_fini((control)) : 0)
+#define smu_get_unique_id(smu) \
+ ((smu)->ppt_funcs->get_unique_id ? (smu)->ppt_funcs->get_unique_id((smu)) : 0)
#define smu_log_thermal_throttling(smu) \
((smu)->ppt_funcs->log_thermal_throttling_event ? (smu)->ppt_funcs->log_thermal_throttling_event((smu)) : 0)