Skip to content

Commit b69386f

Browse files
Jon Linbroonie
authored andcommitted
spi: rockchip-sfc: Using normal memory for dma
Nornal memory CPU copy with cache invalidate is more efficient than uncache memory copy. Signed-off-by: Jon Lin <jon.lin@rock-chips.com> Link: https://patch.msgid.link/20241219010557.333327-1-jon.lin@rock-chips.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent f663898 commit b69386f

File tree

1 file changed

+25
-22
lines changed

1 file changed

+25
-22
lines changed

drivers/spi/spi-rockchip-sfc.c

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,9 @@
156156

157157
#define SFC_MAX_CHIPSELECT_NUM 2
158158

159-
/* The SFC can transfer max 16KB - 1 at one time
160-
* we set it to 15.5KB here for alignment.
161-
*/
162159
#define SFC_MAX_IOSIZE_VER3 (512 * 31)
160+
/* Although up to 4GB, 64KB is enough with less mem reserved */
161+
#define SFC_MAX_IOSIZE_VER4 (0x10000U)
163162

164163
/* DMA is only enabled for large data transmission */
165164
#define SFC_DMA_TRANS_THRETHOLD (0x40)
@@ -456,17 +455,22 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
456455

457456
dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
458457

459-
if (op->data.dir == SPI_MEM_DATA_OUT)
458+
if (op->data.dir == SPI_MEM_DATA_OUT) {
460459
memcpy(sfc->buffer, op->data.buf.out, len);
460+
dma_sync_single_for_device(sfc->dev, sfc->dma_buffer, len, DMA_TO_DEVICE);
461+
}
461462

462463
ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len);
463464
if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
464465
dev_err(sfc->dev, "DMA wait for transfer finish timeout\n");
465466
ret = -ETIMEDOUT;
466467
}
467468
rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA);
468-
if (op->data.dir == SPI_MEM_DATA_IN)
469+
470+
if (op->data.dir == SPI_MEM_DATA_IN) {
471+
dma_sync_single_for_cpu(sfc->dev, sfc->dma_buffer, len, DMA_FROM_DEVICE);
469472
memcpy(op->data.buf.in, sfc->buffer, len);
473+
}
470474

471475
return ret;
472476
}
@@ -631,19 +635,6 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
631635

632636
sfc->use_dma = !of_property_read_bool(sfc->dev->of_node, "rockchip,sfc-no-dma");
633637

634-
if (sfc->use_dma) {
635-
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
636-
if (ret) {
637-
dev_warn(dev, "Unable to set dma mask\n");
638-
return ret;
639-
}
640-
641-
sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3,
642-
&sfc->dma_buffer, GFP_KERNEL);
643-
if (!sfc->buffer)
644-
return -ENOMEM;
645-
}
646-
647638
ret = clk_prepare_enable(sfc->hclk);
648639
if (ret) {
649640
dev_err(&pdev->dev, "Failed to enable ahb clk\n");
@@ -674,25 +665,36 @@ static int rockchip_sfc_probe(struct platform_device *pdev)
674665
if (ret)
675666
goto err_irq;
676667

677-
sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
678668
sfc->version = rockchip_sfc_get_version(sfc);
669+
sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
679670

680671
pm_runtime_set_autosuspend_delay(dev, ROCKCHIP_AUTOSUSPEND_DELAY);
681672
pm_runtime_use_autosuspend(dev);
682673
pm_runtime_set_active(dev);
683674
pm_runtime_enable(dev);
684675
pm_runtime_get_noresume(dev);
685676

677+
if (sfc->use_dma) {
678+
sfc->buffer = (u8 *)__get_free_pages(GFP_KERNEL | GFP_DMA32,
679+
get_order(sfc->max_iosize));
680+
if (!sfc->buffer) {
681+
ret = -ENOMEM;
682+
goto err_dma;
683+
}
684+
sfc->dma_buffer = virt_to_phys(sfc->buffer);
685+
}
686+
686687
ret = devm_spi_register_controller(dev, host);
687688
if (ret)
688-
goto err_pm_runtime_free;
689+
goto err_register;
689690

690691
pm_runtime_mark_last_busy(dev);
691692
pm_runtime_put_autosuspend(dev);
692693

693694
return 0;
694-
695-
err_pm_runtime_free:
695+
err_register:
696+
free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize));
697+
err_dma:
696698
pm_runtime_get_sync(dev);
697699
pm_runtime_put_noidle(dev);
698700
pm_runtime_disable(dev);
@@ -712,6 +714,7 @@ static void rockchip_sfc_remove(struct platform_device *pdev)
712714
struct rockchip_sfc *sfc = platform_get_drvdata(pdev);
713715

714716
spi_unregister_controller(host);
717+
free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize));
715718

716719
clk_disable_unprepare(sfc->clk);
717720
clk_disable_unprepare(sfc->hclk);

0 commit comments

Comments
 (0)