summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamin Guo <samin.guo@starfivetech.com>2021-11-17 09:50:45 +0300
committerEmil Renner Berthing <kernel@esmil.dk>2021-12-26 18:41:30 +0300
commitab9557e1e9afda887c9a2107190dfc9645b7c7db (patch)
tree062cad7bbdf8bd08e6cfa1c49b40e4f900088531
parent3fae1b490ff709284e84c9d180b2e60484c7b5ea (diff)
downloadlinux-ab9557e1e9afda887c9a2107190dfc9645b7c7db.tar.xz
dmaengine: dw-axi-dmac: Add StarFive JH7100 support
Signed-off-by: Samin Guo <samin.guo@starfivetech.com> Signed-off-by: Michael Scott <mike@foundries.io> Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-rw-r--r--drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c32
-rw-r--r--drivers/dma/dw-axi-dmac/dw-axi-dmac.h4
2 files changed, 35 insertions, 1 deletions
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 7c7b9f2a5b3b..4c8416edd4e4 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -32,6 +32,8 @@
#include "../dmaengine.h"
#include "../virt-dma.h"
+#include <soc/sifive/sifive_l2_cache.h>
+
/*
* The set of bus widths supported by the DMA controller. DW AXI DMAC supports
* master data bus width up to 512 bits (for both AXI master interfaces), but
@@ -86,7 +88,7 @@ static inline void axi_chan_config_write(struct axi_dma_chan *chan,
cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
- if (chan->chip->dw->hdata->reg_map_8_channels) {
+ if (!IS_ENABLED(CONFIG_SOC_STARFIVE) && chan->chip->dw->hdata->reg_map_8_channels) {
cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
@@ -428,6 +430,25 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
irq_mask |= DWAXIDMAC_IRQ_SUSPENDED;
axi_chan_irq_set(chan, irq_mask);
+ /* flush all the desc */
+ if (IS_ENABLED(CONFIG_SOC_STARFIVE)) {
+ int count = atomic_read(&chan->descs_allocated);
+ int i;
+
+ for (i = 0; i < count; i++) {
+ sifive_l2_flush64_range(first->hw_desc[i].llp,
+ sizeof(*first->hw_desc[i].lli));
+
+ dev_dbg(chan->chip->dev,
+ "sar:%#llx dar:%#llx llp:%#llx ctl:0x%x:%08x\n",
+ first->hw_desc[i].lli->sar,
+ first->hw_desc[i].lli->dar,
+ first->hw_desc[i].lli->llp,
+ first->hw_desc[i].lli->ctl_hi,
+ first->hw_desc[i].lli->ctl_lo);
+ }
+ }
+
axi_chan_enable(chan);
}
@@ -672,8 +693,13 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
+#ifdef CONFIG_SOC_STARFIVE
+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
+ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
+#else
ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
+#endif
hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
set_desc_src_master(hw_desc);
@@ -1473,7 +1499,11 @@ static int dw_probe(struct platform_device *pdev)
* Therefore, set constraint to 1024 * 4.
*/
dw->dma.dev->dma_parms = &dw->dma_parms;
+#ifdef CONFIG_SOC_STARFIVE
+ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
+#else
dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
+#endif
platform_set_drvdata(pdev, chip);
pm_runtime_enable(chip->dev);
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index afb6be92140a..8530e3130b76 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -282,7 +282,11 @@ enum {
#define CH_CTL_L_SRC_MAST BIT(0)
/* CH_CFG_H */
+#ifdef CONFIG_SOC_STARFIVE
+#define CH_CFG_H_PRIORITY_POS 15
+#else
#define CH_CFG_H_PRIORITY_POS 17
+#endif
#define CH_CFG_H_DST_PER_POS 12
#define CH_CFG_H_SRC_PER_POS 7
#define CH_CFG_H_HS_SEL_DST_POS 4