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>
This commit is contained in:
parent
3e2eae8db2
commit
73a5784a5b
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue