diff options
author | Tom Rini <trini@konsulko.com> | 2022-03-16 12:52:02 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-03-16 12:52:02 -0400 |
commit | 297e6eb8dcf9d90aaf9b0d146cdd502403003d04 (patch) | |
tree | a08774cdaa4a72af892d4c7a57b3e1307734ad89 /drivers/i2c/i2c-cdns.c | |
parent | c24b4e4fb8810b496e5f303ffd2641293f4c4b50 (diff) | |
parent | 0ac03fbab51c72fa978569a831c001c4ddad8e2a (diff) |
Merge tag 'xilinx-for-v2022.07-rc1' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into next
Xilinx changes for v2022.07-rc1
microblaze:
- Add support for reserved memory
xilinx:
- Update FRU code with MAC reading
zynqmp:
- Remove double AMS setting
- DT updates (mostly for SOMs)
- Add support for zcu106 rev 1.0
zynq:
- Update nand binding
nand:
- Aligned zynq_nand to upstream DT binding
net:
- Add support for ethernet-phy-id
mmc:
- Workaround CD in zynq_sdhci driver also for ZynqMP
- Add support for dynamic/run-time SD config for SOMs
gpio:
- Add driver for slg7xl45106
firmware:
- Add support for dynamic SD config
power-domain:
- Update zynqmp driver with the latest firmware
video:
- Add skeleton driver for DP and DPDMA
i2c:
- Fix i2c to work with QEMU
pinctrl:
- Add driver for zynqmp pinctrl driver
Diffstat (limited to 'drivers/i2c/i2c-cdns.c')
-rw-r--r-- | drivers/i2c/i2c-cdns.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index a650dd69b89..0da9f6f35a9 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -251,24 +251,32 @@ static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, u8 *cur_data = data; struct cdns_i2c_regs *regs = i2c_bus->regs; u32 ret; + bool start = 1; /* Set the controller in Master transmit mode and clear FIFO */ setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO); clrbits_le32(®s->control, CDNS_I2C_CONTROL_RW); - /* Check message size against FIFO depth, and set hold bus bit - * if it is greater than FIFO depth + /* + * For sequential data load hold the bus. */ - if (len > CDNS_I2C_FIFO_DEPTH) + if (len > 1) setbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); /* Clear the interrupts in status register */ writel(CDNS_I2C_INTERRUPTS_MASK, ®s->interrupt_status); - writel(addr, ®s->address); + /* In case of Probe (i.e no data), start the transfer */ + if (!len) + writel(addr, ®s->address); while (len-- && !is_arbitration_lost(regs)) { writel(*(cur_data++), ®s->data); + /* Trigger write only after loading data */ + if (start) { + writel(addr, ®s->address); + start = 0; + } if (len && readl(®s->transfer_size) == CDNS_I2C_FIFO_DEPTH) { ret = cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP | CDNS_I2C_INTERRUPT_ARBLOST); @@ -375,7 +383,6 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, curr_recv_count = recv_count; } } else if (recv_count && !hold_quirk && !curr_recv_count) { - writel(addr, ®s->address); if (recv_count > CDNS_I2C_TRANSFER_SIZE) { writel(CDNS_I2C_TRANSFER_SIZE, ®s->transfer_size); @@ -384,6 +391,7 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, writel(recv_count, ®s->transfer_size); curr_recv_count = recv_count; } + writel(addr, ®s->address); } } |