brcm2708-gpu-fw: update to latest version
[openwrt/staging/dedeckeh.git] / target / linux / brcm2708 / patches-4.4 / 0168-bcm2835-sdhost-Only-claim-one-DMA-channel.patch
1 From 1131510a589ae7262b8861af8d2f4a000710d59c Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Mon, 7 Mar 2016 16:46:39 +0000
4 Subject: [PATCH 168/232] bcm2835-sdhost: Only claim one DMA channel
5
6 With both MMC controllers enabled there are few DMA channels left. The
7 bcm2835-sdhost 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-sdhost.c | 70 ++++++++++++++++++++++++-----------
16 2 files changed, 50 insertions(+), 25 deletions(-)
17
18 --- a/arch/arm/boot/dts/bcm2708_common.dtsi
19 +++ b/arch/arm/boot/dts/bcm2708_common.dtsi
20 @@ -136,9 +136,8 @@
21 reg = <0x7e202000 0x100>;
22 interrupts = <2 24>;
23 clocks = <&clk_core>;
24 - dmas = <&dma 13>,
25 - <&dma 13>;
26 - dma-names = "tx", "rx";
27 + dmas = <&dma 13>;
28 + dma-names = "rx-tx";
29 brcm,overclock-50 = <0>;
30 brcm,pio-limit = <1>;
31 status = "disabled";
32 --- a/drivers/mmc/host/bcm2835-sdhost.c
33 +++ b/drivers/mmc/host/bcm2835-sdhost.c
34 @@ -185,9 +185,10 @@ struct bcm2835_host {
35 unsigned int debug:1; /* Enable debug output */
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; /* Channel in used */
41 + struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */
42 + struct dma_chan *dma_chan; /* Channel in use */
43 + struct dma_slave_config dma_cfg_rx;
44 + struct dma_slave_config dma_cfg_tx;
45 struct dma_async_tx_descriptor *dma_desc;
46 u32 dma_dir;
47 u32 drain_words;
48 @@ -771,12 +772,11 @@ static void bcm2835_sdhost_prepare_dma(s
49 log_event("PRD<", (u32)data, 0);
50 pr_debug("bcm2835_sdhost_prepare_dma()\n");
51
52 + dma_chan = host->dma_chan_rxtx;
53 if (data->flags & MMC_DATA_READ) {
54 - dma_chan = host->dma_chan_rx;
55 dir_data = DMA_FROM_DEVICE;
56 dir_slave = DMA_DEV_TO_MEM;
57 } else {
58 - dma_chan = host->dma_chan_tx;
59 dir_data = DMA_TO_DEVICE;
60 dir_slave = DMA_MEM_TO_DEV;
61 }
62 @@ -813,6 +813,12 @@ static void bcm2835_sdhost_prepare_dma(s
63 host->drain_words = len/4;
64 }
65
66 + /* The parameters have already been validated, so this will not fail */
67 + (void)dmaengine_slave_config(dma_chan,
68 + (dir_data == DMA_FROM_DEVICE) ?
69 + &host->dma_cfg_rx :
70 + &host->dma_cfg_tx);
71 +
72 len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
73 dir_data);
74
75 @@ -1805,28 +1811,46 @@ int bcm2835_sdhost_add_host(struct bcm28
76 spin_lock_init(&host->lock);
77
78 if (host->allow_dma) {
79 - if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
80 - IS_ERR_OR_NULL(host->dma_chan_rx)) {
81 - pr_err("%s: unable to initialise DMA channels. "
82 + if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) {
83 + pr_err("%s: unable to initialise DMA channel. "
84 "Falling back to PIO\n",
85 mmc_hostname(mmc));
86 host->use_dma = false;
87 } else {
88 - host->use_dma = true;
89 -
90 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
91 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
92 cfg.slave_id = 13; /* DREQ channel */
93
94 + /* Validate the slave configurations */
95 +
96 cfg.direction = DMA_MEM_TO_DEV;
97 cfg.src_addr = 0;
98 cfg.dst_addr = host->bus_addr + SDDATA;
99 - ret = dmaengine_slave_config(host->dma_chan_tx, &cfg);
100
101 - cfg.direction = DMA_DEV_TO_MEM;
102 - cfg.src_addr = host->bus_addr + SDDATA;
103 - cfg.dst_addr = 0;
104 - ret = dmaengine_slave_config(host->dma_chan_rx, &cfg);
105 + ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
106 +
107 + if (ret == 0) {
108 + host->dma_cfg_tx = cfg;
109 +
110 + cfg.direction = DMA_DEV_TO_MEM;
111 + cfg.src_addr = host->bus_addr + SDDATA;
112 + cfg.dst_addr = 0;
113 +
114 + ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
115 + }
116 +
117 + if (ret == 0) {
118 + host->dma_cfg_rx = cfg;
119 +
120 + host->use_dma = true;
121 + } else {
122 + pr_err("%s: unable to configure DMA channel. "
123 + "Falling back to PIO\n",
124 + mmc_hostname(mmc));
125 + dma_release_channel(host->dma_chan_rxtx);
126 + host->dma_chan_rxtx = NULL;
127 + host->use_dma = false;
128 + }
129 }
130 } else {
131 host->use_dma = false;
132 @@ -1948,19 +1972,21 @@ static int bcm2835_sdhost_probe(struct p
133
134 if (host->allow_dma) {
135 if (node) {
136 - host->dma_chan_tx =
137 - dma_request_slave_channel(dev, "tx");
138 - host->dma_chan_rx =
139 - dma_request_slave_channel(dev, "rx");
140 + host->dma_chan_rxtx =
141 + dma_request_slave_channel(dev, "rx-tx");
142 + if (!host->dma_chan_rxtx)
143 + host->dma_chan_rxtx =
144 + dma_request_slave_channel(dev, "tx");
145 + if (!host->dma_chan_rxtx)
146 + host->dma_chan_rxtx =
147 + dma_request_slave_channel(dev, "rx");
148 } else {
149 dma_cap_mask_t mask;
150
151 dma_cap_zero(mask);
152 /* we don't care about the channel, any would work */
153 dma_cap_set(DMA_SLAVE, mask);
154 - host->dma_chan_tx =
155 - dma_request_channel(mask, NULL, NULL);
156 - host->dma_chan_rx =
157 + host->dma_chan_rxtx =
158 dma_request_channel(mask, NULL, NULL);
159 }
160 }