mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-05 10:39:23 +00:00
The original vendor's driver programmed the dma controller's AHB HPROT values to enable bufferable, privileged mode. This along with the "same priorty for both channels" fixes the freezes according to @takimata, @And.short, that have been reported on the forum by @ticerex. Furtheremore, @takimata reported that the patch also improved the performance of the HDDs considerably: |<https://forum.lede-project.org/t/wd-mybook-live-duo-two-disks/16195/55> |It seems your patch unleashed the full power of the SATA port. |Where I was previously hitting a really hard limit at around |82 MB/s for reading and 27 MB/s for writing, I am now getting this: | |root@OpenWrt:/mnt# time dd if=/dev/zero of=tempfile bs=1M count=1024 |1024+0 records in |1024+0 records out |real 0m 13.65s |user 0m 0.01s |sys 0m 11.89s | |root@OpenWrt:/mnt# time dd if=tempfile of=/dev/null bs=1M count=1024 |1024+0 records in |1024+0 records out |real 0m 8.41s |user 0m 0.01s |sys 0m 4.70s | |This means: 121 MB/s reading and 75 MB/s writing! | |[...] | |The drive is a WD Green WD10EARX taken from an older MBL Single. |I repeated the test a few times with even larger files to rule out |any caching, I'm still seeing the same great performance. OpenWrt is |now completely on par with the original MBL firmware's performance. Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
26 lines
878 B
Diff
26 lines
878 B
Diff
--- a/drivers/dma/dw/core.c
|
|
+++ b/drivers/dma/dw/core.c
|
|
@@ -167,6 +167,8 @@ static void dwc_initialize_chan_dw(struc
|
|
cfghi |= DWC_CFGH_DST_PER(dwc->dws.dst_id);
|
|
cfghi |= DWC_CFGH_SRC_PER(dwc->dws.src_id);
|
|
|
|
+ cfghi |= DWC_CFGH_PROTCTL(3); /* bufferable + privileged access */
|
|
+
|
|
/* Set polarity of handshake interface */
|
|
cfglo |= hs_polarity ? DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL : 0;
|
|
|
|
@@ -1293,11 +1295,8 @@ int dw_dma_probe(struct dw_dma_chip *chi
|
|
else
|
|
list_add(&dwc->chan.device_node, &dw->dma.channels);
|
|
|
|
- /* 7 is highest priority & 0 is lowest. */
|
|
- if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
|
|
- dwc->priority = pdata->nr_channels - i - 1;
|
|
- else
|
|
- dwc->priority = i;
|
|
+ /* set all channels to the same priority */
|
|
+ dwc->priority = pdata->nr_channels - 1;
|
|
|
|
dwc->ch_regs = &__dw_regs(dw)->CHAN[i];
|
|
spin_lock_init(&dwc->lock);
|