From 0e561a2aea8dddbb446f710f1037ec305c23af9e Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Sat, 22 May 2021 20:07:56 +0200 Subject: [PATCH] lantiq: improve ethernet performance This commit contains a series of fixes for DMA. The burst length patch significantly improves Ethernet performance. Patches were tested on the xRX200 and xRX330. Signed-off-by: Aleksander Jan Bajkowski --- .../arch/mips/boot/dts/lantiq/amazonse.dtsi | 2 + .../files/arch/mips/boot/dts/lantiq/ar9.dtsi | 2 + .../arch/mips/boot/dts/lantiq/danube.dtsi | 2 + .../files/arch/mips/boot/dts/lantiq/vr9.dtsi | 2 + ...ntiq-dma-add-small-delay-after-reset.patch | 32 +++++ ...-dma-reset-correct-number-of-channel.patch | 68 ++++++++++ ...-lantiq-dma-fix-burst-length-for-DEU.patch | 41 ++++++ ...make-a-burst-length-configurable-in-.patch | 84 ++++++++++++ ...-configure-burst-length-for-ethernet.patch | 124 ++++++++++++++++++ ...ntiq-dma-add-small-delay-after-reset.patch | 32 +++++ ...-dma-reset-correct-number-of-channel.patch | 68 ++++++++++ ...-lantiq-dma-fix-burst-length-for-DEU.patch | 41 ++++++ ...make-a-burst-length-configurable-in-.patch | 84 ++++++++++++ ...-configure-burst-length-for-ethernet.patch | 124 ++++++++++++++++++ 14 files changed, 706 insertions(+) create mode 100644 target/linux/lantiq/patches-5.10/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch create mode 100644 target/linux/lantiq/patches-5.10/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch create mode 100644 target/linux/lantiq/patches-5.10/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch create mode 100644 target/linux/lantiq/patches-5.10/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch create mode 100644 target/linux/lantiq/patches-5.10/0710-net-lantiq-configure-burst-length-for-ethernet.patch create mode 100644 target/linux/lantiq/patches-5.4/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch create mode 100644 target/linux/lantiq/patches-5.4/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch create mode 100644 target/linux/lantiq/patches-5.4/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch create mode 100644 target/linux/lantiq/patches-5.4/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch create mode 100644 target/linux/lantiq/patches-5.4/0710-net-lantiq-configure-burst-length-for-ethernet.patch diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/amazonse.dtsi b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/amazonse.dtsi index c477473a06..5c608dab63 100644 --- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/amazonse.dtsi +++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/amazonse.dtsi @@ -236,6 +236,8 @@ interrupts = <105 109>; pinctrl-0 = <&mdio_pins>; pinctrl-names = "default"; + lantiq,tx-burst-length = <4>; + lantiq,rx-burst-length = <4>; }; }; diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9.dtsi b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9.dtsi index 819dcfb5a8..61283f5621 100644 --- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9.dtsi +++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9.dtsi @@ -387,6 +387,8 @@ interrupts = <73 72>; pinctrl-0 = <&mdio_pins>; pinctrl-names = "default"; + lantiq,tx-burst-length = <8>; + lantiq,rx-burst-length = <8>; }; ppe@e234000 { diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube.dtsi b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube.dtsi index e531fe45e8..a18183a2de 100644 --- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube.dtsi +++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube.dtsi @@ -299,6 +299,8 @@ reg = <0xe180000 0x40000>; interrupt-parent = <&icu0>; interrupts = <73 78>; + lantiq,tx-burst-length = <4>; + lantiq,rx-burst-length = <4>; }; ppe@e234000 { diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9.dtsi b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9.dtsi index 27858be28f..e379b07b53 100644 --- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9.dtsi +++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9.dtsi @@ -488,6 +488,8 @@ interrupt-names = "tx", "rx"; resets = <&reset0 21 16>, <&reset0 8 8>, <&reset0 3 3>; reset-names = "switch", "ppe", "ppe_dsp"; + lantiq,tx-burst-length = <8>; + lantiq,rx-burst-length = <8>; #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/lantiq/patches-5.10/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch b/target/linux/lantiq/patches-5.10/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch new file mode 100644 index 0000000000..05227c8f89 --- /dev/null +++ b/target/linux/lantiq/patches-5.10/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch @@ -0,0 +1,32 @@ +From 497acc03cd3918baabe25d46e30c5c62b998e24d Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Sat, 19 Jun 2021 13:38:12 +0200 +Subject: [PATCH 1/5] MIPS: lantiq: dma: add small delay after reset + +Reading the DMA registers immediately after the reset causes +Data Bus Error. Adding a small delay fixes this problem. + +Signed-off-by: Aleksander Jan Bajkowski +--- + arch/mips/lantiq/xway/dma.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -221,6 +222,8 @@ ltq_dma_init(struct platform_device *pde + clk_enable(clk); + ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); + ++ usleep_range(1, 10); ++ + /* disable all interrupts */ + ltq_dma_w32(0, LTQ_DMA_IRNEN); + diff --git a/target/linux/lantiq/patches-5.10/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch b/target/linux/lantiq/patches-5.10/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch new file mode 100644 index 0000000000..5d1862d576 --- /dev/null +++ b/target/linux/lantiq/patches-5.10/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch @@ -0,0 +1,68 @@ +From d31260c2f6a5cdddb052ab7cb09560eb23ce6597 Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Thu, 15 Apr 2021 21:28:24 +0200 +Subject: [PATCH 2/5] MIPS: lantiq: dma: reset correct number of channel + +Different SoCs have a different number of channels, e.g .: +* amazon-se has 10 channels, +* danube+ar9 have 20 channels, +* vr9 has 28 channels, +* ar10 has 24 channels. + +We can read the ID register and, depending on the reported +number of channels, reset the appropriate number of channels. + +Signed-off-by: Aleksander Jan Bajkowski +--- + arch/mips/lantiq/xway/dma.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -30,6 +30,7 @@ + #define LTQ_DMA_PCTRL 0x44 + #define LTQ_DMA_IRNEN 0xf4 + ++#define DMA_ID_CHNR GENMASK(26, 20) /* channel number */ + #define DMA_DESCPT BIT(3) /* descriptor complete irq */ + #define DMA_TX BIT(8) /* TX channel direction */ + #define DMA_CHAN_ON BIT(0) /* channel on / off bit */ +@@ -40,7 +41,6 @@ + #define DMA_POLL BIT(31) /* turn on channel polling */ + #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ + #define DMA_2W_BURST BIT(1) /* 2 word burst length */ +-#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ + #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ + #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ + +@@ -206,7 +206,7 @@ ltq_dma_init(struct platform_device *pde + { + struct clk *clk; + struct resource *res; +- unsigned id; ++ unsigned int id, nchannels; + int i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -228,17 +228,18 @@ ltq_dma_init(struct platform_device *pde + ltq_dma_w32(0, LTQ_DMA_IRNEN); + + /* reset/configure each channel */ +- for (i = 0; i < DMA_MAX_CHANNEL; i++) { ++ id = ltq_dma_r32(LTQ_DMA_ID); ++ nchannels = ((id & DMA_ID_CHNR) >> 20); ++ for (i = 0; i < nchannels; i++) { + ltq_dma_w32(i, LTQ_DMA_CS); + ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL); + ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); + ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); + } + +- id = ltq_dma_r32(LTQ_DMA_ID); + dev_info(&pdev->dev, + "Init done - hw rev: %X, ports: %d, channels: %d\n", +- id & 0x1f, (id >> 16) & 0xf, id >> 20); ++ id & 0x1f, (id >> 16) & 0xf, nchannels); + + return 0; + } diff --git a/target/linux/lantiq/patches-5.10/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch b/target/linux/lantiq/patches-5.10/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch new file mode 100644 index 0000000000..67423d2e97 --- /dev/null +++ b/target/linux/lantiq/patches-5.10/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch @@ -0,0 +1,41 @@ +From 7d9ea9052d6680d2910b8b005c397d95b3a8b012 Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Wed, 7 Apr 2021 21:04:39 +0200 +Subject: [PATCH 3/5] MIPS: lantiq: dma: fix burst length for DEU + +The current definition of 2W burst length is invalid. +This patch fixes it. Current downstream DEU driver doesn't +use DMA. An incorrect burst length value doesn't cause any +errors. This patch also adds other burst length values. + +Fixes: dfec1a827d2b ("MIPS: Lantiq: Add DMA support") +Signed-off-by: Aleksander Jan Bajkowski +--- + arch/mips/lantiq/xway/dma.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -40,7 +40,11 @@ + #define DMA_IRQ_ACK 0x7e /* IRQ status register */ + #define DMA_POLL BIT(31) /* turn on channel polling */ + #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ +-#define DMA_2W_BURST BIT(1) /* 2 word burst length */ ++#define DMA_PCTRL_2W_BURST 0x1 /* 2 word burst length */ ++#define DMA_PCTRL_4W_BURST 0x2 /* 4 word burst length */ ++#define DMA_PCTRL_8W_BURST 0x3 /* 8 word burst length */ ++#define DMA_TX_BURST_SHIFT 4 /* tx burst shift */ ++#define DMA_RX_BURST_SHIFT 2 /* rx burst shift */ + #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ + #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ + +@@ -191,7 +195,8 @@ ltq_dma_init_port(int p) + break; + + case DMA_PORT_DEU: +- ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2), ++ ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) | ++ (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), + LTQ_DMA_PCTRL); + break; + diff --git a/target/linux/lantiq/patches-5.10/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch b/target/linux/lantiq/patches-5.10/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch new file mode 100644 index 0000000000..fab2440453 --- /dev/null +++ b/target/linux/lantiq/patches-5.10/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch @@ -0,0 +1,84 @@ +From 6615eeb39f7a110a196f20acbfb3a017da4d75d2 Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Fri, 14 May 2021 21:25:08 +0200 +Subject: [PATCH 4/5] MIPS: lantiq: dma: make a burst length configurable in + drivers + +Make a burst length configurable in drivers. + +Signed-off-by: Aleksander Jan Bajkowski +--- + .../include/asm/mach-lantiq/xway/xway_dma.h | 2 +- + arch/mips/lantiq/xway/dma.c | 38 ++++++++++++++++--- + 2 files changed, 34 insertions(+), 6 deletions(-) + +--- a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h ++++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h +@@ -45,6 +45,6 @@ extern void ltq_dma_close(struct ltq_dma + extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch); + extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch); + extern void ltq_dma_free(struct ltq_dma_channel *ch); +-extern void ltq_dma_init_port(int p); ++extern void ltq_dma_init_port(int p, int tx_burst, int rx_burst); + + #endif +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -181,7 +181,7 @@ ltq_dma_free(struct ltq_dma_channel *ch) + EXPORT_SYMBOL_GPL(ltq_dma_free); + + void +-ltq_dma_init_port(int p) ++ltq_dma_init_port(int p, int tx_burst, int rx_burst) + { + ltq_dma_w32(p, LTQ_DMA_PS); + switch (p) { +@@ -190,16 +190,44 @@ ltq_dma_init_port(int p) + * Tell the DMA engine to swap the endianness of data frames and + * drop packets if the channel arbitration fails. + */ +- ltq_dma_w32_mask(0, DMA_ETOP_ENDIANNESS | DMA_PDEN, ++ ltq_dma_w32_mask(0, (DMA_ETOP_ENDIANNESS | DMA_PDEN), + LTQ_DMA_PCTRL); + break; + +- case DMA_PORT_DEU: +- ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) | +- (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), ++ default: ++ break; ++ } ++ ++ switch (rx_burst) { ++ case 8: ++ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_8W_BURST << DMA_RX_BURST_SHIFT), + LTQ_DMA_PCTRL); + break; ++ case 4: ++ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_4W_BURST << DMA_RX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ case 2: ++ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ default: ++ break; ++ } + ++ switch (tx_burst) { ++ case 8: ++ ltq_dma_w32_mask(0x30, (DMA_PCTRL_8W_BURST << DMA_TX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ case 4: ++ ltq_dma_w32_mask(0x30, (DMA_PCTRL_4W_BURST << DMA_TX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ case 2: ++ ltq_dma_w32_mask(0x30, (DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; + default: + break; + } diff --git a/target/linux/lantiq/patches-5.10/0710-net-lantiq-configure-burst-length-for-ethernet.patch b/target/linux/lantiq/patches-5.10/0710-net-lantiq-configure-burst-length-for-ethernet.patch new file mode 100644 index 0000000000..0a2996813a --- /dev/null +++ b/target/linux/lantiq/patches-5.10/0710-net-lantiq-configure-burst-length-for-ethernet.patch @@ -0,0 +1,124 @@ +From ec1a17a11aced3cd756e59d91ad6f50b7a2fabfb Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Sun, 16 May 2021 15:52:06 +0200 +Subject: [PATCH 5/5] net: lantiq: configure burst length for ethernet + +Configure the burst length for Ethernet. This improves Ethernet +performance by 58%. According to the vendor BSP, 8W burst length +is supported by ar9 and newer SoCs. + +The NAT benchmark results on xRX200 (Down/Up): +* 2W: 330 Mb/s +* 4W: 432 Mb/s 372 Mb/s +* 8W: 520 Mb/s 389 Mb/s + +Tested on xRX200 and xRX330. + +Signed-off-by: Aleksander Jan Bajkowski +--- + drivers/net/ethernet/lantiq_etop.c | 21 ++++++++++++++++++--- + drivers/net/ethernet/lantiq_xrx200.c | 21 ++++++++++++++++++--- + 2 files changed, 36 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/lantiq_etop.c ++++ b/drivers/net/ethernet/lantiq_etop.c +@@ -148,6 +148,9 @@ struct ltq_etop_priv { + struct ltq_etop_chan txch; + struct ltq_etop_chan rxch; + ++ int tx_burst_len; ++ int rx_burst_len; ++ + int tx_irq; + int rx_irq; + +@@ -399,7 +402,7 @@ ltq_etop_dma_init(struct net_device *dev + int rx = priv->rx_irq - LTQ_DMA_ETOP; + int err; + +- ltq_dma_init_port(DMA_PORT_ETOP); ++ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len); + + priv->txch.dma.nr = tx; + priv->txch.dma.dev = &priv->pdev->dev; +@@ -676,8 +679,8 @@ ltq_etop_tx(struct sk_buff *skb, struct + return NETDEV_TX_BUSY; + } + +- /* dma needs to start on a 16 byte aligned address */ +- byte_offset = CPHYSADDR(skb->data) % 16; ++ /* dma needs to start on a burst length value aligned address */ ++ byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4); + priv->txch.skb[priv->txch.dma.desc] = skb; + + netif_trans_update(dev); +@@ -925,6 +928,18 @@ static int ltq_etop_probe(struct platfor + spin_lock_init(&priv->lock); + SET_NETDEV_DEV(dev, &pdev->dev); + ++ err = device_property_read_u32(&pdev->dev, "lantiq,tx-burst-length", &priv->tx_burst_len); ++ if (err < 0) { ++ dev_err(&pdev->dev, "unable to read tx-burst-length property\n"); ++ return err; ++ } ++ ++ err = device_property_read_u32(&pdev->dev, "lantiq,rx-burst-length", &priv->rx_burst_len); ++ if (err < 0) { ++ dev_err(&pdev->dev, "unable to read rx-burst-length property\n"); ++ return err; ++ } ++ + netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8); + netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32); + priv->txch.netdev = dev; +--- a/drivers/net/ethernet/lantiq_xrx200.c ++++ b/drivers/net/ethernet/lantiq_xrx200.c +@@ -71,6 +71,9 @@ struct xrx200_priv { + struct net_device *net_dev; + struct device *dev; + ++ int tx_burst_len; ++ int rx_burst_len; ++ + __iomem void *pmac_reg; + }; + +@@ -316,8 +319,8 @@ static netdev_tx_t xrx200_start_xmit(str + if (unlikely(dma_mapping_error(priv->dev, mapping))) + goto err_drop; + +- /* dma needs to start on a 16 byte aligned address */ +- byte_offset = mapping % 16; ++ /* dma needs to start on a burst length value aligned address */ ++ byte_offset = mapping % (priv->tx_burst_len * 4); + + desc->addr = mapping - byte_offset; + /* Make sure the address is written before we give it to HW */ +@@ -369,7 +372,7 @@ static int xrx200_dma_init(struct xrx200 + int ret = 0; + int i; + +- ltq_dma_init_port(DMA_PORT_ETOP); ++ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len); + + ch_rx->dma.nr = XRX200_DMA_RX; + ch_rx->dma.dev = priv->dev; +@@ -487,6 +490,18 @@ static int xrx200_probe(struct platform_ + if (err) + eth_hw_addr_random(net_dev); + ++ err = device_property_read_u32(dev, "lantiq,tx-burst-length", &priv->tx_burst_len); ++ if (err < 0) { ++ dev_err(dev, "unable to read tx-burst-length property\n"); ++ return err; ++ } ++ ++ err = device_property_read_u32(dev, "lantiq,rx-burst-length", &priv->rx_burst_len); ++ if (err < 0) { ++ dev_err(dev, "unable to read rx-burst-length property\n"); ++ return err; ++ } ++ + /* bring up the dma engine and IP core */ + err = xrx200_dma_init(priv); + if (err) diff --git a/target/linux/lantiq/patches-5.4/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch b/target/linux/lantiq/patches-5.4/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch new file mode 100644 index 0000000000..05227c8f89 --- /dev/null +++ b/target/linux/lantiq/patches-5.4/0110-MIPS-lantiq-dma-add-small-delay-after-reset.patch @@ -0,0 +1,32 @@ +From 497acc03cd3918baabe25d46e30c5c62b998e24d Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Sat, 19 Jun 2021 13:38:12 +0200 +Subject: [PATCH 1/5] MIPS: lantiq: dma: add small delay after reset + +Reading the DMA registers immediately after the reset causes +Data Bus Error. Adding a small delay fixes this problem. + +Signed-off-by: Aleksander Jan Bajkowski +--- + arch/mips/lantiq/xway/dma.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -221,6 +222,8 @@ ltq_dma_init(struct platform_device *pde + clk_enable(clk); + ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); + ++ usleep_range(1, 10); ++ + /* disable all interrupts */ + ltq_dma_w32(0, LTQ_DMA_IRNEN); + diff --git a/target/linux/lantiq/patches-5.4/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch b/target/linux/lantiq/patches-5.4/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch new file mode 100644 index 0000000000..5d1862d576 --- /dev/null +++ b/target/linux/lantiq/patches-5.4/0111-MIPS-lantiq-dma-reset-correct-number-of-channel.patch @@ -0,0 +1,68 @@ +From d31260c2f6a5cdddb052ab7cb09560eb23ce6597 Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Thu, 15 Apr 2021 21:28:24 +0200 +Subject: [PATCH 2/5] MIPS: lantiq: dma: reset correct number of channel + +Different SoCs have a different number of channels, e.g .: +* amazon-se has 10 channels, +* danube+ar9 have 20 channels, +* vr9 has 28 channels, +* ar10 has 24 channels. + +We can read the ID register and, depending on the reported +number of channels, reset the appropriate number of channels. + +Signed-off-by: Aleksander Jan Bajkowski +--- + arch/mips/lantiq/xway/dma.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -30,6 +30,7 @@ + #define LTQ_DMA_PCTRL 0x44 + #define LTQ_DMA_IRNEN 0xf4 + ++#define DMA_ID_CHNR GENMASK(26, 20) /* channel number */ + #define DMA_DESCPT BIT(3) /* descriptor complete irq */ + #define DMA_TX BIT(8) /* TX channel direction */ + #define DMA_CHAN_ON BIT(0) /* channel on / off bit */ +@@ -40,7 +41,6 @@ + #define DMA_POLL BIT(31) /* turn on channel polling */ + #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ + #define DMA_2W_BURST BIT(1) /* 2 word burst length */ +-#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ + #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ + #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ + +@@ -206,7 +206,7 @@ ltq_dma_init(struct platform_device *pde + { + struct clk *clk; + struct resource *res; +- unsigned id; ++ unsigned int id, nchannels; + int i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -228,17 +228,18 @@ ltq_dma_init(struct platform_device *pde + ltq_dma_w32(0, LTQ_DMA_IRNEN); + + /* reset/configure each channel */ +- for (i = 0; i < DMA_MAX_CHANNEL; i++) { ++ id = ltq_dma_r32(LTQ_DMA_ID); ++ nchannels = ((id & DMA_ID_CHNR) >> 20); ++ for (i = 0; i < nchannels; i++) { + ltq_dma_w32(i, LTQ_DMA_CS); + ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL); + ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); + ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); + } + +- id = ltq_dma_r32(LTQ_DMA_ID); + dev_info(&pdev->dev, + "Init done - hw rev: %X, ports: %d, channels: %d\n", +- id & 0x1f, (id >> 16) & 0xf, id >> 20); ++ id & 0x1f, (id >> 16) & 0xf, nchannels); + + return 0; + } diff --git a/target/linux/lantiq/patches-5.4/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch b/target/linux/lantiq/patches-5.4/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch new file mode 100644 index 0000000000..67423d2e97 --- /dev/null +++ b/target/linux/lantiq/patches-5.4/0112-MIPS-lantiq-dma-fix-burst-length-for-DEU.patch @@ -0,0 +1,41 @@ +From 7d9ea9052d6680d2910b8b005c397d95b3a8b012 Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Wed, 7 Apr 2021 21:04:39 +0200 +Subject: [PATCH 3/5] MIPS: lantiq: dma: fix burst length for DEU + +The current definition of 2W burst length is invalid. +This patch fixes it. Current downstream DEU driver doesn't +use DMA. An incorrect burst length value doesn't cause any +errors. This patch also adds other burst length values. + +Fixes: dfec1a827d2b ("MIPS: Lantiq: Add DMA support") +Signed-off-by: Aleksander Jan Bajkowski +--- + arch/mips/lantiq/xway/dma.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -40,7 +40,11 @@ + #define DMA_IRQ_ACK 0x7e /* IRQ status register */ + #define DMA_POLL BIT(31) /* turn on channel polling */ + #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ +-#define DMA_2W_BURST BIT(1) /* 2 word burst length */ ++#define DMA_PCTRL_2W_BURST 0x1 /* 2 word burst length */ ++#define DMA_PCTRL_4W_BURST 0x2 /* 4 word burst length */ ++#define DMA_PCTRL_8W_BURST 0x3 /* 8 word burst length */ ++#define DMA_TX_BURST_SHIFT 4 /* tx burst shift */ ++#define DMA_RX_BURST_SHIFT 2 /* rx burst shift */ + #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ + #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ + +@@ -191,7 +195,8 @@ ltq_dma_init_port(int p) + break; + + case DMA_PORT_DEU: +- ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2), ++ ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) | ++ (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), + LTQ_DMA_PCTRL); + break; + diff --git a/target/linux/lantiq/patches-5.4/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch b/target/linux/lantiq/patches-5.4/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch new file mode 100644 index 0000000000..fab2440453 --- /dev/null +++ b/target/linux/lantiq/patches-5.4/0113-MIPS-lantiq-dma-make-a-burst-length-configurable-in-.patch @@ -0,0 +1,84 @@ +From 6615eeb39f7a110a196f20acbfb3a017da4d75d2 Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Fri, 14 May 2021 21:25:08 +0200 +Subject: [PATCH 4/5] MIPS: lantiq: dma: make a burst length configurable in + drivers + +Make a burst length configurable in drivers. + +Signed-off-by: Aleksander Jan Bajkowski +--- + .../include/asm/mach-lantiq/xway/xway_dma.h | 2 +- + arch/mips/lantiq/xway/dma.c | 38 ++++++++++++++++--- + 2 files changed, 34 insertions(+), 6 deletions(-) + +--- a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h ++++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h +@@ -45,6 +45,6 @@ extern void ltq_dma_close(struct ltq_dma + extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch); + extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch); + extern void ltq_dma_free(struct ltq_dma_channel *ch); +-extern void ltq_dma_init_port(int p); ++extern void ltq_dma_init_port(int p, int tx_burst, int rx_burst); + + #endif +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -181,7 +181,7 @@ ltq_dma_free(struct ltq_dma_channel *ch) + EXPORT_SYMBOL_GPL(ltq_dma_free); + + void +-ltq_dma_init_port(int p) ++ltq_dma_init_port(int p, int tx_burst, int rx_burst) + { + ltq_dma_w32(p, LTQ_DMA_PS); + switch (p) { +@@ -190,16 +190,44 @@ ltq_dma_init_port(int p) + * Tell the DMA engine to swap the endianness of data frames and + * drop packets if the channel arbitration fails. + */ +- ltq_dma_w32_mask(0, DMA_ETOP_ENDIANNESS | DMA_PDEN, ++ ltq_dma_w32_mask(0, (DMA_ETOP_ENDIANNESS | DMA_PDEN), + LTQ_DMA_PCTRL); + break; + +- case DMA_PORT_DEU: +- ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) | +- (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), ++ default: ++ break; ++ } ++ ++ switch (rx_burst) { ++ case 8: ++ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_8W_BURST << DMA_RX_BURST_SHIFT), + LTQ_DMA_PCTRL); + break; ++ case 4: ++ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_4W_BURST << DMA_RX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ case 2: ++ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ default: ++ break; ++ } + ++ switch (tx_burst) { ++ case 8: ++ ltq_dma_w32_mask(0x30, (DMA_PCTRL_8W_BURST << DMA_TX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ case 4: ++ ltq_dma_w32_mask(0x30, (DMA_PCTRL_4W_BURST << DMA_TX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; ++ case 2: ++ ltq_dma_w32_mask(0x30, (DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT), ++ LTQ_DMA_PCTRL); ++ break; + default: + break; + } diff --git a/target/linux/lantiq/patches-5.4/0710-net-lantiq-configure-burst-length-for-ethernet.patch b/target/linux/lantiq/patches-5.4/0710-net-lantiq-configure-burst-length-for-ethernet.patch new file mode 100644 index 0000000000..746a09c453 --- /dev/null +++ b/target/linux/lantiq/patches-5.4/0710-net-lantiq-configure-burst-length-for-ethernet.patch @@ -0,0 +1,124 @@ +From ec1a17a11aced3cd756e59d91ad6f50b7a2fabfb Mon Sep 17 00:00:00 2001 +From: Aleksander Jan Bajkowski +Date: Sun, 16 May 2021 15:52:06 +0200 +Subject: [PATCH 5/5] net: lantiq: configure burst length for ethernet + +Configure the burst length for Ethernet. This improves Ethernet +performance by 58%. According to the vendor BSP, 8W burst length +is supported by ar9 and newer SoCs. + +The NAT benchmark results on xRX200 (Down/Up): +* 2W: 330 Mb/s +* 4W: 432 Mb/s 372 Mb/s +* 8W: 520 Mb/s 389 Mb/s + +Tested on xRX200 and xRX330. + +Signed-off-by: Aleksander Jan Bajkowski +--- + drivers/net/ethernet/lantiq_etop.c | 21 ++++++++++++++++++--- + drivers/net/ethernet/lantiq_xrx200.c | 21 ++++++++++++++++++--- + 2 files changed, 36 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/lantiq_etop.c ++++ b/drivers/net/ethernet/lantiq_etop.c +@@ -148,6 +148,9 @@ struct ltq_etop_priv { + struct ltq_etop_chan txch; + struct ltq_etop_chan rxch; + ++ int tx_burst_len; ++ int rx_burst_len; ++ + int tx_irq; + int rx_irq; + +@@ -399,7 +402,7 @@ ltq_etop_dma_init(struct net_device *dev + int rx = priv->rx_irq - LTQ_DMA_ETOP; + int err; + +- ltq_dma_init_port(DMA_PORT_ETOP); ++ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len); + + priv->txch.dma.nr = tx; + priv->txch.dma.dev = &priv->pdev->dev; +@@ -676,8 +679,8 @@ ltq_etop_tx(struct sk_buff *skb, struct + return NETDEV_TX_BUSY; + } + +- /* dma needs to start on a 16 byte aligned address */ +- byte_offset = CPHYSADDR(skb->data) % 16; ++ /* dma needs to start on a burst length value aligned address */ ++ byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4); + priv->txch.skb[priv->txch.dma.desc] = skb; + + netif_trans_update(dev); +@@ -930,6 +933,18 @@ static int ltq_etop_probe(struct platfor + spin_lock_init(&priv->lock); + SET_NETDEV_DEV(dev, &pdev->dev); + ++ err = device_property_read_u32(&pdev->dev, "lantiq,tx-burst-length", &priv->tx_burst_len); ++ if (err < 0) { ++ dev_err(&pdev->dev, "unable to read tx-burst-length property\n"); ++ return err; ++ } ++ ++ err = device_property_read_u32(&pdev->dev, "lantiq,rx-burst-length", &priv->rx_burst_len); ++ if (err < 0) { ++ dev_err(&pdev->dev, "unable to read rx-burst-length property\n"); ++ return err; ++ } ++ + netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8); + netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32); + priv->txch.netdev = dev; +--- a/drivers/net/ethernet/lantiq_xrx200.c ++++ b/drivers/net/ethernet/lantiq_xrx200.c +@@ -71,6 +71,9 @@ struct xrx200_priv { + struct net_device *net_dev; + struct device *dev; + ++ int tx_burst_len; ++ int rx_burst_len; ++ + __iomem void *pmac_reg; + }; + +@@ -315,8 +318,8 @@ static int xrx200_start_xmit(struct sk_b + if (unlikely(dma_mapping_error(priv->dev, mapping))) + goto err_drop; + +- /* dma needs to start on a 16 byte aligned address */ +- byte_offset = mapping % 16; ++ /* dma needs to start on a burst length value aligned address */ ++ byte_offset = mapping % (priv->tx_burst_len * 4); + + desc->addr = mapping - byte_offset; + /* Make sure the address is written before we give it to HW */ +@@ -368,7 +371,7 @@ static int xrx200_dma_init(struct xrx200 + int ret = 0; + int i; + +- ltq_dma_init_port(DMA_PORT_ETOP); ++ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len); + + ch_rx->dma.nr = XRX200_DMA_RX; + ch_rx->dma.dev = priv->dev; +@@ -486,6 +489,18 @@ static int xrx200_probe(struct platform_ + if (err) + eth_hw_addr_random(net_dev); + ++ err = device_property_read_u32(dev, "lantiq,tx-burst-length", &priv->tx_burst_len); ++ if (err < 0) { ++ dev_err(dev, "unable to read tx-burst-length property\n"); ++ return err; ++ } ++ ++ err = device_property_read_u32(dev, "lantiq,rx-burst-length", &priv->rx_burst_len); ++ if (err < 0) { ++ dev_err(dev, "unable to read rx-burst-length property\n"); ++ return err; ++ } ++ + /* bring up the dma engine and IP core */ + err = xrx200_dma_init(priv); + if (err) -- 2.30.2