Skip to contentSkip to conversation

i2c: imx: DMA related fixes

PATCH New Oleksij Rempel 4 participants 14 messages Oct 18, 2018 – Nov 3, 2018

Subsystems (4)
lore
Share & tools
lore

Oleksij Rempel

author maintainer
#0 lore raw

cover i2c: imx: DMA related fixes

Current i2c-imx module prints DMA warnings which in many cases are false positive and just confuse testers:
1. DMA is not available on chips before i.MX50
2. DMA for i2c is muxed with some other peripheral, and can be used only for one of devices at same time. So, obvious choice it to use it with SDHC instead of i2c.

Oleksij Rempel (3):
ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node
i2c: imx: probe dma only only on i.MX50 and later.
i2c: imx: don't print error if DMA is not configured

 arch/arm/boot/dts/imx6sll.dtsi |  2 +-
 drivers/i2c/busses/i2c-imx.c   | 89 +++++++++++++++++++++++++++-------
 2 files changed, 73 insertions(+), 18 deletions(-)
Signature · 1 line
2.19.0
author maintainer
#1 lore raw

PATCH 1/3 ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node

---
 arch/arm/boot/dts/imx6sll.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6sll.dtsi +1 -1
index 000e6136a9d6..3e6ffaf5f104 100644
@@ -709,7 +709,7 @@
 			i2c1: i2c at 21a0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fs,imx6sll-i2c", "fsl,imx21-i2c";
+				compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";
 				reg = <0x021a0000 0x4000>;
 				interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SLL_CLK_I2C1>;
Signature · 1 line
2.19.0
#2 lore raw

PATCH 1/3 ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node

Quoted 10 lines · Oleksij Rempel
---
 arch/arm/boot/dts/imx6sll.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6sll.dtsi +0 -0
index 000e6136a9d6..3e6ffaf5f104 100644

arch/arm/boot/dts/imx6sll.dtsi line 712

Quoted 5 lines
arch/arm/boot/dts/imx6sll.dtsi +1 -1
@@ -709,7 +709,7 @@
 			i2c1: i2c at 21a0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fs,imx6sll-i2c", "fsl,imx21-i2c";
+				compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Applied
#3 lore raw

PATCH 1/3 ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node

In reply to Oleksij Rempel
Quoted 1 line · Oleksij Rempel

Applied, thanks.

Quoted 20 lines
---
 arch/arm/boot/dts/imx6sll.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6sll.dtsi +1 -1
index 000e6136a9d6..3e6ffaf5f104 100644
@@ -709,7 +709,7 @@
 			i2c1: i2c at 21a0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fs,imx6sll-i2c", "fsl,imx21-i2c";
+				compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";
 				reg = <0x021a0000 0x4000>;
 				interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SLL_CLK_I2C1>;
Signature · 1 line
2.19.0
author maintainer
#4 lore raw

PATCH 2/3 i2c: imx: probe dma only only on i.MX50 and later.

In reply to Oleksij Rempel

The DMA support for I2C was introduced on i.MX50. So, avoid of DMA probing on not supported versions.

---
 drivers/i2c/busses/i2c-imx.c | 53 ++++++++++++++++++++++++++++++++++--
 1 file changed, 51 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-imx.c +51 -2
index c406700789e1..df013b1b6fa4 100644
@@ -169,6 +169,7 @@ struct imx_i2c_hwdata {
 	unsigned		ndivs;
 	unsigned		i2sr_clr_opcode;
 	unsigned		i2cr_ien_opcode;
+	bool			has_dmamode;
 };
 
 struct imx_i2c_dma {
@@ -211,7 +212,7 @@ static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
 	.ndivs			= ARRAY_SIZE(imx_i2c_clk_div),
 	.i2sr_clr_opcode	= I2SR_CLR_OPCODE_W0C,
 	.i2cr_ien_opcode	= I2CR_IEN_OPCODE_1,
-
+	.has_dmamode		= false,
 };
 
 static const struct imx_i2c_hwdata imx21_i2c_hwdata = {
@@ -221,7 +222,17 @@ static const struct imx_i2c_hwdata imx21_i2c_hwdata = {
 	.ndivs			= ARRAY_SIZE(imx_i2c_clk_div),
 	.i2sr_clr_opcode	= I2SR_CLR_OPCODE_W0C,
 	.i2cr_ien_opcode	= I2CR_IEN_OPCODE_1,
+	.has_dmamode		= false,
+};
 
+static const struct imx_i2c_hwdata imx50_i2c_hwdata = {
+	.devtype		= IMX21_I2C,
+	.regshift		= IMX_I2C_REGSHIFT,
+	.clk_div		= imx_i2c_clk_div,
+	.ndivs			= ARRAY_SIZE(imx_i2c_clk_div),
+	.i2sr_clr_opcode	= I2SR_CLR_OPCODE_W0C,
+	.i2cr_ien_opcode	= I2CR_IEN_OPCODE_1,
+	.has_dmamode		= true,
 };
 
 static struct imx_i2c_hwdata vf610_i2c_hwdata = {
@@ -231,7 +242,7 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {
 	.ndivs			= ARRAY_SIZE(vf610_i2c_clk_div),
 	.i2sr_clr_opcode	= I2SR_CLR_OPCODE_W1C,
 	.i2cr_ien_opcode	= I2CR_IEN_OPCODE_0,
-
+	.has_dmamode		= true,
 };
 
 static const struct platform_device_id imx_i2c_devtype[] = {
@@ -241,6 +252,33 @@ static const struct platform_device_id imx_i2c_devtype[] = {
 	}, {
 		.name = "imx21-i2c",
 		.driver_data = (kernel_ulong_t)&imx21_i2c_hwdata,
+	}, {
+		.name = "imx50-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx51-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx53-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx6q-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx6sl-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx6sll-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx6sx-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx6ul-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
+	}, {
+		.name = "imx7d-i2c",
+		.driver_data = (kernel_ulong_t)&imx50_i2c_hwdata,
 	}, {
 		/* sentinel */
 	}
@@ -250,6 +288,14 @@ MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
 static const struct of_device_id i2c_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
 	{ .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
+	{ .compatible = "fsl,imx50-i2c", .data = &imx50_i2c_hwdata, },
+	{ .compatible = "fsl,imx51-i2c", .data = &imx50_i2c_hwdata, },
+	{ .compatible = "fsl,imx53-i2c", .data = &imx50_i2c_hwdata, },
+	{ .compatible = "fsl,imx6q-i2c", .data = &imx50_i2c_hwdata, },
+	{ .compatible = "fsl,imx6sl-i2c", .data = &imx50_i2c_hwdata, },
+	{ .compatible = "fsl,imx6sll-i2c", .data = &imx50_i2c_hwdata, },
+	{ .compatible = "fsl,imx6sx-i2c", .data = &imx50_i2c_hwdata, },
+	{ .compatible = "fsl,imx6ul-i2c", .data = &imx50_i2c_hwdata, },
 	{ .compatible = "fsl,vf610-i2c", .data = &vf610_i2c_hwdata, },
 	{ /* sentinel */ }
 };
@@ -281,6 +327,9 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	struct device *dev = &i2c_imx->adapter.dev;
 	int ret;
 
+	if (!i2c_imx->hwdata->has_dmamode)
+		return;
+
 	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
 	if (!dma)
 		return;
Signature · 1 line
2.19.0
#5 lore raw

PATCH 2/3 i2c: imx: probe dma only only on i.MX50 and later.

Hello Oleksij,

Quoted 2 lines · Oleksij Rempel

The DMA support for I2C was introduced on i.MX50. So, avoid of DMA probing on not supported versions.

What is the obvious downside of trying to use DMA on i.MX21? If the purpose is just to suppress the message

can't request DMA tx channel

, that goes away with patch 3, too.

Note that if we agree that i.MX50 (and later) isn't compatible to i.MX21, all device trees should be fixed accordingly. IMHO the difference "There is a DMA engine connected only on some implementations" doesn't give enough incentive to claim that i.MX21 and i.MX50 must not share the compatible.

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
author maintainer
#6 lore raw

PATCH 2/3 i2c: imx: probe dma only only on i.MX50 and later.

Quoted 11 lines · Uwe Kleine-K?nig

Hello Oleksij,

Quoted 2 lines · Oleksij Rempel

The DMA support for I2C was introduced on i.MX50. So, avoid of DMA probing on not supported versions.

What is the obvious downside of trying to use DMA on i.MX21? If the purpose is just to suppress the message

can't request DMA tx channel

Quoted 7 lines

, that goes away with patch 3, too.

Note that if we agree that i.MX50 (and later) isn't compatible to i.MX21, all device trees should be fixed accordingly. IMHO the difference "There is a DMA engine connected only on some implementations" doesn't give enough incentive to claim that i.MX21 and i.MX50 must not share the compatible.

I don't see any sense to do allocation and add extra probes just to find what we already know from compatible.

Signature · 11 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20181019/0d0f381a/attachment.sig>
#7 lore raw

PATCH 2/3 i2c: imx: probe dma only only on i.MX50 and later.

Quoted 14 lines · Oleksij Rempel
Quoted 13 lines · Uwe Kleine-K?nig

Hello Oleksij,

Quoted 2 lines · Oleksij Rempel

The DMA support for I2C was introduced on i.MX50. So, avoid of DMA probing on not supported versions.

What is the obvious downside of trying to use DMA on i.MX21? If the purpose is just to suppress the message

can't request DMA tx channel

, that goes away with patch 3, too.

Quoted 8 lines
Quoted 5 lines

Note that if we agree that i.MX50 (and later) isn't compatible to i.MX21, all device trees should be fixed accordingly. IMHO the difference "There is a DMA engine connected only on some implementations" doesn't give enough incentive to claim that i.MX21 and i.MX50 must not share the compatible.

I don't see any sense to do allocation and add extra probes just to find what we already know from compatible.

I think it's perfectly fine to only notice that there is no DMA support when trying to set it up. It has slight runtime overhead, yes, but being able to handle imx21 and imx50 in the same way is a nice advantage that I don't want to throw away easily.

If you care about the allocation, you can do do the calls to dma_request_chan first and assign to local variables before the allocation of *dma.

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
author maintainer
#8 lore raw

PATCH 2/3 i2c: imx: probe dma only only on i.MX50 and later.

Quoted 24 lines · Uwe Kleine-K?nig
Quoted 14 lines · Oleksij Rempel
Quoted 13 lines · Uwe Kleine-K?nig

Hello Oleksij,

Quoted 2 lines · Oleksij Rempel

The DMA support for I2C was introduced on i.MX50. So, avoid of DMA probing on not supported versions.

What is the obvious downside of trying to use DMA on i.MX21? If the purpose is just to suppress the message

can't request DMA tx channel

, that goes away with patch 3, too.

Quoted 8 lines
Quoted 5 lines

Note that if we agree that i.MX50 (and later) isn't compatible to i.MX21, all device trees should be fixed accordingly. IMHO the difference "There is a DMA engine connected only on some implementations" doesn't give enough incentive to claim that i.MX21 and i.MX50 must not share the compatible.

I don't see any sense to do allocation and add extra probes just to find what we already know from compatible.

Quoted 8 lines

I think it's perfectly fine to only notice that there is no DMA support when trying to set it up. It has slight runtime overhead, yes, but being able to handle imx21 and imx50 in the same way is a nice advantage that I don't want to throw away easily.

If you care about the allocation, you can do do the calls to dma_request_chan first and assign to local variables before the allocation of *dma.

Ok, then we can drop this patch.

Signature · 11 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20181019/37dc7490/attachment.sig>
author maintainer
#9 lore raw

PATCH 3/3 i2c: imx: don't print error if DMA is not configured

In reply to Oleksij Rempel

At least on i.MX5x variants is DMA event for I2C muxed with SDHC. So it is project specific configuration and not an error.

---
 drivers/i2c/busses/i2c-imx.c | 38 +++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 16 deletions(-)
drivers/i2c/busses/i2c-imx.c +22 -16
index df013b1b6fa4..bd362fe07257 100644
@@ -319,7 +319,7 @@ static inline unsigned char imx_i2c_read_reg(struct imx_i2c_struct *i2c_imx,
 }
 
 /* Functions for DMA support */
-static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
+static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 						dma_addr_t phy_addr)
 {
 	struct imx_i2c_dma *dma;
@@ -328,15 +328,17 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	int ret;
 
 	if (!i2c_imx->hwdata->has_dmamode)
-		return;
+		return 0;
 
 	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
 	if (!dma)
-		return;
+		return -ENOMEM;
 
-	dma->chan_tx = dma_request_slave_channel(dev, "tx");
-	if (!dma->chan_tx) {
-		dev_dbg(dev, "can't request DMA tx channel\n");
+	dma->chan_tx = dma_request_chan(dev, "tx");
+	if (IS_ERR(dma->chan_tx)) {
+		ret = PTR_ERR(dma->chan_rx);
+		if (ret != -ENODEV && ret != -EPROBE_DEFER)
+			dev_err(dev, "can't request DMA tx channel (%d)\n", ret);
 		goto fail_al;
 	}
 
@@ -347,13 +349,15 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	dma_sconfig.direction = DMA_MEM_TO_DEV;
 	ret = dmaengine_slave_config(dma->chan_tx, &dma_sconfig);
 	if (ret < 0) {
-		dev_dbg(dev, "can't configure tx channel\n");
+		dev_err(dev, "can't configure tx channel (%d)\n", ret);
 		goto fail_tx;
 	}
 
-	dma->chan_rx = dma_request_slave_channel(dev, "rx");
-	if (!dma->chan_rx) {
-		dev_dbg(dev, "can't request DMA rx channel\n");
+	dma->chan_rx = dma_request_chan(dev, "rx");
+	if (IS_ERR(dma->chan_rx)) {
+		ret = PTR_ERR(dma->chan_rx);
+		if (ret != -ENODEV && ret != -EPROBE_DEFER)
+			dev_err(dev, "can't request DMA rx channel (%d)\n", ret);
 		goto fail_tx;
 	}
 
@@ -364,7 +368,7 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	dma_sconfig.direction = DMA_DEV_TO_MEM;
 	ret = dmaengine_slave_config(dma->chan_rx, &dma_sconfig);
 	if (ret < 0) {
-		dev_dbg(dev, "can't configure rx channel\n");
+		dev_err(dev, "can't configure rx channel (%d)\n", ret);
 		goto fail_rx;
 	}
 
@@ -373,15 +377,15 @@ static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
 	dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
 		dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));
 
-	return;
+	return 0;
 
 fail_rx:
 	dma_release_channel(dma->chan_rx);
 fail_tx:
 	dma_release_channel(dma->chan_tx);
 fail_al:
-	devm_kfree(dev, dma);
-	dev_info(dev, "can't use DMA, using PIO instead.\n");
+	/* return successfully if there is no dma support */
+	return ret == -ENODEV ? 0 : ret;
 }
 
 static void i2c_imx_dma_callback(void *arg)
@@ -1208,11 +1212,13 @@ static int i2c_imx_probe(struct platform_device *pdev)
 	dev_dbg(&i2c_imx->adapter.dev, "device resources: %pR\n", res);
 	dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
 		i2c_imx->adapter.name);
-	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 
 	/* Init DMA config if supported */
-	i2c_imx_dma_request(i2c_imx, phy_addr);
+	ret = i2c_imx_dma_request(i2c_imx, phy_addr);
+	if (ret < 0)
+		goto clk_notifier_unregister;
 
+	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 	return 0;   /* Return OK */
 
 clk_notifier_unregister:
Signature · 1 line
2.19.0
#10 lore raw

PATCH 3/3 i2c: imx: don't print error if DMA is not configured

Quoted 4 lines · Oleksij Rempel

At least on i.MX5x variants is DMA event for I2C muxed with SDHC. So it is project specific configuration and not an error.

So, the first patch is not I2C realm, and the second is dropped. No comment about the third one?

And is maybe someone from Pengutronix interested in maintaining this driver? Uwe maybe? That would speed up things for it...

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20181028/88739af1/attachment.sig>

author maintainer
#11 lore raw

PATCH 3/3 i2c: imx: don't print error if DMA is not configured

Quoted 11 lines · Wolfram Sang
Quoted 4 lines · Oleksij Rempel

At least on i.MX5x variants is DMA event for I2C muxed with SDHC. So it is project specific configuration and not an error.

So, the first patch is not I2C realm, and the second is dropped. No comment about the third one?

And is maybe someone from Pengutronix interested in maintaining this driver? Uwe maybe? That would speed up things for it...

Should i resend it as single patch?

#12 lore raw

PATCH 3/3 i2c: imx: don't print error if DMA is not configured

Quoted 9 lines · Oleksij Rempel
Quoted 6 lines · Wolfram Sang
Quoted 4 lines · Oleksij Rempel

At least on i.MX5x variants is DMA event for I2C muxed with SDHC. So it is project specific configuration and not an error.

Quoted 7 lines
Quoted 5 lines

So, the first patch is not I2C realm, and the second is dropped. No comment about the third one?

And is maybe someone from Pengutronix interested in maintaining this driver? Uwe maybe? That would speed up things for it...

Should i resend it as single patch?

I am fine with an ack here.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20181029/4e44cb1b/attachment.sig>

#13 lore raw

PATCH 3/3 i2c: imx: don't print error if DMA is not configured

Hello Wolfram, hello Oleksij,

Quoted 11 lines · Wolfram Sang
Quoted 10 lines · Oleksij Rempel
Quoted 9 lines · Wolfram Sang
Quoted 4 lines · Oleksij Rempel

At least on i.MX5x variants is DMA event for I2C muxed with SDHC. So it is project specific configuration and not an error.

So, the first patch is not I2C realm, and the second is dropped. No comment about the third one?

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

And is maybe someone from Pengutronix interested in maintaining this driver? Uwe maybe? That would speed up things for it...

Should i resend it as single patch?

I am fine with an ack here.

With patch 1 dropped this patch needs adaption I think.

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |