Commit 8a2b5139 authored by Lijo Lazar's avatar Lijo Lazar Committed by Alex Deucher

drm/amdgpu: Refactor FRU product information

Keep FRU related information together in a separate structure.
Signed-off-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent be2e8aca
...@@ -770,8 +770,8 @@ struct amdgpu_mqd { ...@@ -770,8 +770,8 @@ struct amdgpu_mqd {
#define AMDGPU_RESET_MAGIC_NUM 64 #define AMDGPU_RESET_MAGIC_NUM 64
#define AMDGPU_MAX_DF_PERFMONS 4 #define AMDGPU_MAX_DF_PERFMONS 4
#define AMDGPU_PRODUCT_NAME_LEN 64
struct amdgpu_reset_domain; struct amdgpu_reset_domain;
struct amdgpu_fru_info;
/* /*
* Non-zero (true) if the GPU has VRAM. Zero (false) otherwise. * Non-zero (true) if the GPU has VRAM. Zero (false) otherwise.
...@@ -1055,11 +1055,7 @@ struct amdgpu_device { ...@@ -1055,11 +1055,7 @@ struct amdgpu_device {
bool ucode_sysfs_en; bool ucode_sysfs_en;
/* Chip product information */ struct amdgpu_fru_info *fru_info;
char product_number[20];
char product_name[AMDGPU_PRODUCT_NAME_LEN];
char serial[20];
atomic_t throttling_logging_enabled; atomic_t throttling_logging_enabled;
struct ratelimit_state throttling_logging_rs; struct ratelimit_state throttling_logging_rs;
uint32_t ras_hw_enabled; uint32_t ras_hw_enabled;
......
...@@ -4274,6 +4274,9 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) ...@@ -4274,6 +4274,9 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
kfree(adev->bios); kfree(adev->bios);
adev->bios = NULL; adev->bios = NULL;
kfree(adev->fru_info);
adev->fru_info = NULL;
px = amdgpu_device_supports_px(adev_to_drm(adev)); px = amdgpu_device_supports_px(adev_to_drm(adev));
if (px || (!pci_is_thunderbolt_attached(adev->pdev) && if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
......
...@@ -109,6 +109,7 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev, u32 *fru_addr) ...@@ -109,6 +109,7 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev, u32 *fru_addr)
int amdgpu_fru_get_product_info(struct amdgpu_device *adev) int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
{ {
struct amdgpu_fru_info *fru_info;
unsigned char buf[8], *pia; unsigned char buf[8], *pia;
u32 addr, fru_addr; u32 addr, fru_addr;
int size, len; int size, len;
...@@ -117,6 +118,19 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) ...@@ -117,6 +118,19 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
if (!is_fru_eeprom_supported(adev, &fru_addr)) if (!is_fru_eeprom_supported(adev, &fru_addr))
return 0; return 0;
if (!adev->fru_info) {
adev->fru_info = kzalloc(sizeof(*adev->fru_info), GFP_KERNEL);
if (!adev->fru_info)
return -ENOMEM;
}
fru_info = adev->fru_info;
/* For Arcturus-and-later, default value of serial_number is unique_id
* so convert it to a 16-digit HEX string for convenience and
* backwards-compatibility.
*/
sprintf(fru_info->serial, "%llx", adev->unique_id);
/* If algo exists, it means that the i2c_adapter's initialized */ /* If algo exists, it means that the i2c_adapter's initialized */
if (!adev->pm.fru_eeprom_i2c_bus || !adev->pm.fru_eeprom_i2c_bus->algo) { if (!adev->pm.fru_eeprom_i2c_bus || !adev->pm.fru_eeprom_i2c_bus->algo) {
DRM_WARN("Cannot access FRU, EEPROM accessor not initialized"); DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
...@@ -192,21 +206,18 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) ...@@ -192,21 +206,18 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
addr = 3 + 1 + (pia[3] & 0x3F); addr = 3 + 1 + (pia[3] & 0x3F);
if (addr + 1 >= len) if (addr + 1 >= len)
goto Out; goto Out;
memcpy(adev->product_name, pia + addr + 1, memcpy(fru_info->product_name, pia + addr + 1,
min_t(size_t, min_t(size_t, sizeof(fru_info->product_name), pia[addr] & 0x3F));
sizeof(adev->product_name), fru_info->product_name[sizeof(fru_info->product_name) - 1] = '\0';
pia[addr] & 0x3F));
adev->product_name[sizeof(adev->product_name) - 1] = '\0';
/* Go to the Product Part/Model Number field. */ /* Go to the Product Part/Model Number field. */
addr += 1 + (pia[addr] & 0x3F); addr += 1 + (pia[addr] & 0x3F);
if (addr + 1 >= len) if (addr + 1 >= len)
goto Out; goto Out;
memcpy(adev->product_number, pia + addr + 1, memcpy(fru_info->product_number, pia + addr + 1,
min_t(size_t, min_t(size_t, sizeof(fru_info->product_number),
sizeof(adev->product_number),
pia[addr] & 0x3F)); pia[addr] & 0x3F));
adev->product_number[sizeof(adev->product_number) - 1] = '\0'; fru_info->product_number[sizeof(fru_info->product_number) - 1] = '\0';
/* Go to the Product Version field. */ /* Go to the Product Version field. */
addr += 1 + (pia[addr] & 0x3F); addr += 1 + (pia[addr] & 0x3F);
...@@ -215,10 +226,9 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) ...@@ -215,10 +226,9 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
addr += 1 + (pia[addr] & 0x3F); addr += 1 + (pia[addr] & 0x3F);
if (addr + 1 >= len) if (addr + 1 >= len)
goto Out; goto Out;
memcpy(adev->serial, pia + addr + 1, min_t(size_t, memcpy(fru_info->serial, pia + addr + 1,
sizeof(adev->serial), min_t(size_t, sizeof(fru_info->serial), pia[addr] & 0x3F));
pia[addr] & 0x3F)); fru_info->serial[sizeof(fru_info->serial) - 1] = '\0';
adev->serial[sizeof(adev->serial) - 1] = '\0';
Out: Out:
kfree(pia); kfree(pia);
return 0; return 0;
...@@ -241,7 +251,7 @@ static ssize_t amdgpu_fru_product_name_show(struct device *dev, ...@@ -241,7 +251,7 @@ static ssize_t amdgpu_fru_product_name_show(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev); struct amdgpu_device *adev = drm_to_adev(ddev);
return sysfs_emit(buf, "%s\n", adev->product_name); return sysfs_emit(buf, "%s\n", adev->fru_info->product_name);
} }
static DEVICE_ATTR(product_name, 0444, amdgpu_fru_product_name_show, NULL); static DEVICE_ATTR(product_name, 0444, amdgpu_fru_product_name_show, NULL);
...@@ -263,7 +273,7 @@ static ssize_t amdgpu_fru_product_number_show(struct device *dev, ...@@ -263,7 +273,7 @@ static ssize_t amdgpu_fru_product_number_show(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev); struct amdgpu_device *adev = drm_to_adev(ddev);
return sysfs_emit(buf, "%s\n", adev->product_number); return sysfs_emit(buf, "%s\n", adev->fru_info->product_number);
} }
static DEVICE_ATTR(product_number, 0444, amdgpu_fru_product_number_show, NULL); static DEVICE_ATTR(product_number, 0444, amdgpu_fru_product_number_show, NULL);
...@@ -285,7 +295,7 @@ static ssize_t amdgpu_fru_serial_number_show(struct device *dev, ...@@ -285,7 +295,7 @@ static ssize_t amdgpu_fru_serial_number_show(struct device *dev,
struct drm_device *ddev = dev_get_drvdata(dev); struct drm_device *ddev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(ddev); struct amdgpu_device *adev = drm_to_adev(ddev);
return sysfs_emit(buf, "%s\n", adev->serial); return sysfs_emit(buf, "%s\n", adev->fru_info->serial);
} }
static DEVICE_ATTR(serial_number, 0444, amdgpu_fru_serial_number_show, NULL); static DEVICE_ATTR(serial_number, 0444, amdgpu_fru_serial_number_show, NULL);
...@@ -299,7 +309,7 @@ static const struct attribute *amdgpu_fru_attributes[] = { ...@@ -299,7 +309,7 @@ static const struct attribute *amdgpu_fru_attributes[] = {
int amdgpu_fru_sysfs_init(struct amdgpu_device *adev) int amdgpu_fru_sysfs_init(struct amdgpu_device *adev)
{ {
if (!is_fru_eeprom_supported(adev, NULL)) if (!is_fru_eeprom_supported(adev, NULL) || !adev->fru_info)
return 0; return 0;
return sysfs_create_files(&adev->dev->kobj, amdgpu_fru_attributes); return sysfs_create_files(&adev->dev->kobj, amdgpu_fru_attributes);
...@@ -307,7 +317,7 @@ int amdgpu_fru_sysfs_init(struct amdgpu_device *adev) ...@@ -307,7 +317,7 @@ int amdgpu_fru_sysfs_init(struct amdgpu_device *adev)
void amdgpu_fru_sysfs_fini(struct amdgpu_device *adev) void amdgpu_fru_sysfs_fini(struct amdgpu_device *adev)
{ {
if (!is_fru_eeprom_supported(adev, NULL)) if (!is_fru_eeprom_supported(adev, NULL) || !adev->fru_info)
return; return;
sysfs_remove_files(&adev->dev->kobj, amdgpu_fru_attributes); sysfs_remove_files(&adev->dev->kobj, amdgpu_fru_attributes);
......
...@@ -24,6 +24,15 @@ ...@@ -24,6 +24,15 @@
#ifndef __AMDGPU_FRU_EEPROM_H__ #ifndef __AMDGPU_FRU_EEPROM_H__
#define __AMDGPU_FRU_EEPROM_H__ #define __AMDGPU_FRU_EEPROM_H__
#define AMDGPU_PRODUCT_NAME_LEN 64
/* FRU product information */
struct amdgpu_fru_info {
char product_number[20];
char product_name[AMDGPU_PRODUCT_NAME_LEN];
char serial[20];
};
int amdgpu_fru_get_product_info(struct amdgpu_device *adev); int amdgpu_fru_get_product_info(struct amdgpu_device *adev);
int amdgpu_fru_sysfs_init(struct amdgpu_device *adev); int amdgpu_fru_sysfs_init(struct amdgpu_device *adev);
void amdgpu_fru_sysfs_fini(struct amdgpu_device *adev); void amdgpu_fru_sysfs_fini(struct amdgpu_device *adev);
......
...@@ -2192,10 +2192,6 @@ static void arcturus_get_unique_id(struct smu_context *smu) ...@@ -2192,10 +2192,6 @@ static void arcturus_get_unique_id(struct smu_context *smu)
id = ((uint64_t)bottom32 << 32) | top32; id = ((uint64_t)bottom32 << 32) | top32;
adev->unique_id = id; 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
*/
sprintf(adev->serial, "%llx", id);
} }
static int arcturus_set_df_cstate(struct smu_context *smu, static int arcturus_set_df_cstate(struct smu_context *smu,
......
...@@ -1996,8 +1996,6 @@ static void sienna_cichlid_get_unique_id(struct smu_context *smu) ...@@ -1996,8 +1996,6 @@ static void sienna_cichlid_get_unique_id(struct smu_context *smu)
out: out:
adev->unique_id = ((uint64_t)upper32 << 32) | lower32; adev->unique_id = ((uint64_t)upper32 << 32) | lower32;
if (adev->serial[0] == '\0')
sprintf(adev->serial, "%016llx", adev->unique_id);
} }
static int sienna_cichlid_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states) static int sienna_cichlid_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states)
......
...@@ -1578,8 +1578,6 @@ static void aldebaran_get_unique_id(struct smu_context *smu) ...@@ -1578,8 +1578,6 @@ static void aldebaran_get_unique_id(struct smu_context *smu)
out: out:
adev->unique_id = ((uint64_t)upper32 << 32) | lower32; adev->unique_id = ((uint64_t)upper32 << 32) | lower32;
if (adev->serial[0] == '\0')
sprintf(adev->serial, "%016llx", adev->unique_id);
} }
static bool aldebaran_is_baco_supported(struct smu_context *smu) static bool aldebaran_is_baco_supported(struct smu_context *smu)
......
...@@ -2264,8 +2264,6 @@ static void smu_v13_0_0_get_unique_id(struct smu_context *smu) ...@@ -2264,8 +2264,6 @@ static void smu_v13_0_0_get_unique_id(struct smu_context *smu)
out: out:
adev->unique_id = ((uint64_t)upper32 << 32) | lower32; adev->unique_id = ((uint64_t)upper32 << 32) | lower32;
if (adev->serial[0] == '\0')
sprintf(adev->serial, "%016llx", adev->unique_id);
} }
static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu, static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu,
......
...@@ -1880,8 +1880,6 @@ static void smu_v13_0_6_get_unique_id(struct smu_context *smu) ...@@ -1880,8 +1880,6 @@ static void smu_v13_0_6_get_unique_id(struct smu_context *smu)
(struct PPTable_t *)smu_table->driver_pptable; (struct PPTable_t *)smu_table->driver_pptable;
adev->unique_id = pptable->PublicSerialNumber_AID; adev->unique_id = pptable->PublicSerialNumber_AID;
if (adev->serial[0] == '\0')
sprintf(adev->serial, "%016llx", adev->unique_id);
} }
static bool smu_v13_0_6_is_baco_supported(struct smu_context *smu) static bool smu_v13_0_6_is_baco_supported(struct smu_context *smu)
......
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