brcm2708: update 4.1 patches
[openwrt/staging/wigyori.git] / target / linux / brcm2708 / patches-4.1 / 0165-bcm2708-dmaengine-Use-more-DMA-channels-but-not-12.patch
1 From 4e62a443aa8ffecca7918db93329d8bd8210a92c Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Thu, 20 Aug 2015 13:50:18 +0100
4 Subject: [PATCH 165/171] bcm2708-dmaengine: Use more DMA channels (but not 12)
5
6 1) Only the bcm2708_fb drivers uses the legacy DMA API, and
7 it requires a BULK-capable channel, so all other types
8 (FAST, NORMAL and LITE) can be made available to the regular
9 DMA API.
10
11 2) DMA channels 11-14 share an interrupt. The driver can't
12 handle this, so don't use channels 12-14 (12 was used, probably
13 because it appears to have an interrupt, but in reality that
14 interrupt is for activity on ANY channel). This may explain
15 a lockup encountered when running out of DMA channels.
16
17 The combined effect of this patch is to leave 7 DMA channels
18 available + channel 0 for bcm2708_fb via the legacy API.
19
20 See: https://github.com/raspberrypi/linux/issues/1110
21 https://github.com/raspberrypi/linux/issues/1108
22 ---
23 arch/arm/boot/dts/bcm2708_common.dtsi | 5 ++--
24 drivers/dma/bcm2708-dmaengine.c | 43 +++++++++++++++++++++++------------
25 2 files changed, 31 insertions(+), 17 deletions(-)
26
27 --- a/arch/arm/boot/dts/bcm2708_common.dtsi
28 +++ b/arch/arm/boot/dts/bcm2708_common.dtsi
29 @@ -59,11 +59,10 @@
30 <1 24>,
31 <1 25>,
32 <1 26>,
33 - <1 27>,
34 - <1 28>;
35 + <1 27>;
36
37 #dma-cells = <1>;
38 - brcm,dma-channel-mask = <0x7f35>;
39 + brcm,dma-channel-mask = <0x0f35>;
40 };
41
42 intc: interrupt-controller {
43 --- a/drivers/dma/bcm2708-dmaengine.c
44 +++ b/drivers/dma/bcm2708-dmaengine.c
45 @@ -184,7 +184,7 @@ static void vc_dmaman_init(struct vc_dma
46 }
47
48 static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman,
49 - unsigned preferred_feature_set)
50 + unsigned required_feature_set)
51 {
52 u32 chans;
53 int chan = 0;
54 @@ -193,10 +193,8 @@ static int vc_dmaman_chan_alloc(struct v
55 chans = dmaman->chan_available;
56 for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++)
57 /* select the subset of available channels with the desired
58 - feature so long as some of the candidate channels have that
59 - feature */
60 - if ((preferred_feature_set & (1 << feature)) &&
61 - (chans & dmaman->has_feature[feature]))
62 + features */
63 + if (required_feature_set & (1 << feature))
64 chans &= dmaman->has_feature[feature];
65
66 if (!chans)
67 @@ -228,7 +226,7 @@ static int vc_dmaman_chan_free(struct vc
68
69 /* DMA Manager Monitor */
70
71 -extern int bcm_dma_chan_alloc(unsigned preferred_feature_set,
72 +extern int bcm_dma_chan_alloc(unsigned required_feature_set,
73 void __iomem **out_dma_base, int *out_dma_irq)
74 {
75 struct vc_dmaman *dmaman = g_dmaman;
76 @@ -240,7 +238,7 @@ extern int bcm_dma_chan_alloc(unsigned p
77 return -ENODEV;
78
79 mutex_lock(&dmaman->lock);
80 - chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set);
81 + chan = vc_dmaman_chan_alloc(dmaman, required_feature_set);
82 if (chan < 0)
83 goto out;
84
85 @@ -442,6 +440,7 @@ static inline struct bcm2835_desc *to_bc
86 return container_of(t, struct bcm2835_desc, vd.tx);
87 }
88
89 +#if 0
90 static void dma_dumpregs(struct bcm2835_chan *c)
91 {
92 pr_debug("-------------DMA DUMPREGS-------------\n");
93 @@ -457,6 +456,7 @@ static void dma_dumpregs(struct bcm2835_
94 readl(c->chan_base + BCM2835_DMA_NEXTCB));
95 pr_debug("--------------------------------------\n");
96 }
97 +#endif
98
99 static void bcm2835_dma_desc_free(struct virt_dma_desc *vd)
100 {
101 @@ -862,6 +862,7 @@ static struct dma_async_tx_descriptor *b
102 uint32_t len = sg_dma_len(sgent);
103
104 for (j = 0; j < len; j += max_size) {
105 + u32 waits;
106 struct bcm2835_dma_cb *control_block =
107 &d->control_block_base[i+splitct];
108
109 @@ -879,7 +880,7 @@ static struct dma_async_tx_descriptor *b
110 }
111
112 /* Common part */
113 - u32 waits = SDHCI_BCM_DMA_WAITS;
114 + waits = SDHCI_BCM_DMA_WAITS;
115 if ((dma_debug >> 0) & 0x1f)
116 waits = (dma_debug >> 0) & 0x1f;
117 control_block->info |= BCM2835_DMA_WAITS(waits);
118 @@ -1074,6 +1075,14 @@ static int bcm2835_dma_probe(struct plat
119 int rc;
120 int i;
121 int irq;
122 +#ifdef CONFIG_DMA_BCM2708_LEGACY
123 + static const u32 wanted_features[] = {
124 + BCM_DMA_FEATURE_FAST,
125 + BCM_DMA_FEATURE_NORMAL,
126 + BCM_DMA_FEATURE_LITE
127 + };
128 + int j;
129 +#endif
130
131
132 if (!pdev->dev.dma_mask)
133 @@ -1120,20 +1129,24 @@ static int bcm2835_dma_probe(struct plat
134
135 platform_set_drvdata(pdev, od);
136
137 - for (i = 0; i < 5; i++) {
138 + for (i = 0, j = 0; j < ARRAY_SIZE(wanted_features);) {
139 +
140 void __iomem *chan_base;
141 int chan_id;
142
143 - chan_id = bcm_dma_chan_alloc(BCM_DMA_FEATURE_LITE,
144 - &chan_base,
145 - &irq);
146 -
147 - if (chan_id < 0)
148 - break;
149 + chan_id = bcm_dma_chan_alloc(wanted_features[j],
150 + &chan_base,
151 + &irq);
152 +
153 + if (chan_id < 0) {
154 + j++;
155 + continue;
156 + }
157
158 rc = bcm2708_dma_chan_init(od, chan_base, chan_id, irq);
159 if (rc)
160 goto err_no_dma;
161 + i++;
162 }
163
164 if (pdev->dev.of_node) {
165 @@ -1146,6 +1159,8 @@ static int bcm2835_dma_probe(struct plat
166 }
167 }
168
169 + dev_info(&pdev->dev, "Initialized %i DMA channels (+ 1 legacy)\n", i);
170 +
171 #else
172 rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
173 if (rc)