drm/amdgpu: Refactor FRU product information
authorLijo Lazar <lijo.lazar@amd.com>
Wed, 4 Oct 2023 10:30:47 +0000 (16:00 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 9 Oct 2023 20:52:08 +0000 (16:52 -0400)
Keep FRU related information together in a separate structure.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.h
drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c

index daec39387f7019b9f611ef718f6904fc2083f91d..6b89d92e22a47e6311e16a006d64908a6247d10b 100644 (file)
@@ -770,8 +770,8 @@ struct amdgpu_mqd {
 
 #define AMDGPU_RESET_MAGIC_NUM 64
 #define AMDGPU_MAX_DF_PERFMONS 4
-#define AMDGPU_PRODUCT_NAME_LEN 64
 struct amdgpu_reset_domain;
+struct amdgpu_fru_info;
 
 /*
  * Non-zero (true) if the GPU has VRAM. Zero (false) otherwise.
@@ -1055,11 +1055,7 @@ struct amdgpu_device {
 
        bool                            ucode_sysfs_en;
 
-       /* Chip product information */
-       char                            product_number[20];
-       char                            product_name[AMDGPU_PRODUCT_NAME_LEN];
-       char                            serial[20];
-
+       struct amdgpu_fru_info          *fru_info;
        atomic_t                        throttling_logging_enabled;
        struct ratelimit_state          throttling_logging_rs;
        uint32_t                        ras_hw_enabled;
index 27c95bb024110e0b4d5184624ae2d56961047a48..0cb702c3046a9c23c97dc84da4f94d13d02c4d7a 100644 (file)
@@ -4274,6 +4274,9 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
        kfree(adev->bios);
        adev->bios = NULL;
 
+       kfree(adev->fru_info);
+       adev->fru_info = NULL;
+
        px = amdgpu_device_supports_px(adev_to_drm(adev));
 
        if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
index d0ae9cada11054381bb71950fe9ba74f999889b1..79ba74dfc5764c7591953c393e08d211e2722ce1 100644 (file)
@@ -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)
 {
+       struct amdgpu_fru_info *fru_info;
        unsigned char buf[8], *pia;
        u32 addr, fru_addr;
        int size, len;
@@ -117,6 +118,19 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
        if (!is_fru_eeprom_supported(adev, &fru_addr))
                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 (!adev->pm.fru_eeprom_i2c_bus || !adev->pm.fru_eeprom_i2c_bus->algo) {
                DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
@@ -192,21 +206,18 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
        addr = 3 + 1 + (pia[3] & 0x3F);
        if (addr + 1 >= len)
                goto Out;
-       memcpy(adev->product_name, pia + addr + 1,
-              min_t(size_t,
-                    sizeof(adev->product_name),
-                    pia[addr] & 0x3F));
-       adev->product_name[sizeof(adev->product_name) - 1] = '\0';
+       memcpy(fru_info->product_name, pia + addr + 1,
+              min_t(size_t, sizeof(fru_info->product_name), pia[addr] & 0x3F));
+       fru_info->product_name[sizeof(fru_info->product_name) - 1] = '\0';
 
        /* Go to the Product Part/Model Number field. */
        addr += 1 + (pia[addr] & 0x3F);
        if (addr + 1 >= len)
                goto Out;
-       memcpy(adev->product_number, pia + addr + 1,
-              min_t(size_t,
-                    sizeof(adev->product_number),
+       memcpy(fru_info->product_number, pia + addr + 1,
+              min_t(size_t, sizeof(fru_info->product_number),
                     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. */
        addr += 1 + (pia[addr] & 0x3F);
@@ -215,10 +226,9 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
        addr += 1 + (pia[addr] & 0x3F);
        if (addr + 1 >= len)
                goto Out;
-       memcpy(adev->serial, pia + addr + 1, min_t(size_t,
-                                                  sizeof(adev->serial),
-                                                  pia[addr] & 0x3F));
-       adev->serial[sizeof(adev->serial) - 1] = '\0';
+       memcpy(fru_info->serial, pia + addr + 1,
+              min_t(size_t, sizeof(fru_info->serial), pia[addr] & 0x3F));
+       fru_info->serial[sizeof(fru_info->serial) - 1] = '\0';
 Out:
        kfree(pia);
        return 0;
@@ -241,7 +251,7 @@ static ssize_t amdgpu_fru_product_name_show(struct device *dev,
        struct drm_device *ddev = dev_get_drvdata(dev);
        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);
@@ -263,7 +273,7 @@ static ssize_t amdgpu_fru_product_number_show(struct device *dev,
        struct drm_device *ddev = dev_get_drvdata(dev);
        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);
@@ -285,7 +295,7 @@ static ssize_t amdgpu_fru_serial_number_show(struct device *dev,
        struct drm_device *ddev = dev_get_drvdata(dev);
        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);
@@ -299,7 +309,7 @@ static const struct attribute *amdgpu_fru_attributes[] = {
 
 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 sysfs_create_files(&adev->dev->kobj, amdgpu_fru_attributes);
@@ -307,7 +317,7 @@ int amdgpu_fru_sysfs_init(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;
 
        sysfs_remove_files(&adev->dev->kobj, amdgpu_fru_attributes);
index c817db17cfa75a6efe9abaecb02560eff0ba4aed..c99c74811c78a3af1b315f554f2b80d10f4f7613 100644 (file)
 #ifndef __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_sysfs_init(struct amdgpu_device *adev);
 void amdgpu_fru_sysfs_fini(struct amdgpu_device *adev);
index a2bbc180b160f48bb436a869af257aece8100675..44e4289b95cddccd0d6f961e9284c5fbc32cc6de 100644 (file)
@@ -2192,10 +2192,6 @@ static void arcturus_get_unique_id(struct smu_context *smu)
 
        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
-        */
-       sprintf(adev->serial, "%llx", id);
 }
 
 static int arcturus_set_df_cstate(struct smu_context *smu,
index ad2884088e69dd905ac02376b62eb09b9a2c8f59..28868f64d1340de336bed195ad87d6f89b851dae 100644 (file)
@@ -1996,8 +1996,6 @@ static void sienna_cichlid_get_unique_id(struct smu_context *smu)
 out:
 
        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)
index b57184a3e24f4920100b75831cc9872c233bc6b7..2373a66c7efd07860436d36bbf282d1bae057c16 100644 (file)
@@ -1578,8 +1578,6 @@ static void aldebaran_get_unique_id(struct smu_context *smu)
 
 out:
        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)
index 9f8ad46e27bba93694fac8ea10bf019837635adb..5c5a4631c945e52345d93fbcaa786ebbe3a9b331 100644 (file)
@@ -2264,8 +2264,6 @@ static void smu_v13_0_0_get_unique_id(struct smu_context *smu)
 
 out:
        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,
index ce971a93d28b63fa3e3d7a071c0a8229ad35ac56..bf01a23f399a170d6c6d9fe9169a346d8243e6d3 100644 (file)
@@ -1880,8 +1880,6 @@ static void smu_v13_0_6_get_unique_id(struct smu_context *smu)
                (struct PPTable_t *)smu_table->driver_pptable;
 
        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)