mediatek: sync patches and add more ethernet stability fixes
[openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0176-bcm2835-mmc-Only-claim-one-DMA-channel.patch
1 From af80d75abc7604cd9eb1788b0171148d000db09d Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Tue, 8 Mar 2016 09:49:16 +0000
4 Subject: [PATCH 176/180] bcm2835-mmc: Only claim one DMA channel
5
6 With both MMC controllers enabled there are few DMA channels left. The
7 bcm2835-mmc driver only uses DMA in one direction at a time, so it
8 doesn't need to claim two channels.
9
10 See: https://github.com/raspberrypi/linux/issues/1327
11
12 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
13 ---
14  arch/arm/boot/dts/bcm2708_common.dtsi |  5 +--
15  drivers/mmc/host/bcm2835-mmc.c        | 69 +++++++++++++++++++++++++----------
16  2 files changed, 51 insertions(+), 23 deletions(-)
17
18 --- a/arch/arm/boot/dts/bcm2708_common.dtsi
19 +++ b/arch/arm/boot/dts/bcm2708_common.dtsi
20 @@ -232,9 +232,8 @@
21                         reg = <0x7e300000 0x100>;
22                         interrupts = <2 30>;
23                         clocks = <&clk_mmc>;
24 -                       dmas = <&dma 11>,
25 -                              <&dma 11>;
26 -                       dma-names = "tx", "rx";
27 +                       dmas = <&dma 11>;
28 +                       dma-names = "rx-tx";
29                         brcm,overclock-50 = <0>;
30                         status = "disabled";
31                 };
32 --- a/drivers/mmc/host/bcm2835-mmc.c
33 +++ b/drivers/mmc/host/bcm2835-mmc.c
34 @@ -108,8 +108,9 @@ struct bcm2835_host {
35         u32                                             shadow;
36  
37         /*DMA part*/
38 -       struct dma_chan                 *dma_chan_rx;           /* DMA channel for reads */
39 -       struct dma_chan                 *dma_chan_tx;           /* DMA channel for writes */
40 +       struct dma_chan                 *dma_chan_rxtx;         /* DMA channel for reads and writes */
41 +       struct dma_slave_config         dma_cfg_rx;
42 +       struct dma_slave_config         dma_cfg_tx;
43         struct dma_async_tx_descriptor  *tx_desc;       /* descriptor */
44  
45         bool                                    have_dma;
46 @@ -342,7 +343,7 @@ static void bcm2835_mmc_dma_complete(voi
47  
48         if (host->data && !(host->data->flags & MMC_DATA_WRITE)) {
49                 /* otherwise handled in SDHCI IRQ */
50 -               dma_chan = host->dma_chan_rx;
51 +               dma_chan = host->dma_chan_rxtx;
52                 dir_data = DMA_FROM_DEVICE;
53  
54                 dma_unmap_sg(dma_chan->device->dev,
55 @@ -493,16 +494,21 @@ static void bcm2835_mmc_transfer_dma(str
56         if (host->blocks == 0)
57                 return;
58  
59 +       dma_chan = host->dma_chan_rxtx;
60         if (host->data->flags & MMC_DATA_READ) {
61 -               dma_chan = host->dma_chan_rx;
62                 dir_data = DMA_FROM_DEVICE;
63                 dir_slave = DMA_DEV_TO_MEM;
64         } else {
65 -               dma_chan = host->dma_chan_tx;
66                 dir_data = DMA_TO_DEVICE;
67                 dir_slave = DMA_MEM_TO_DEV;
68         }
69  
70 +       /* The parameters have already been validated, so this will not fail */
71 +       (void)dmaengine_slave_config(dma_chan,
72 +                                    (dir_data == DMA_FROM_DEVICE) ?
73 +                                    &host->dma_cfg_rx :
74 +                                    &host->dma_cfg_tx);
75 +
76         BUG_ON(!dma_chan->device);
77         BUG_ON(!dma_chan->device->dev);
78         BUG_ON(!host->data->sg);
79 @@ -936,7 +942,7 @@ static void bcm2835_mmc_data_irq(struct
80                 if  (host->data->flags & MMC_DATA_WRITE) {
81                         /* IRQ handled here */
82  
83 -                       dma_chan = host->dma_chan_tx;
84 +                       dma_chan = host->dma_chan_rxtx;
85                         dir_data = DMA_TO_DEVICE;
86                         dma_unmap_sg(dma_chan->device->dev,
87                                  host->data->sg, host->data->sg_len,
88 @@ -1316,28 +1322,47 @@ static int bcm2835_mmc_add_host(struct b
89         dev_info(dev, "Forcing PIO mode\n");
90         host->have_dma = false;
91  #else
92 -       if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
93 -           IS_ERR_OR_NULL(host->dma_chan_rx)) {
94 -               dev_err(dev, "%s: Unable to initialise DMA channels. Falling back to PIO\n",
95 +       if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) {
96 +               dev_err(dev, "%s: Unable to initialise DMA channel. Falling back to PIO\n",
97                         DRIVER_NAME);
98                 host->have_dma = false;
99         } else {
100 -               dev_info(dev, "DMA channels allocated");
101 -               host->have_dma = true;
102 +               dev_info(dev, "DMA channel allocated");
103  
104                 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
105                 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
106                 cfg.slave_id = 11;              /* DREQ channel */
107  
108 +               /* Validate the slave configurations */
109 +
110                 cfg.direction = DMA_MEM_TO_DEV;
111                 cfg.src_addr = 0;
112                 cfg.dst_addr = host->bus_addr + SDHCI_BUFFER;
113 -               ret = dmaengine_slave_config(host->dma_chan_tx, &cfg);
114  
115 -               cfg.direction = DMA_DEV_TO_MEM;
116 -               cfg.src_addr = host->bus_addr + SDHCI_BUFFER;
117 -               cfg.dst_addr = 0;
118 -               ret = dmaengine_slave_config(host->dma_chan_rx, &cfg);
119 +               ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
120 +
121 +               if (ret == 0) {
122 +                       host->dma_cfg_tx = cfg;
123 +
124 +                       cfg.direction = DMA_DEV_TO_MEM;
125 +                       cfg.src_addr = host->bus_addr + SDHCI_BUFFER;
126 +                       cfg.dst_addr = 0;
127 +
128 +                       ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
129 +               }
130 +
131 +               if (ret == 0) {
132 +                       host->dma_cfg_rx = cfg;
133 +
134 +                       host->use_dma = true;
135 +               } else {
136 +                       pr_err("%s: unable to configure DMA channel. "
137 +                              "Faling back to PIO\n",
138 +                              mmc_hostname(mmc));
139 +                       dma_release_channel(host->dma_chan_rxtx);
140 +                       host->dma_chan_rxtx = NULL;
141 +                       host->use_dma = false;
142 +               }
143         }
144  #endif
145         mmc->max_segs = 128;
146 @@ -1416,16 +1441,20 @@ static int bcm2835_mmc_probe(struct plat
147  
148  #ifndef FORCE_PIO
149         if (node) {
150 -               host->dma_chan_tx = dma_request_slave_channel(dev, "tx");
151 -               host->dma_chan_rx = dma_request_slave_channel(dev, "rx");
152 +               host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx");
153 +               if (!host->dma_chan_rxtx)
154 +                       host->dma_chan_rxtx =
155 +                               dma_request_slave_channel(dev, "tx");
156 +               if (!host->dma_chan_rxtx)
157 +                       host->dma_chan_rxtx =
158 +                               dma_request_slave_channel(dev, "rx");
159         } else {
160                 dma_cap_mask_t mask;
161  
162                 dma_cap_zero(mask);
163                 /* we don't care about the channel, any would work */
164                 dma_cap_set(DMA_SLAVE, mask);
165 -               host->dma_chan_tx = dma_request_channel(mask, NULL, NULL);
166 -               host->dma_chan_rx = dma_request_channel(mask, NULL, NULL);
167 +               host->dma_chan_rxtx = dma_request_channel(mask, NULL, NULL);
168         }
169  #endif
170         clk = devm_clk_get(dev, NULL);