Commit 2fe5575f authored by Jernej Skrabec's avatar Jernej Skrabec Committed by Vinod Koul

dmaengine: sun6i: Add support for H6 DMA

H6 DMA has more than 32 supported DRQs, which means that configuration
register is slightly rearranged. It also needs additional clock to be
enabled.

Add support for it.
Signed-off-by: default avatarJernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: default avatarClément Péron <peron.clem@gmail.com>
Acked-by: default avatarMaxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 802440bd
...@@ -69,14 +69,19 @@ ...@@ -69,14 +69,19 @@
#define DMA_CHAN_CUR_CFG 0x0c #define DMA_CHAN_CUR_CFG 0x0c
#define DMA_CHAN_MAX_DRQ_A31 0x1f #define DMA_CHAN_MAX_DRQ_A31 0x1f
#define DMA_CHAN_MAX_DRQ_H6 0x3f
#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) #define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31)
#define DMA_CHAN_CFG_SRC_DRQ_H6(x) ((x) & DMA_CHAN_MAX_DRQ_H6)
#define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5) #define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5)
#define DMA_CHAN_CFG_SRC_MODE_H6(x) (((x) & 0x1) << 8)
#define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7)
#define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6)
#define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9)
#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) #define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16)
#define DMA_CHAN_CFG_DST_DRQ_H6(x) (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16)
#define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16) #define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16)
#define DMA_CHAN_CFG_DST_MODE_H6(x) (DMA_CHAN_CFG_SRC_MODE_H6(x) << 16)
#define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16)
#define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16)
#define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16)
...@@ -319,12 +324,24 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) ...@@ -319,12 +324,24 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq)
DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); DMA_CHAN_CFG_DST_DRQ_A31(dst_drq);
} }
static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq)
{
*p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) |
DMA_CHAN_CFG_DST_DRQ_H6(dst_drq);
}
static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode) static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode)
{ {
*p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) | *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) |
DMA_CHAN_CFG_DST_MODE_A31(dst_mode); DMA_CHAN_CFG_DST_MODE_A31(dst_mode);
} }
static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode)
{
*p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) |
DMA_CHAN_CFG_DST_MODE_H6(dst_mode);
}
static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
{ {
struct sun6i_desc *txd = pchan->desc; struct sun6i_desc *txd = pchan->desc;
...@@ -1160,6 +1177,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = { ...@@ -1160,6 +1177,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
}; };
/*
* The H6 binding uses the number of dma channels from the
* device tree node.
*/
static struct sun6i_dma_config sun50i_h6_dma_cfg = {
.clock_autogate_enable = sun6i_enable_clock_autogate_h3,
.set_burst_length = sun6i_set_burst_length_h3,
.set_drq = sun6i_set_drq_h6,
.set_mode = sun6i_set_mode_h6,
.src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
.dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
.has_mbus_clk = true,
};
/* /*
* The V3s have only 8 physical channels, a maximum DRQ port id of 23, * The V3s have only 8 physical channels, a maximum DRQ port id of 23,
* and a total of 24 usable source and destination endpoints. * and a total of 24 usable source and destination endpoints.
...@@ -1190,6 +1229,7 @@ static const struct of_device_id sun6i_dma_match[] = { ...@@ -1190,6 +1229,7 @@ static const struct of_device_id sun6i_dma_match[] = {
{ .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg }, { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg },
{ .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg }, { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg },
{ .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg }, { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
{ .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, sun6i_dma_match); MODULE_DEVICE_TABLE(of, sun6i_dma_match);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment