Skip to content

Commit 4f7b097

Browse files
committed
Merge pull request #1329 from pelwell/sdhost4.4
bcm2835-sdhost: Only claim one DMA channel
2 parents 48f3f77 + af80d75 commit 4f7b097

File tree

3 files changed

+101
-48
lines changed

3 files changed

+101
-48
lines changed

arch/arm/boot/dts/bcm2708_common.dtsi

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,8 @@
136136
reg = <0x7e202000 0x100>;
137137
interrupts = <2 24>;
138138
clocks = <&clk_core>;
139-
dmas = <&dma 13>,
140-
<&dma 13>;
141-
dma-names = "tx", "rx";
139+
dmas = <&dma 13>;
140+
dma-names = "rx-tx";
142141
brcm,overclock-50 = <0>;
143142
brcm,pio-limit = <1>;
144143
status = "disabled";
@@ -233,9 +232,8 @@
233232
reg = <0x7e300000 0x100>;
234233
interrupts = <2 30>;
235234
clocks = <&clk_mmc>;
236-
dmas = <&dma 11>,
237-
<&dma 11>;
238-
dma-names = "tx", "rx";
235+
dmas = <&dma 11>;
236+
dma-names = "rx-tx";
239237
brcm,overclock-50 = <0>;
240238
status = "disabled";
241239
};

drivers/mmc/host/bcm2835-mmc.c

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ struct bcm2835_host {
108108
u32 shadow;
109109

110110
/*DMA part*/
111-
struct dma_chan *dma_chan_rx; /* DMA channel for reads */
112-
struct dma_chan *dma_chan_tx; /* DMA channel for writes */
111+
struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */
112+
struct dma_slave_config dma_cfg_rx;
113+
struct dma_slave_config dma_cfg_tx;
113114
struct dma_async_tx_descriptor *tx_desc; /* descriptor */
114115

115116
bool have_dma;
@@ -342,7 +343,7 @@ static void bcm2835_mmc_dma_complete(void *param)
342343

343344
if (host->data && !(host->data->flags & MMC_DATA_WRITE)) {
344345
/* otherwise handled in SDHCI IRQ */
345-
dma_chan = host->dma_chan_rx;
346+
dma_chan = host->dma_chan_rxtx;
346347
dir_data = DMA_FROM_DEVICE;
347348

348349
dma_unmap_sg(dma_chan->device->dev,
@@ -493,16 +494,21 @@ static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host)
493494
if (host->blocks == 0)
494495
return;
495496

497+
dma_chan = host->dma_chan_rxtx;
496498
if (host->data->flags & MMC_DATA_READ) {
497-
dma_chan = host->dma_chan_rx;
498499
dir_data = DMA_FROM_DEVICE;
499500
dir_slave = DMA_DEV_TO_MEM;
500501
} else {
501-
dma_chan = host->dma_chan_tx;
502502
dir_data = DMA_TO_DEVICE;
503503
dir_slave = DMA_MEM_TO_DEV;
504504
}
505505

506+
/* The parameters have already been validated, so this will not fail */
507+
(void)dmaengine_slave_config(dma_chan,
508+
(dir_data == DMA_FROM_DEVICE) ?
509+
&host->dma_cfg_rx :
510+
&host->dma_cfg_tx);
511+
506512
BUG_ON(!dma_chan->device);
507513
BUG_ON(!dma_chan->device->dev);
508514
BUG_ON(!host->data->sg);
@@ -936,7 +942,7 @@ static void bcm2835_mmc_data_irq(struct bcm2835_host *host, u32 intmask)
936942
if (host->data->flags & MMC_DATA_WRITE) {
937943
/* IRQ handled here */
938944

939-
dma_chan = host->dma_chan_tx;
945+
dma_chan = host->dma_chan_rxtx;
940946
dir_data = DMA_TO_DEVICE;
941947
dma_unmap_sg(dma_chan->device->dev,
942948
host->data->sg, host->data->sg_len,
@@ -1316,28 +1322,47 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host)
13161322
dev_info(dev, "Forcing PIO mode\n");
13171323
host->have_dma = false;
13181324
#else
1319-
if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
1320-
IS_ERR_OR_NULL(host->dma_chan_rx)) {
1321-
dev_err(dev, "%s: Unable to initialise DMA channels. Falling back to PIO\n",
1325+
if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) {
1326+
dev_err(dev, "%s: Unable to initialise DMA channel. Falling back to PIO\n",
13221327
DRIVER_NAME);
13231328
host->have_dma = false;
13241329
} else {
1325-
dev_info(dev, "DMA channels allocated");
1326-
host->have_dma = true;
1330+
dev_info(dev, "DMA channel allocated");
13271331

13281332
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
13291333
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
13301334
cfg.slave_id = 11; /* DREQ channel */
13311335

1336+
/* Validate the slave configurations */
1337+
13321338
cfg.direction = DMA_MEM_TO_DEV;
13331339
cfg.src_addr = 0;
13341340
cfg.dst_addr = host->bus_addr + SDHCI_BUFFER;
1335-
ret = dmaengine_slave_config(host->dma_chan_tx, &cfg);
13361341

1337-
cfg.direction = DMA_DEV_TO_MEM;
1338-
cfg.src_addr = host->bus_addr + SDHCI_BUFFER;
1339-
cfg.dst_addr = 0;
1340-
ret = dmaengine_slave_config(host->dma_chan_rx, &cfg);
1342+
ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
1343+
1344+
if (ret == 0) {
1345+
host->dma_cfg_tx = cfg;
1346+
1347+
cfg.direction = DMA_DEV_TO_MEM;
1348+
cfg.src_addr = host->bus_addr + SDHCI_BUFFER;
1349+
cfg.dst_addr = 0;
1350+
1351+
ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
1352+
}
1353+
1354+
if (ret == 0) {
1355+
host->dma_cfg_rx = cfg;
1356+
1357+
host->use_dma = true;
1358+
} else {
1359+
pr_err("%s: unable to configure DMA channel. "
1360+
"Faling back to PIO\n",
1361+
mmc_hostname(mmc));
1362+
dma_release_channel(host->dma_chan_rxtx);
1363+
host->dma_chan_rxtx = NULL;
1364+
host->use_dma = false;
1365+
}
13411366
}
13421367
#endif
13431368
mmc->max_segs = 128;
@@ -1416,16 +1441,20 @@ static int bcm2835_mmc_probe(struct platform_device *pdev)
14161441

14171442
#ifndef FORCE_PIO
14181443
if (node) {
1419-
host->dma_chan_tx = dma_request_slave_channel(dev, "tx");
1420-
host->dma_chan_rx = dma_request_slave_channel(dev, "rx");
1444+
host->dma_chan_rxtx = dma_request_slave_channel(dev, "rx-tx");
1445+
if (!host->dma_chan_rxtx)
1446+
host->dma_chan_rxtx =
1447+
dma_request_slave_channel(dev, "tx");
1448+
if (!host->dma_chan_rxtx)
1449+
host->dma_chan_rxtx =
1450+
dma_request_slave_channel(dev, "rx");
14211451
} else {
14221452
dma_cap_mask_t mask;
14231453

14241454
dma_cap_zero(mask);
14251455
/* we don't care about the channel, any would work */
14261456
dma_cap_set(DMA_SLAVE, mask);
1427-
host->dma_chan_tx = dma_request_channel(mask, NULL, NULL);
1428-
host->dma_chan_rx = dma_request_channel(mask, NULL, NULL);
1457+
host->dma_chan_rxtx = dma_request_channel(mask, NULL, NULL);
14291458
}
14301459
#endif
14311460
clk = devm_clk_get(dev, NULL);

drivers/mmc/host/bcm2835-sdhost.c

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,10 @@ struct bcm2835_host {
185185
unsigned int debug:1; /* Enable debug output */
186186

187187
/*DMA part*/
188-
struct dma_chan *dma_chan_rx; /* DMA channel for reads */
189-
struct dma_chan *dma_chan_tx; /* DMA channel for writes */
190-
struct dma_chan *dma_chan; /* Channel in used */
188+
struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */
189+
struct dma_chan *dma_chan; /* Channel in use */
190+
struct dma_slave_config dma_cfg_rx;
191+
struct dma_slave_config dma_cfg_tx;
191192
struct dma_async_tx_descriptor *dma_desc;
192193
u32 dma_dir;
193194
u32 drain_words;
@@ -771,12 +772,11 @@ static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host,
771772
log_event("PRD<", (u32)data, 0);
772773
pr_debug("bcm2835_sdhost_prepare_dma()\n");
773774

775+
dma_chan = host->dma_chan_rxtx;
774776
if (data->flags & MMC_DATA_READ) {
775-
dma_chan = host->dma_chan_rx;
776777
dir_data = DMA_FROM_DEVICE;
777778
dir_slave = DMA_DEV_TO_MEM;
778779
} else {
779-
dma_chan = host->dma_chan_tx;
780780
dir_data = DMA_TO_DEVICE;
781781
dir_slave = DMA_MEM_TO_DEV;
782782
}
@@ -813,6 +813,12 @@ static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host,
813813
host->drain_words = len/4;
814814
}
815815

816+
/* The parameters have already been validated, so this will not fail */
817+
(void)dmaengine_slave_config(dma_chan,
818+
(dir_data == DMA_FROM_DEVICE) ?
819+
&host->dma_cfg_rx :
820+
&host->dma_cfg_tx);
821+
816822
len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
817823
dir_data);
818824

@@ -1805,28 +1811,46 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host)
18051811
spin_lock_init(&host->lock);
18061812

18071813
if (host->allow_dma) {
1808-
if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
1809-
IS_ERR_OR_NULL(host->dma_chan_rx)) {
1810-
pr_err("%s: unable to initialise DMA channels. "
1814+
if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) {
1815+
pr_err("%s: unable to initialise DMA channel. "
18111816
"Falling back to PIO\n",
18121817
mmc_hostname(mmc));
18131818
host->use_dma = false;
18141819
} else {
1815-
host->use_dma = true;
1816-
18171820
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
18181821
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
18191822
cfg.slave_id = 13; /* DREQ channel */
18201823

1824+
/* Validate the slave configurations */
1825+
18211826
cfg.direction = DMA_MEM_TO_DEV;
18221827
cfg.src_addr = 0;
18231828
cfg.dst_addr = host->bus_addr + SDDATA;
1824-
ret = dmaengine_slave_config(host->dma_chan_tx, &cfg);
18251829

1826-
cfg.direction = DMA_DEV_TO_MEM;
1827-
cfg.src_addr = host->bus_addr + SDDATA;
1828-
cfg.dst_addr = 0;
1829-
ret = dmaengine_slave_config(host->dma_chan_rx, &cfg);
1830+
ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
1831+
1832+
if (ret == 0) {
1833+
host->dma_cfg_tx = cfg;
1834+
1835+
cfg.direction = DMA_DEV_TO_MEM;
1836+
cfg.src_addr = host->bus_addr + SDDATA;
1837+
cfg.dst_addr = 0;
1838+
1839+
ret = dmaengine_slave_config(host->dma_chan_rxtx, &cfg);
1840+
}
1841+
1842+
if (ret == 0) {
1843+
host->dma_cfg_rx = cfg;
1844+
1845+
host->use_dma = true;
1846+
} else {
1847+
pr_err("%s: unable to configure DMA channel. "
1848+
"Falling back to PIO\n",
1849+
mmc_hostname(mmc));
1850+
dma_release_channel(host->dma_chan_rxtx);
1851+
host->dma_chan_rxtx = NULL;
1852+
host->use_dma = false;
1853+
}
18301854
}
18311855
} else {
18321856
host->use_dma = false;
@@ -1948,19 +1972,21 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev)
19481972

19491973
if (host->allow_dma) {
19501974
if (node) {
1951-
host->dma_chan_tx =
1952-
dma_request_slave_channel(dev, "tx");
1953-
host->dma_chan_rx =
1954-
dma_request_slave_channel(dev, "rx");
1975+
host->dma_chan_rxtx =
1976+
dma_request_slave_channel(dev, "rx-tx");
1977+
if (!host->dma_chan_rxtx)
1978+
host->dma_chan_rxtx =
1979+
dma_request_slave_channel(dev, "tx");
1980+
if (!host->dma_chan_rxtx)
1981+
host->dma_chan_rxtx =
1982+
dma_request_slave_channel(dev, "rx");
19551983
} else {
19561984
dma_cap_mask_t mask;
19571985

19581986
dma_cap_zero(mask);
19591987
/* we don't care about the channel, any would work */
19601988
dma_cap_set(DMA_SLAVE, mask);
1961-
host->dma_chan_tx =
1962-
dma_request_channel(mask, NULL, NULL);
1963-
host->dma_chan_rx =
1989+
host->dma_chan_rxtx =
19641990
dma_request_channel(mask, NULL, NULL);
19651991
}
19661992
}

0 commit comments

Comments
 (0)