diff mbox series

[OpenWrt-Devel,2/2] apm821xx: attempt to fix sata access freezes

Message ID e674ca144430b2985e6b0b75c1c6830fab8df314.1531581259.git.chunkeey@gmail.com
State Accepted
Delegated to: John Crispin
Headers show
Series [OpenWrt-Devel,1/2,master+18.06] apm821xx: fix usb-otg on 4.14 | expand

Commit Message

Christian Lamparter July 14, 2018, 3:21 p.m. UTC
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" could very
well fix the freezes that have been reported on the forum by
@ticerex and @takimata.

<https://forum.lede-project.org/t/wd-mybook-live-duo-two-disks/16195/46>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
Awaiting confirmation from the original reporters. But if
this turns out to fix the issue, I'll do a separate patch for
18.06 and lede-17.01.
---
 ...-dw-dma-hprot-fix-and-equal-priortiy.patch | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 target/linux/apm821xx/patches-4.14/302-dw-dma-hprot-fix-and-equal-priortiy.patch
diff mbox series

Patch

diff --git a/target/linux/apm821xx/patches-4.14/302-dw-dma-hprot-fix-and-equal-priortiy.patch b/target/linux/apm821xx/patches-4.14/302-dw-dma-hprot-fix-and-equal-priortiy.patch
new file mode 100644
index 0000000000..c6e4331aa9
--- /dev/null
+++ b/target/linux/apm821xx/patches-4.14/302-dw-dma-hprot-fix-and-equal-priortiy.patch
@@ -0,0 +1,25 @@ 
+--- 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);