diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 98 | 
1 files changed, 53 insertions, 45 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index 2a8e04895595..c0096097bbcf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -25,10 +25,11 @@  #include "amdgpu.h"  #include "amdgpu_ras.h"  #include <linux/bits.h> -#include "smu_v11_0_i2c.h" +#include "atom.h" -#define EEPROM_I2C_TARGET_ADDR_ARCTURUS  0xA8 -#define EEPROM_I2C_TARGET_ADDR_VEGA20    0xA0 +#define EEPROM_I2C_TARGET_ADDR_VEGA20    	0xA0 +#define EEPROM_I2C_TARGET_ADDR_ARCTURUS  	0xA8 +#define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342  	0xA0  /*   * The 2 macros bellow represent the actual size in bytes that @@ -55,6 +56,45 @@  #define to_amdgpu_device(x) (container_of(x, struct amdgpu_ras, eeprom_control))->adev +static bool __get_eeprom_i2c_addr_arct(struct amdgpu_device *adev, +				       uint16_t *i2c_addr) +{ +	struct atom_context *atom_ctx = adev->mode_info.atom_context; + +	if (!i2c_addr || !atom_ctx) +		return false; + +	if (strnstr(atom_ctx->vbios_version, +	            "D342", +		    sizeof(atom_ctx->vbios_version))) +		*i2c_addr = EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342; +	else +		*i2c_addr = EEPROM_I2C_TARGET_ADDR_ARCTURUS; + +	return true; +} + +static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, +				  uint16_t *i2c_addr) +{ +	if (!i2c_addr) +		return false; + +	switch (adev->asic_type) { +	case CHIP_VEGA20: +		*i2c_addr = EEPROM_I2C_TARGET_ADDR_VEGA20; +		break; + +	case CHIP_ARCTURUS: +		return __get_eeprom_i2c_addr_arct(adev, i2c_addr); + +	default: +		return false; +	} + +	return true; +} +  static void __encode_table_header_to_buff(struct amdgpu_ras_eeprom_table_header *hdr,  					  unsigned char *buff)  { @@ -83,6 +123,7 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control,  				 unsigned char *buff)  {  	int ret = 0; +	struct amdgpu_device *adev = to_amdgpu_device(control);  	struct i2c_msg msg = {  			.addr	= 0,  			.flags	= 0, @@ -96,15 +137,13 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control,  	msg.addr = control->i2c_address; -	ret = i2c_transfer(&control->eeprom_accessor, &msg, 1); +	ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1);  	if (ret < 1)  		DRM_ERROR("Failed to write EEPROM table header, ret:%d", ret);  	return ret;  } - -  static uint32_t  __calc_hdr_byte_sum(struct amdgpu_ras_eeprom_control *control)  {  	int i; @@ -212,32 +251,18 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)  			.buf	= buff,  	}; -	mutex_init(&control->tbl_mutex); - -	switch (adev->asic_type) { -	case CHIP_VEGA20: -		control->i2c_address = EEPROM_I2C_TARGET_ADDR_VEGA20; -		ret = smu_v11_0_i2c_eeprom_control_init(&control->eeprom_accessor); -		break; - -	case CHIP_ARCTURUS: -		control->i2c_address = EEPROM_I2C_TARGET_ADDR_ARCTURUS; -		ret = smu_i2c_eeprom_init(&adev->smu, &control->eeprom_accessor); -		break; +	/* Verify i2c adapter is initialized */ +	if (!adev->pm.smu_i2c.algo) +		return -ENOENT; -	default: -		return 0; -	} +	if (!__get_eeprom_i2c_addr(adev, &control->i2c_address)) +		return -EINVAL; -	if (ret) { -		DRM_ERROR("Failed to init I2C controller, ret:%d", ret); -		return ret; -	} +	mutex_init(&control->tbl_mutex);  	msg.addr = control->i2c_address; -  	/* Read/Create table header from EEPROM address 0 */ -	ret = i2c_transfer(&control->eeprom_accessor, &msg, 1); +	ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1);  	if (ret < 1) {  		DRM_ERROR("Failed to read EEPROM table header, ret:%d", ret);  		return ret; @@ -263,23 +288,6 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)  	return ret == 1 ? 0 : -EIO;  } -void amdgpu_ras_eeprom_fini(struct amdgpu_ras_eeprom_control *control) -{ -	struct amdgpu_device *adev = to_amdgpu_device(control); - -	switch (adev->asic_type) { -	case CHIP_VEGA20: -		smu_v11_0_i2c_eeprom_control_fini(&control->eeprom_accessor); -		break; -	case CHIP_ARCTURUS: -		smu_i2c_eeprom_fini(&adev->smu, &control->eeprom_accessor); -		break; - -	default: -		return; -	} -} -  static void __encode_table_record_to_buff(struct amdgpu_ras_eeprom_control *control,  					  struct eeprom_table_record *record,  					  unsigned char *buff) @@ -436,7 +444,7 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,  		control->next_addr += EEPROM_TABLE_RECORD_SIZE;  	} -	ret = i2c_transfer(&control->eeprom_accessor, msgs, num); +	ret = i2c_transfer(&adev->pm.smu_i2c, msgs, num);  	if (ret < 1) {  		DRM_ERROR("Failed to process EEPROM table records, ret:%d", ret);  | 
