aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/sun6i-dma.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 0cabb48b0fb5..0cd13f17fc11 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -42,6 +42,9 @@
42 42
43#define DMA_STAT 0x30 43#define DMA_STAT 0x30
44 44
45/* Offset between DMA_IRQ_EN and DMA_IRQ_STAT limits number of channels */
46#define DMA_MAX_CHANNELS (DMA_IRQ_CHAN_NR * 0x10 / 4)
47
45/* 48/*
46 * sun8i specific registers 49 * sun8i specific registers
47 */ 50 */
@@ -65,7 +68,8 @@
65#define DMA_CHAN_LLI_ADDR 0x08 68#define DMA_CHAN_LLI_ADDR 0x08
66 69
67#define DMA_CHAN_CUR_CFG 0x0c 70#define DMA_CHAN_CUR_CFG 0x0c
68#define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & 0x1f) 71#define DMA_CHAN_MAX_DRQ 0x1f
72#define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & DMA_CHAN_MAX_DRQ)
69#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) 73#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5)
70#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) 74#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5)
71#define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) 75#define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7)
@@ -1174,6 +1178,7 @@ MODULE_DEVICE_TABLE(of, sun6i_dma_match);
1174 1178
1175static int sun6i_dma_probe(struct platform_device *pdev) 1179static int sun6i_dma_probe(struct platform_device *pdev)
1176{ 1180{
1181 struct device_node *np = pdev->dev.of_node;
1177 struct sun6i_dma_dev *sdc; 1182 struct sun6i_dma_dev *sdc;
1178 struct resource *res; 1183 struct resource *res;
1179 int ret, i; 1184 int ret, i;
@@ -1248,6 +1253,26 @@ static int sun6i_dma_probe(struct platform_device *pdev)
1248 sdc->num_vchans = sdc->cfg->nr_max_vchans; 1253 sdc->num_vchans = sdc->cfg->nr_max_vchans;
1249 sdc->max_request = sdc->cfg->nr_max_requests; 1254 sdc->max_request = sdc->cfg->nr_max_requests;
1250 1255
1256 ret = of_property_read_u32(np, "dma-channels", &sdc->num_pchans);
1257 if (ret && !sdc->num_pchans) {
1258 dev_err(&pdev->dev, "Can't get dma-channels.\n");
1259 return ret;
1260 }
1261
1262 ret = of_property_read_u32(np, "dma-requests", &sdc->max_request);
1263 if (ret && !sdc->max_request) {
1264 dev_info(&pdev->dev, "Missing dma-requests, using %u.\n",
1265 DMA_CHAN_MAX_DRQ);
1266 sdc->max_request = DMA_CHAN_MAX_DRQ;
1267 }
1268
1269 /*
1270 * If the number of vchans is not specified, derive it from the
1271 * highest port number, at most one channel per port and direction.
1272 */
1273 if (!sdc->num_vchans)
1274 sdc->num_vchans = 2 * (sdc->max_request + 1);
1275
1251 sdc->pchans = devm_kcalloc(&pdev->dev, sdc->num_pchans, 1276 sdc->pchans = devm_kcalloc(&pdev->dev, sdc->num_pchans,
1252 sizeof(struct sun6i_pchan), GFP_KERNEL); 1277 sizeof(struct sun6i_pchan), GFP_KERNEL);
1253 if (!sdc->pchans) 1278 if (!sdc->pchans)