summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2022-02-14 10:31:51 +1000
committerDave Airlie <airlied@redhat.com>2022-02-14 10:31:51 +1000
commit123db17ddff007080d464e785689fb14f94cbc7a (patch)
tree11da22fd6a508e496be838e43e0b504266c4a4d3 /drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
parente7a09cea6483b44ea0c82f07145fcbd8a918bf96 (diff)
parent7f161df1a513e2961f4e3c96a8355c8ce93ad175 (diff)
downloadlinux-123db17ddff007080d464e785689fb14f94cbc7a.tar.bz2
Merge tag 'amd-drm-next-5.18-2022-02-11-1' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.18-2022-02-11-1: amdgpu: - Clean up of power management code - Enable freesync video mode by default - Clean up of RAS code - Improve VRAM access for debug using SDMA - Coding style cleanups - SR-IOV fixes - More display FP reorg - TLB flush fixes for Arcuturus, Vega20 - Misc display fixes - Rework special register access methods for SR-IOV - DP2 fixes - DP tunneling fixes - DSC fixes - More IP discovery cleanups - Misc RAS fixes - Enable both SMU i2c buses where applicable - s2idle improvements - DPCS header cleanup - Add new CAP firmware support for SR-IOV amdkfd: - Misc cleanups - SVM fixes - CRIU support - Clean up MQD manager UAPI: - Add interface to amdgpu CTX ioctl to request a stable power state for profiling https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/207 - Add amdkfd support for CRIU https://github.com/checkpoint-restore/criu/pull/1709 - Remove old unused amdkfd debugger interface Was only implemented for Kaveri and was only ever used by an old HSA tool that was never open sourced radeon: - Fix error handling in radeon_driver_open_kms - UVD suspend fix - Misc fixes From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220211220706.5803-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
index 2a786e788627..ecada5eadfe3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c
@@ -30,7 +30,6 @@
#include "amdgpu_eeprom.h"
#define FRU_EEPROM_MADDR 0x60000
-#define I2C_PRODUCT_INFO_OFFSET 0xC0
static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
{
@@ -40,7 +39,13 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
*/
struct atom_context *atom_ctx = adev->mode_info.atom_context;
- /* VBIOS is of the format ###-DXXXYY-##. For SKU identification,
+ /* The i2c access is blocked on VF
+ * TODO: Need other way to get the info
+ */
+ if (amdgpu_sriov_vf(adev))
+ return false;
+
+ /* VBIOS is of the format ###-DXXXYYYY-##. For SKU identification,
* we can use just the "DXXX" portion. If there were more models, we
* could convert the 3 characters to a hex integer and use a switch
* for ease/speed/readability. For now, 2 string comparisons are
@@ -59,17 +64,24 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
case CHIP_ALDEBARAN:
/* All Aldebaran SKUs have the FRU */
return true;
+ case CHIP_SIENNA_CICHLID:
+ if (strnstr(atom_ctx->vbios_version, "D603",
+ sizeof(atom_ctx->vbios_version)))
+ return true;
+ else
+ return false;
default:
return false;
}
}
static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
- unsigned char *buff)
+ unsigned char *buf, size_t buf_size)
{
- int ret, size;
+ int ret;
+ u8 size;
- ret = amdgpu_eeprom_read(&adev->pm.smu_i2c, addrptr, buff, 1);
+ ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr, buf, 1);
if (ret < 1) {
DRM_WARN("FRU: Failed to get size field");
return ret;
@@ -78,9 +90,11 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
/* The size returned by the i2c requires subtraction of 0xC0 since the
* size apparently always reports as 0xC0+actual size.
*/
- size = buff[0] - I2C_PRODUCT_INFO_OFFSET;
+ size = buf[0] & 0x3F;
+ size = min_t(size_t, size, buf_size);
- ret = amdgpu_eeprom_read(&adev->pm.smu_i2c, addrptr + 1, buff, size);
+ ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr + 1,
+ buf, size);
if (ret < 1) {
DRM_WARN("FRU: Failed to get data field");
return ret;
@@ -91,19 +105,15 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
{
- unsigned char buff[AMDGPU_PRODUCT_NAME_LEN+2];
+ unsigned char buf[AMDGPU_PRODUCT_NAME_LEN];
u32 addrptr;
int size, len;
- int offset = 2;
if (!is_fru_eeprom_supported(adev))
return 0;
- if (adev->asic_type == CHIP_ALDEBARAN)
- offset = 0;
-
/* If algo exists, it means that the i2c_adapter's initialized */
- if (!adev->pm.smu_i2c.algo) {
+ if (!adev->pm.fru_eeprom_i2c_bus || !adev->pm.fru_eeprom_i2c_bus->algo) {
DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
return -ENODEV;
}
@@ -121,7 +131,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
* and the language field, so just start from 0xb, manufacturer size
*/
addrptr = FRU_EEPROM_MADDR + 0xb;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
return -EINVAL;
@@ -131,7 +141,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
* size field being 1 byte. This pattern continues below.
*/
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product name, ret:%d", size);
return -EINVAL;
@@ -143,12 +153,11 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
AMDGPU_PRODUCT_NAME_LEN);
len = AMDGPU_PRODUCT_NAME_LEN - 1;
}
- /* Start at 2 due to buff using fields 0 and 1 for the address */
- memcpy(adev->product_name, &buff[offset], len);
+ memcpy(adev->product_name, buf, len);
adev->product_name[len] = '\0';
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product number, ret:%d", size);
return -EINVAL;
@@ -162,11 +171,11 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake");
len = sizeof(adev->product_number) - 1;
}
- memcpy(adev->product_number, &buff[offset], len);
+ memcpy(adev->product_number, buf, len);
adev->product_number[len] = '\0';
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product version, ret:%d", size);
@@ -174,7 +183,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
}
addrptr += size + 1;
- size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
+ size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU serial number, ret:%d", size);
@@ -189,7 +198,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake");
len = sizeof(adev->serial) - 1;
}
- memcpy(adev->serial, &buff[offset], len);
+ memcpy(adev->serial, buf, len);
adev->serial[len] = '\0';
return 0;