sunxi: backport increased SATA/AHCI DMA TX/RX FIFOs
authorAleksander Jan Bajkowski <A.Bajkowski@stud.elka.pw.edu.pl>
Wed, 5 Feb 2020 19:31:00 +0000 (20:31 +0100)
committerPetr Štetiar <ynezz@true.cz>
Thu, 13 Feb 2020 16:45:46 +0000 (17:45 +0100)
This backports SATA performance boost from 5.3 kernel:

 Increasing the SATA/AHCI DMA TX/RX FIFOs (P0DMACR.TXTS and .RXTS, ie.
 TX_TRANSACTION_SIZE and RX_TRANSACTION_SIZE) from default 0x0 each to
 0x3 each, gives a write performance boost of 120 MiB/s to 132 MiB/s from
 lame 36 MiB/s to 45 MiB/s previously.  Read performance is above 200
 MiB/s. [tested on SSD using dd bs=4K/8K/12K/16K/20K/24K/32K: peak-perf
 at 12K]

 dd bs  Before MB/s  After MB/s  Increase
 4k            14.4        16.5       15%
 64k           34.5        74.4      116%
 1M            40.5        93.2      130%

Ref: https://forum.openwrt.org/t/sunxi-sata-write-speed-patch/54555/5
Signed-off-by: Aleksander Jan Bajkowski <A.Bajkowski@stud.elka.pw.edu.pl>
[commit subject & description tweaks]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
target/linux/sunxi/patches-4.19/010-v5.3-drivers-ata-ahci_sunxi-Increased-SATA-AHCI-DMA-TX-RX.patch [new file with mode: 0644]

diff --git a/target/linux/sunxi/patches-4.19/010-v5.3-drivers-ata-ahci_sunxi-Increased-SATA-AHCI-DMA-TX-RX.patch b/target/linux/sunxi/patches-4.19/010-v5.3-drivers-ata-ahci_sunxi-Increased-SATA-AHCI-DMA-TX-RX.patch
new file mode 100644 (file)
index 0000000..74e51c0
--- /dev/null
@@ -0,0 +1,94 @@
+From 120357ea176e420d313cf8cf2ff35fbe233d3bab Mon Sep 17 00:00:00 2001
+From: Uenal Mutlu <um@mutluit.com>
+Date: Mon, 13 May 2019 16:24:10 +0200
+Subject: [PATCH] drivers: ata: ahci_sunxi: Increased SATA/AHCI DMA TX/RX FIFOs
+
+Increasing the SATA/AHCI DMA TX/RX FIFOs (P0DMACR.TXTS and .RXTS, ie.
+TX_TRANSACTION_SIZE and RX_TRANSACTION_SIZE) from default 0x0 each
+to 0x3 each, gives a write performance boost of 120 MiB/s to 132 MiB/s
+from lame 36 MiB/s to 45 MiB/s previously.
+Read performance is above 200 MiB/s.
+[tested on SSD using dd bs=4K/8K/12K/16K/20K/24K/32K: peak-perf at 12K]
+
+Tested on the SBCs Banana Pi R1 (aka Lamobo R1) and Banana Pi M1 which
+are based on the Allwinner A20 32bit-SoC (ARMv7-a / arm-linux-gnueabihf).
+These devices are RaspberryPi-like small devices.
+
+This problem of slow SATA write-speed with these small devices lasts
+for about 7 years now (beginning with the A10 SoC). Many commentators
+throughout the years wrongly assumed the slow write speed was a
+hardware limitation. This patch finally solves the problem, which
+in fact was just a hard-to-find software problem due to lack of
+SATA/AHCI documentation by the SoC-maker Allwinner Technology.
+
+Lists of the affected sunxi and other boards and SoCs with SATA using
+the ahci_sunxi driver:
+  $ grep -i -e "^&ahci" arch/arm/boot/dts/sun*dts
+  and http://linux-sunxi.org/SATA#Devices_with_SATA_ports
+  See also http://linux-sunxi.org/Category:Devices_with_SATA_port
+
+Tested-by: Chen-Yu Tsai <wens@csie.org>
+Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Uenal Mutlu <um@mutluit.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+---
+ drivers/ata/ahci_sunxi.c | 47 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 45 insertions(+), 2 deletions(-)
+
+--- a/drivers/ata/ahci_sunxi.c
++++ b/drivers/ata/ahci_sunxi.c
+@@ -157,8 +157,51 @@ static void ahci_sunxi_start_engine(stru
+       void __iomem *port_mmio = ahci_port_base(ap);
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+-      /* Setup DMA before DMA start */
+-      sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400);
++      /* Setup DMA before DMA start
++       *
++       * NOTE: A similar SoC with SATA/AHCI by Texas Instruments documents
++       *   this Vendor Specific Port (P0DMACR, aka PxDMACR) in its
++       *   User's Guide document (TMS320C674x/OMAP-L1x Processor
++       *   Serial ATA (SATA) Controller, Literature Number: SPRUGJ8C,
++       *   March 2011, Chapter 4.33 Port DMA Control Register (P0DMACR),
++       *   p.68, https://www.ti.com/lit/ug/sprugj8c/sprugj8c.pdf)
++       *   as equivalent to the following struct:
++       *
++       *   struct AHCI_P0DMACR_t
++       *   {
++       *     unsigned TXTS     : 4;
++       *     unsigned RXTS     : 4;
++       *     unsigned TXABL    : 4;
++       *     unsigned RXABL    : 4;
++       *     unsigned Reserved : 16;
++       *   };
++       *
++       *   TXTS: Transmit Transaction Size (TX_TRANSACTION_SIZE).
++       *     This field defines the DMA transaction size in DWORDs for
++       *     transmit (system bus read, device write) operation. [...]
++       *
++       *   RXTS: Receive Transaction Size (RX_TRANSACTION_SIZE).
++       *     This field defines the Port DMA transaction size in DWORDs
++       *     for receive (system bus write, device read) operation. [...]
++       *
++       *   TXABL: Transmit Burst Limit.
++       *     This field allows software to limit the VBUSP master read
++       *     burst size. [...]
++       *
++       *   RXABL: Receive Burst Limit.
++       *     Allows software to limit the VBUSP master write burst
++       *     size. [...]
++       *
++       *   Reserved: Reserved.
++       *
++       *
++       * NOTE: According to the above document, the following alternative
++       *   to the code below could perhaps be a better option
++       *   (or preparation) for possible further improvements later:
++       *     sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ffff,
++       *              0x00000033);
++       */
++      sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ffff, 0x00004433);
+       /* Start DMA */
+       sunxi_setbits(port_mmio + PORT_CMD, PORT_CMD_START);