Commit 73a5784a authored by Aaron Rice's avatar Aaron Rice Committed by Alex Deucher

drm/amdgpu: rework smu11 i2c for generic operation

Handle things besides EEPROMS.
Signed-off-by: default avatarAaron Rice <wolf@lovehindpa.ws>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarLuben Tuikov <luben.tuikov@amd.com>
parent 3e2eae8d
...@@ -117,8 +117,7 @@ static void smu_v11_0_i2c_set_address(struct i2c_adapter *control, uint8_t addre ...@@ -117,8 +117,7 @@ static void smu_v11_0_i2c_set_address(struct i2c_adapter *control, uint8_t addre
{ {
struct amdgpu_device *adev = to_amdgpu_device(control); struct amdgpu_device *adev = to_amdgpu_device(control);
/* Convert fromr 8-bit to 7-bit address */ /* We take 7-bit addresses raw */
address >>= 1;
WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_TAR, (address & 0xFF)); WREG32_SOC15(SMUIO, 0, mmCKSVII2C_IC_TAR, (address & 0xFF));
} }
...@@ -531,22 +530,14 @@ static bool smu_v11_0_i2c_bus_unlock(struct i2c_adapter *control) ...@@ -531,22 +530,14 @@ static bool smu_v11_0_i2c_bus_unlock(struct i2c_adapter *control)
/***************************** I2C GLUE ****************************/ /***************************** I2C GLUE ****************************/
static uint32_t smu_v11_0_i2c_read_data(struct i2c_adapter *control, static uint32_t smu_v11_0_i2c_read_data(struct i2c_adapter *control,
uint8_t address, struct i2c_msg *msg)
uint8_t *data,
uint32_t numbytes)
{ {
uint32_t ret = 0; uint32_t ret = 0;
/* First 2 bytes are dummy write to set EEPROM address */
ret = smu_v11_0_i2c_transmit(control, address, data, 2, I2C_NO_STOP);
if (ret != I2C_OK)
goto Fail;
/* Now read data starting with that address */ /* Now read data starting with that address */
ret = smu_v11_0_i2c_receive(control, address, data + 2, numbytes - 2, ret = smu_v11_0_i2c_receive(control, msg->addr, msg->buf, msg->len,
I2C_RESTART); I2C_RESTART);
Fail:
if (ret != I2C_OK) if (ret != I2C_OK)
DRM_ERROR("ReadData() - I2C error occurred :%x", ret); DRM_ERROR("ReadData() - I2C error occurred :%x", ret);
...@@ -554,28 +545,16 @@ static uint32_t smu_v11_0_i2c_read_data(struct i2c_adapter *control, ...@@ -554,28 +545,16 @@ static uint32_t smu_v11_0_i2c_read_data(struct i2c_adapter *control,
} }
static uint32_t smu_v11_0_i2c_write_data(struct i2c_adapter *control, static uint32_t smu_v11_0_i2c_write_data(struct i2c_adapter *control,
uint8_t address, struct i2c_msg *msg)
uint8_t *data,
uint32_t numbytes)
{ {
uint32_t ret; uint32_t ret;
ret = smu_v11_0_i2c_transmit(control, address, data, numbytes, 0); /* Send I2C_NO_STOP unless requested to stop. */
ret = smu_v11_0_i2c_transmit(control, msg->addr, msg->buf, msg->len, ((msg->flags & I2C_M_STOP) ? 0 : I2C_NO_STOP));
if (ret != I2C_OK) if (ret != I2C_OK)
DRM_ERROR("WriteI2CData() - I2C error occurred :%x", ret); DRM_ERROR("WriteI2CData() - I2C error occurred :%x", ret);
else
/*
* According to EEPROM spec there is a MAX of 10 ms required for
* EEPROM to flush internal RX buffer after STOP was issued at the
* end of write transaction. During this time the EEPROM will not be
* responsive to any more commands - so wait a bit more.
*
* TODO Improve to wait for first ACK for slave address after
* internal write cycle done.
*/
msleep(10);
return ret; return ret;
} }
...@@ -618,24 +597,16 @@ static int smu_v11_0_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -618,24 +597,16 @@ static int smu_v11_0_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num) struct i2c_msg *msgs, int num)
{ {
int i, ret; int i, ret;
struct amdgpu_device *adev = to_amdgpu_device(i2c_adap);
if (!adev->pm.bus_locked) {
DRM_ERROR("I2C bus unlocked, stopping transaction!");
return -EIO;
}
smu_v11_0_i2c_init(i2c_adap); smu_v11_0_i2c_init(i2c_adap);
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
if (msgs[i].flags & I2C_M_RD) if (msgs[i].flags & I2C_M_RD)
ret = smu_v11_0_i2c_read_data(i2c_adap, ret = smu_v11_0_i2c_read_data(i2c_adap,
(uint8_t)msgs[i].addr, msgs + i);
msgs[i].buf, msgs[i].len);
else else
ret = smu_v11_0_i2c_write_data(i2c_adap, ret = smu_v11_0_i2c_write_data(i2c_adap,
(uint8_t)msgs[i].addr, msgs + i);
msgs[i].buf, msgs[i].len);
if (ret != I2C_OK) { if (ret != I2C_OK) {
num = -EIO; num = -EIO;
......
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