diff options
author | Pei Yue Ho <peiyue.ho@starfivetech.com> | 2023-02-13 11:02:41 +0300 |
---|---|---|
committer | Heiko Schocher <hs@denx.de> | 2023-02-13 11:58:27 +0300 |
commit | f536fda99fa2c1c88f68d8da54ed6233cec3532e (patch) | |
tree | fd3918bfb7edf9bb6d6c750756e6b506ab42b5f7 /drivers | |
parent | 8511a7fc85ac1d1e3aea44d0e97fab26ace10ab2 (diff) | |
download | u-boot-f536fda99fa2c1c88f68d8da54ed6233cec3532e.tar.xz |
i2c: i2c-cdns.c: Update driver to read fifo-depth from device tree
Enable driver to fetch the optional parameter (fifo-depth) from device
tree. If the parameter is not found in the device tree, it will use
the default value declared in the driver.
Signed-off-by: Pei Yue Ho <peiyue.ho@starfivetech.com>
Reviewed-by: Wei Liang Lim <weiliang.lim@starfivetech.com>
Reviewed-by: Eng Lee Teh <englee.teh@starfivetech.com>
Reviewed-by: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/i2c-cdns.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index 0da9f6f35a..c1672ca18e 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -78,7 +78,7 @@ struct cdns_i2c_regs { CDNS_I2C_INTERRUPT_RXUNF | \ CDNS_I2C_INTERRUPT_ARBLOST) -#define CDNS_I2C_FIFO_DEPTH 16 +#define CDNS_I2C_FIFO_DEPTH_DEFAULT 16 #define CDNS_I2C_TRANSFER_SIZE_MAX 255 /* Controller transfer limit */ #define CDNS_I2C_TRANSFER_SIZE (CDNS_I2C_TRANSFER_SIZE_MAX - 3) @@ -135,6 +135,7 @@ struct i2c_cdns_bus { int hold_flag; u32 quirks; + u32 fifo_depth; }; struct cdns_i2c_platform_data { @@ -277,7 +278,7 @@ static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, writel(addr, ®s->address); start = 0; } - if (len && readl(®s->transfer_size) == CDNS_I2C_FIFO_DEPTH) { + if (len && readl(®s->transfer_size) == i2c_bus->fifo_depth) { ret = cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP | CDNS_I2C_INTERRUPT_ARBLOST); if (ret & CDNS_I2C_INTERRUPT_ARBLOST) @@ -310,9 +311,10 @@ static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, return 0; } -static inline bool cdns_is_hold_quirk(int hold_quirk, int curr_recv_count) +static inline bool cdns_is_hold_quirk(struct i2c_cdns_bus *i2c_bus, int hold_quirk, + int curr_recv_count) { - return hold_quirk && (curr_recv_count == CDNS_I2C_FIFO_DEPTH + 1); + return hold_quirk && (curr_recv_count == i2c_bus->fifo_depth + 1); } static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, @@ -327,7 +329,7 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, curr_recv_count = recv_count; /* Check for the message size against the FIFO depth */ - if (recv_count > CDNS_I2C_FIFO_DEPTH) + if (recv_count > i2c_bus->fifo_depth) setbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO | @@ -349,7 +351,7 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, while (recv_count && !is_arbitration_lost(regs)) { while (readl(®s->status) & CDNS_I2C_STATUS_RXDV) { - if (recv_count < CDNS_I2C_FIFO_DEPTH && + if (recv_count < i2c_bus->fifo_depth && !i2c_bus->hold_flag) { clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); @@ -358,27 +360,27 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, recv_count--; curr_recv_count--; - if (cdns_is_hold_quirk(hold_quirk, curr_recv_count)) + if (cdns_is_hold_quirk(i2c_bus, hold_quirk, curr_recv_count)) break; } - if (cdns_is_hold_quirk(hold_quirk, curr_recv_count)) { + if (cdns_is_hold_quirk(i2c_bus, hold_quirk, curr_recv_count)) { /* wait while fifo is full */ while (readl(®s->transfer_size) != - (curr_recv_count - CDNS_I2C_FIFO_DEPTH)) + (curr_recv_count - i2c_bus->fifo_depth)) ; /* * Check number of bytes to be received against maximum * transfer size and update register accordingly. */ - if ((recv_count - CDNS_I2C_FIFO_DEPTH) > + if ((recv_count - i2c_bus->fifo_depth) > CDNS_I2C_TRANSFER_SIZE) { writel(CDNS_I2C_TRANSFER_SIZE, ®s->transfer_size); curr_recv_count = CDNS_I2C_TRANSFER_SIZE + - CDNS_I2C_FIFO_DEPTH; + i2c_bus->fifo_depth; } else { - writel(recv_count - CDNS_I2C_FIFO_DEPTH, + writel(recv_count - i2c_bus->fifo_depth, ®s->transfer_size); curr_recv_count = recv_count; } @@ -496,6 +498,10 @@ static int cdns_i2c_of_to_plat(struct udevice *dev) return ret; } + /* Update FIFO depth based on device tree entry */ + i2c_bus->fifo_depth = dev_read_u32_default(dev, "fifo-depth", + CDNS_I2C_FIFO_DEPTH_DEFAULT); + return 0; } |