summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
diff options
context:
space:
mode:
authorAaron Rice <wolf@lovehindpa.ws>2021-01-21 23:45:54 -0500
committerAlex Deucher <alexander.deucher@amd.com>2021-07-01 00:24:39 -0400
commit73a5784a5bd0b4e8bfe5dbed1a6b7936bf1005e3 (patch)
treecf0da1544d218beb290352a33729cfade0d220c5 /drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
parent3e2eae8db2169c4caea8ae7d2701ef8c1871ac92 (diff)
downloadlinux-stable-73a5784a5bd0b4e8bfe5dbed1a6b7936bf1005e3.tar.gz
linux-stable-73a5784a5bd0b4e8bfe5dbed1a6b7936bf1005e3.tar.bz2
linux-stable-73a5784a5bd0b4e8bfe5dbed1a6b7936bf1005e3.zip
drm/amdgpu: rework smu11 i2c for generic operation
Handle things besides EEPROMS. Signed-off-by: Aaron Rice <wolf@lovehindpa.ws> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c47
1 files changed, 9 insertions, 38 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c b/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
index 3a164d93c902..3193d566f4f8 100644
--- a/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
+++ b/drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c
@@ -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);
- /* Convert fromr 8-bit to 7-bit address */
- address >>= 1;
+ /* We take 7-bit addresses raw */
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)
/***************************** I2C GLUE ****************************/
static uint32_t smu_v11_0_i2c_read_data(struct i2c_adapter *control,
- uint8_t address,
- uint8_t *data,
- uint32_t numbytes)
+ struct i2c_msg *msg)
{
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 */
- 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);
-Fail:
if (ret != I2C_OK)
DRM_ERROR("ReadData() - I2C error occurred :%x", ret);
@@ -554,28 +545,16 @@ Fail:
}
static uint32_t smu_v11_0_i2c_write_data(struct i2c_adapter *control,
- uint8_t address,
- uint8_t *data,
- uint32_t numbytes)
+ struct i2c_msg *msg)
{
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)
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;
}
@@ -618,24 +597,16 @@ static int smu_v11_0_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num)
{
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);
for (i = 0; i < num; i++) {
if (msgs[i].flags & I2C_M_RD)
ret = smu_v11_0_i2c_read_data(i2c_adap,
- (uint8_t)msgs[i].addr,
- msgs[i].buf, msgs[i].len);
+ msgs + i);
else
ret = smu_v11_0_i2c_write_data(i2c_adap,
- (uint8_t)msgs[i].addr,
- msgs[i].buf, msgs[i].len);
+ msgs + i);
if (ret != I2C_OK) {
num = -EIO;