[PATCHv2 1/3] i2c: imx_lpi2c: Fix a typo in bus_i2c_receive

From: Fedor Ross fedor.ross@ifm.com
Fix a typo in a debug message. It should be 'for' not 'fot' .
Signed-off-by: Fedor Ross fedor.ross@ifm.com --- Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de ---
Changes in v2: - Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
drivers/i2c/imx_lpi2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c index a1be841b119..3c43f61d819 100644 --- a/drivers/i2c/imx_lpi2c.c +++ b/drivers/i2c/imx_lpi2c.c @@ -130,7 +130,7 @@ static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
result = bus_i2c_wait_for_tx_ready(regs); if (result) { - debug("i2c: receive wait fot tx ready: %d\n", result); + debug("i2c: receive wait for tx ready: %d\n", result); return result; }

From: Fedor Ross fedor.ross@ifm.com
Instead of using the hard-coded bus speed value I2C_SPEED_STANDARD_RATE, use the actual configured bus speed. This way the bus speed doesn't change suddenly after calling the imx_lpi2c_probe_chip() function for example.
Signed-off-by: Fedor Ross fedor.ross@ifm.com --- Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de ---
Changes in v2: - Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied. - Drop the second parameter of bus_i2c_init().
drivers/i2c/imx_lpi2c.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c index 3c43f61d819..54db6fa863f 100644 --- a/drivers/i2c/imx_lpi2c.c +++ b/drivers/i2c/imx_lpi2c.c @@ -19,7 +19,7 @@ #define LPI2C_NACK_TOUT_MS 1 #define LPI2C_TIMEOUT_MS 100
-static int bus_i2c_init(struct udevice *bus, int speed); +static int bus_i2c_init(struct udevice *bus);
/* Weak linked function for overridden by some SoC power function */ int __weak init_i2c_power(unsigned i2c_num) @@ -172,7 +172,7 @@ static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir) debug("i2c: start check busy bus: 0x%x\n", result);
/* Try to init the lpi2c then check the bus busy again */ - bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE); + bus_i2c_init(bus); result = imx_lpci2c_check_busy_bus(regs); if (result) { printf("i2c: Error check busy bus: 0x%x\n", result); @@ -344,11 +344,14 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed) return 0; }
-static int bus_i2c_init(struct udevice *bus, int speed) +static int bus_i2c_init(struct udevice *bus) { u32 val; int ret;
+ struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); + int speed = i2c->speed_hz; + struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); /* reset peripheral */ @@ -388,13 +391,13 @@ static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip, result = bus_i2c_start(bus, chip, 0); if (result) { bus_i2c_stop(bus); - bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE); + bus_i2c_init(bus); return result; }
result = bus_i2c_stop(bus); if (result) - bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE); + bus_i2c_init(bus);
return result; } @@ -489,7 +492,7 @@ static int imx_lpi2c_probe(struct udevice *bus) return ret; }
- ret = bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE); + ret = bus_i2c_init(bus); if (ret < 0) return ret;

Hello Fedor,
On 30.07.24 17:25, fedorross@gmail.com wrote:
From: Fedor Ross fedor.ross@ifm.com
Instead of using the hard-coded bus speed value I2C_SPEED_STANDARD_RATE, use the actual configured bus speed. This way the bus speed doesn't change suddenly after calling the imx_lpi2c_probe_chip() function for example.
Signed-off-by: Fedor Ross fedor.ross@ifm.com
Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de
Changes in v2:
Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
Drop the second parameter of bus_i2c_init().
drivers/i2c/imx_lpi2c.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
Reviewed-by: Heiko Schocher hs@denx.de
Thanks!
bye, Heiko

From: Fedor Ross fedor.ross@ifm.com
The TXFIFO register of LPI2C only has one byte length, and if the length of the data that needs to be read exceeds 256 bytes, it needs to be written to TXFIFO multiple times.
Signed-off-by: Fedor Ross fedor.ross@ifm.com --- Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de ---
Changes in v2: - Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied. - Prefix 'CHUNK_DATA' macro with 'LPI2C_' to namespace it. - Do bit manipulation in writel() function directly and drop the 'val = assignment' .
drivers/i2c/imx_lpi2c.c | 71 ++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 25 deletions(-)
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c index 54db6fa863f..a223d91bac3 100644 --- a/drivers/i2c/imx_lpi2c.c +++ b/drivers/i2c/imx_lpi2c.c @@ -19,6 +19,8 @@ #define LPI2C_NACK_TOUT_MS 1 #define LPI2C_TIMEOUT_MS 100
+#define LPI2C_CHUNK_DATA 256 + static int bus_i2c_init(struct udevice *bus);
/* Weak linked function for overridden by some SoC power function */ @@ -118,8 +120,10 @@ static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len) { + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus); struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base); + unsigned int chunk_len, rx_remain, timeout; lpi2c_status_t result = LPI2C_SUCESS; u32 val; ulong start_time = get_timer(0); @@ -128,33 +132,50 @@ static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len) if (!len) return result;
- result = bus_i2c_wait_for_tx_ready(regs); - if (result) { - debug("i2c: receive wait for tx ready: %d\n", result); - return result; - } + /* + * Extend the timeout for a bulk read if needed. + * The calculated timeout is the result of multiplying the + * transfer length with 8 bit + ACK + one clock of extra time, + * considering the I2C bus frequency. + */ + timeout = max(len * 10 * 1000 / i2c->speed_hz, LPI2C_TIMEOUT_MS);
- /* clear all status flags */ - writel(0x7f00, ®s->msr); - /* send receive command */ - val = LPI2C_MTDR_CMD(0x1) | LPI2C_MTDR_DATA(len - 1); - writel(val, ®s->mtdr); + rx_remain = len; + while (rx_remain > 0) { + chunk_len = clamp(rx_remain, 1, LPI2C_CHUNK_DATA) - 1;
- while (len--) { - do { - result = imx_lpci2c_check_clear_error(regs); - if (result) { - debug("i2c: receive check clear error: %d\n", - result); - return result; - } - if (get_timer(start_time) > LPI2C_TIMEOUT_MS) { - debug("i2c: receive mrdr: timeout\n"); - return -1; - } - val = readl(®s->mrdr); - } while (val & LPI2C_MRDR_RXEMPTY_MASK); - *rxbuf++ = LPI2C_MRDR_DATA(val); + result = bus_i2c_wait_for_tx_ready(regs); + if (result) { + debug("i2c: receive wait for tx ready: %d\n", result); + return result; + } + + /* clear all status flags */ + writel(0x7f00, ®s->msr); + /* send receive command */ + writel(LPI2C_MTDR_CMD(0x1) | LPI2C_MTDR_DATA(chunk_len), ®s->mtdr); + rx_remain = rx_remain - (chunk_len & 0xff) - 1; + + while (len--) { + do { + result = imx_lpci2c_check_clear_error(regs); + if (result) { + debug("i2c: receive check clear error: %d\n", + result); + return result; + } + if (get_timer(start_time) > timeout) { + debug("i2c: receive mrdr: timeout\n"); + return -1; + } + val = readl(®s->mrdr); + } while (val & LPI2C_MRDR_RXEMPTY_MASK); + *rxbuf++ = LPI2C_MRDR_DATA(val); + + /* send next receive command before controller NACKs last byte */ + if ((len - rx_remain) < 2 && rx_remain > 0) + break; + } }
return result;

Hello Fedor,
On 30.07.24 17:25, fedorross@gmail.com wrote:
From: Fedor Ross fedor.ross@ifm.com
The TXFIFO register of LPI2C only has one byte length, and if the length of the data that needs to be read exceeds 256 bytes, it needs to be written to TXFIFO multiple times.
Signed-off-by: Fedor Ross fedor.ross@ifm.com
Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de
Changes in v2:
Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
Prefix 'CHUNK_DATA' macro with 'LPI2C_' to namespace it.
Do bit manipulation in writel() function directly and drop the 'val = assignment' .
drivers/i2c/imx_lpi2c.c | 71 ++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 25 deletions(-)
Reviewed-by: Heiko Schocher hs@denx.de
Thanks!
bye, Heiko

Hello Fedor,
On 30.07.24 17:25, fedorross@gmail.com wrote:
From: Fedor Ross fedor.ross@ifm.com
The TXFIFO register of LPI2C only has one byte length, and if the length of the data that needs to be read exceeds 256 bytes, it needs to be written to TXFIFO multiple times.
Signed-off-by: Fedor Ross fedor.ross@ifm.com
Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de
Changes in v2:
Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
Prefix 'CHUNK_DATA' macro with 'LPI2C_' to namespace it.
Do bit manipulation in writel() function directly and drop the 'val = assignment' .
drivers/i2c/imx_lpi2c.c | 71 ++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 25 deletions(-)
Patch breaks world build, see for example
https://dev.azure.com/hs0298/hs/_build/results?buildId=114&view=logs&...
Find the whole pipeline (with other patches too...)
https://dev.azure.com/hs0298/hs/_build/results?buildId=114&view=results
Could you take a look please?
Thanks!
bye, Heiko

On Wed, Aug 7, 2024 at 12:50 PM Heiko Schocher hs@denx.de wrote:
Hello Heiko,
On 30.07.24 17:25, fedorross@gmail.com wrote:
From: Fedor Ross fedor.ross@ifm.com
The TXFIFO register of LPI2C only has one byte length, and if the length of the data that needs to be read exceeds 256 bytes, it needs to be written to TXFIFO multiple times.
Signed-off-by: Fedor Ross fedor.ross@ifm.com
Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de
Changes in v2:
Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
Prefix 'CHUNK_DATA' macro with 'LPI2C_' to namespace it.
Do bit manipulation in writel() function directly and drop the 'val = assignment' .
drivers/i2c/imx_lpi2c.c | 71 ++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 25 deletions(-)
Patch breaks world build, see for example
https://dev.azure.com/hs0298/hs/_build/results?buildId=114&view=logs&...
Find the whole pipeline (with other patches too...)
https://dev.azure.com/hs0298/hs/_build/results?buildId=114&view=results
Could you take a look please?
Done. Sorry for the inconvenience.
[...]
Best regards, Fedor

Hello Fedor,
On 07.08.24 16:13, Fedor Ross wrote:
On Wed, Aug 7, 2024 at 12:50 PM Heiko Schocher hs@denx.de wrote:
Hello Heiko,
On 30.07.24 17:25, fedorross@gmail.com wrote:
From: Fedor Ross fedor.ross@ifm.com
The TXFIFO register of LPI2C only has one byte length, and if the length of the data that needs to be read exceeds 256 bytes, it needs to be written to TXFIFO multiple times.
Signed-off-by: Fedor Ross fedor.ross@ifm.com
Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de
Changes in v2:
Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
Prefix 'CHUNK_DATA' macro with 'LPI2C_' to namespace it.
Do bit manipulation in writel() function directly and drop the 'val = assignment' .
drivers/i2c/imx_lpi2c.c | 71 ++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 25 deletions(-)
Patch breaks world build, see for example
https://dev.azure.com/hs0298/hs/_build/results?buildId=114&view=logs&...
Find the whole pipeline (with other patches too...)
https://dev.azure.com/hs0298/hs/_build/results?buildId=114&view=results
Could you take a look please?
Done.
Thanks!
Sorry for the inconvenience.
No problem.
bye, Heiko

Hello Fedor,
On 30.07.24 17:25, fedorross@gmail.com wrote:
From: Fedor Ross fedor.ross@ifm.com
Fix a typo in a debug message. It should be 'for' not 'fot' .
Signed-off-by: Fedor Ross fedor.ross@ifm.com
Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de
Changes in v2:
- Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
You may also take a look at patman tool in u-boot:/tools/patman
Reviewed-by: Heiko Schocher hs@denx.de
Thanks!
bye, Heiko

On Wed, Jul 31, 2024 at 5:41 AM Heiko Schocher hs@denx.de wrote:
Hello Fedor,
Hello Heiko,
On 30.07.24 17:25, fedorross@gmail.com wrote:
From: Fedor Ross fedor.ross@ifm.com
Fix a typo in a debug message. It should be 'for' not 'fot' .
Signed-off-by: Fedor Ross fedor.ross@ifm.com
Cc: Heiko Schocher hs@denx.de Cc: Tom Rini trini@konsulko.com Cc: Marek Vasut marex@denx.de
Changes in v2:
- Add additional '---' below SoB line to separate Cc list. This way it does not get included in the commit message when the patch is applied.
You may also take a look at patman tool in u-boot:/tools/patman
I'll take a look at that. Thanks!
Reviewed-by: Heiko Schocher hs@denx.de
[...]
Best regards, Fedor
participants (3)
-
Fedor Ross
-
fedorross@gmail.com
-
Heiko Schocher