Commit 9015d60c authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher
Browse files

drm/amdgpu: Move EEPROM I2C adapter to amdgpu_device



Puts the i2c adapter in common place for sharing by RAS
and upcoming data read from FRU EEPROM feature.

v2:
Move i2c adapter to amdgpu_pm and rename it.

v3: Move i2c adapter init to ASIC specific code and get rid
of the switch case in amdgpu_device

Signed-off-by: default avatarAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 57210c19
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -448,6 +448,8 @@ struct amdgpu_pm {
	/* powerplay feature */
	uint32_t pp_feature;

	/* Used for I2C access to various EEPROMs on relevant ASICs */
	struct i2c_adapter smu_i2c;
};

#define R600_SSTU_DFLT                               0
+8 −40
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@
#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_VEGA20    	0xA0
@@ -124,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,
@@ -137,7 +137,7 @@ 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);

@@ -251,33 +251,18 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control)
			.buf	= buff,
	};

	/* Verify i2c adapter is initialized */
	if (!adev->pm.smu_i2c.algo)
		return -ENOENT;

	if (!__get_eeprom_i2c_addr(adev, &control->i2c_address))
		return -EINVAL;

	mutex_init(&control->tbl_mutex);

	switch (adev->asic_type) {
	case CHIP_VEGA20:
		ret = smu_v11_0_i2c_eeprom_control_init(&control->eeprom_accessor);
		break;

	case CHIP_ARCTURUS:
		ret = smu_i2c_eeprom_init(&adev->smu, &control->eeprom_accessor);
		break;

	default:
		return 0;
	}

	if (ret) {
		DRM_ERROR("Failed to init I2C controller, ret:%d", ret);
		return ret;
	}

	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;
@@ -303,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)
@@ -476,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);

+0 −2
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ struct amdgpu_ras_eeprom_table_header {

struct amdgpu_ras_eeprom_control {
	struct amdgpu_ras_eeprom_table_header tbl_hdr;
	struct i2c_adapter eeprom_accessor;
	uint32_t next_addr;
	unsigned int num_recs;
	struct mutex tbl_mutex;
@@ -79,7 +78,6 @@ struct eeprom_table_record {
}__attribute__((__packed__));

int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control);
void amdgpu_ras_eeprom_fini(struct amdgpu_ras_eeprom_control *control);
int amdgpu_ras_eeprom_reset_table(struct amdgpu_ras_eeprom_control *control);

int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
+8 −6
Original line number Diff line number Diff line
@@ -46,8 +46,7 @@
#define I2C_NO_STOP	1
#define I2C_RESTART	2

#define to_amdgpu_device(x) (container_of(x, struct amdgpu_ras, eeprom_control.eeprom_accessor))->adev
#define to_eeprom_control(x) container_of(x, struct amdgpu_ras_eeprom_control, eeprom_accessor)
#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))

static void smu_v11_0_i2c_set_clock_gating(struct i2c_adapter *control, bool en)
{
@@ -592,7 +591,8 @@ static uint32_t smu_v11_0_i2c_eeprom_write_data(struct i2c_adapter *control,

static void lock_bus(struct i2c_adapter *i2c, unsigned int flags)
{
	struct amdgpu_ras_eeprom_control *control = to_eeprom_control(i2c);
	struct amdgpu_device *adev = to_amdgpu_device(i2c);
	struct amdgpu_ras_eeprom_control *control = &adev->psp.ras.ras->eeprom_control;

	if (!smu_v11_0_i2c_bus_lock(i2c)) {
		DRM_ERROR("Failed to lock the bus from SMU");
@@ -610,7 +610,8 @@ static int trylock_bus(struct i2c_adapter *i2c, unsigned int flags)

static void unlock_bus(struct i2c_adapter *i2c, unsigned int flags)
{
	struct amdgpu_ras_eeprom_control *control = to_eeprom_control(i2c);
	struct amdgpu_device *adev = to_amdgpu_device(i2c);
	struct amdgpu_ras_eeprom_control *control = &adev->psp.ras.ras->eeprom_control;

	if (!smu_v11_0_i2c_bus_unlock(i2c)) {
		DRM_ERROR("Failed to unlock the bus from SMU");
@@ -630,7 +631,8 @@ static int smu_v11_0_i2c_eeprom_i2c_xfer(struct i2c_adapter *i2c_adap,
			      struct i2c_msg *msgs, int num)
{
	int i, ret;
	struct amdgpu_ras_eeprom_control *control = to_eeprom_control(i2c_adap);
	struct amdgpu_device *adev = to_amdgpu_device(i2c_adap);
	struct amdgpu_ras_eeprom_control *control = &adev->psp.ras.ras->eeprom_control;

	if (!control->bus_locked) {
		DRM_ERROR("I2C bus unlocked, stopping transaction!");
@@ -679,7 +681,7 @@ int smu_v11_0_i2c_eeprom_control_init(struct i2c_adapter *control)
	control->class = I2C_CLASS_SPD;
	control->dev.parent = &adev->pdev->dev;
	control->algo = &smu_v11_0_i2c_eeprom_i2c_algo;
	snprintf(control->name, sizeof(control->name), "RAS EEPROM");
	snprintf(control->name, sizeof(control->name), "AMDGPU EEPROM");
	control->lock_ops = &smu_v11_0_i2c_i2c_lock_ops;

	res = i2c_add_adapter(control);
+10 −0
Original line number Diff line number Diff line
@@ -932,6 +932,13 @@ static int smu_sw_init(void *handle)
		return ret;
	}

	if (adev->smu.ppt_funcs->i2c_eeprom_init) {
		ret = smu_i2c_eeprom_init(smu, &adev->pm.smu_i2c);

		if (ret)
			return ret;
	}

	return 0;
}

@@ -941,6 +948,9 @@ static int smu_sw_fini(void *handle)
	struct smu_context *smu = &adev->smu;
	int ret;

	if (adev->smu.ppt_funcs->i2c_eeprom_fini)
		smu_i2c_eeprom_fini(smu, &adev->pm.smu_i2c);

	kfree(smu->irq_source);
	smu->irq_source = NULL;

Loading