aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/qcom/bam_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/qcom/bam_dma.c')
-rw-r--r--drivers/dma/qcom/bam_dma.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index d5e0a9c3ad5d..969b48176745 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -342,7 +342,7 @@ static const struct reg_offset_data bam_v1_7_reg_info[] = {
342 342
343#define BAM_DESC_FIFO_SIZE SZ_32K 343#define BAM_DESC_FIFO_SIZE SZ_32K
344#define MAX_DESCRIPTORS (BAM_DESC_FIFO_SIZE / sizeof(struct bam_desc_hw) - 1) 344#define MAX_DESCRIPTORS (BAM_DESC_FIFO_SIZE / sizeof(struct bam_desc_hw) - 1)
345#define BAM_MAX_DATA_SIZE (SZ_32K - 8) 345#define BAM_FIFO_SIZE (SZ_32K - 8)
346 346
347struct bam_chan { 347struct bam_chan {
348 struct virt_dma_chan vc; 348 struct virt_dma_chan vc;
@@ -387,6 +387,7 @@ struct bam_device {
387 387
388 /* execution environment ID, from DT */ 388 /* execution environment ID, from DT */
389 u32 ee; 389 u32 ee;
390 bool controlled_remotely;
390 391
391 const struct reg_offset_data *layout; 392 const struct reg_offset_data *layout;
392 393
@@ -458,7 +459,7 @@ static void bam_chan_init_hw(struct bam_chan *bchan,
458 */ 459 */
459 writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)), 460 writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)),
460 bam_addr(bdev, bchan->id, BAM_P_DESC_FIFO_ADDR)); 461 bam_addr(bdev, bchan->id, BAM_P_DESC_FIFO_ADDR));
461 writel_relaxed(BAM_DESC_FIFO_SIZE, 462 writel_relaxed(BAM_FIFO_SIZE,
462 bam_addr(bdev, bchan->id, BAM_P_FIFO_SIZES)); 463 bam_addr(bdev, bchan->id, BAM_P_FIFO_SIZES));
463 464
464 /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */ 465 /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */
@@ -604,7 +605,7 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
604 605
605 /* calculate number of required entries */ 606 /* calculate number of required entries */
606 for_each_sg(sgl, sg, sg_len, i) 607 for_each_sg(sgl, sg, sg_len, i)
607 num_alloc += DIV_ROUND_UP(sg_dma_len(sg), BAM_MAX_DATA_SIZE); 608 num_alloc += DIV_ROUND_UP(sg_dma_len(sg), BAM_FIFO_SIZE);
608 609
609 /* allocate enough room to accomodate the number of entries */ 610 /* allocate enough room to accomodate the number of entries */
610 async_desc = kzalloc(sizeof(*async_desc) + 611 async_desc = kzalloc(sizeof(*async_desc) +
@@ -635,10 +636,10 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
635 desc->addr = cpu_to_le32(sg_dma_address(sg) + 636 desc->addr = cpu_to_le32(sg_dma_address(sg) +
636 curr_offset); 637 curr_offset);
637 638
638 if (remainder > BAM_MAX_DATA_SIZE) { 639 if (remainder > BAM_FIFO_SIZE) {
639 desc->size = cpu_to_le16(BAM_MAX_DATA_SIZE); 640 desc->size = cpu_to_le16(BAM_FIFO_SIZE);
640 remainder -= BAM_MAX_DATA_SIZE; 641 remainder -= BAM_FIFO_SIZE;
641 curr_offset += BAM_MAX_DATA_SIZE; 642 curr_offset += BAM_FIFO_SIZE;
642 } else { 643 } else {
643 desc->size = cpu_to_le16(remainder); 644 desc->size = cpu_to_le16(remainder);
644 remainder = 0; 645 remainder = 0;
@@ -801,13 +802,17 @@ static irqreturn_t bam_dma_irq(int irq, void *data)
801 if (srcs & P_IRQ) 802 if (srcs & P_IRQ)
802 tasklet_schedule(&bdev->task); 803 tasklet_schedule(&bdev->task);
803 804
804 if (srcs & BAM_IRQ) 805 if (srcs & BAM_IRQ) {
805 clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS)); 806 clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS));
806 807
807 /* don't allow reorder of the various accesses to the BAM registers */ 808 /*
808 mb(); 809 * don't allow reorder of the various accesses to the BAM
810 * registers
811 */
812 mb();
809 813
810 writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR)); 814 writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR));
815 }
811 816
812 return IRQ_HANDLED; 817 return IRQ_HANDLED;
813} 818}
@@ -1038,6 +1043,9 @@ static int bam_init(struct bam_device *bdev)
1038 val = readl_relaxed(bam_addr(bdev, 0, BAM_NUM_PIPES)); 1043 val = readl_relaxed(bam_addr(bdev, 0, BAM_NUM_PIPES));
1039 bdev->num_channels = val & BAM_NUM_PIPES_MASK; 1044 bdev->num_channels = val & BAM_NUM_PIPES_MASK;
1040 1045
1046 if (bdev->controlled_remotely)
1047 return 0;
1048
1041 /* s/w reset bam */ 1049 /* s/w reset bam */
1042 /* after reset all pipes are disabled and idle */ 1050 /* after reset all pipes are disabled and idle */
1043 val = readl_relaxed(bam_addr(bdev, 0, BAM_CTRL)); 1051 val = readl_relaxed(bam_addr(bdev, 0, BAM_CTRL));
@@ -1125,6 +1133,9 @@ static int bam_dma_probe(struct platform_device *pdev)
1125 return ret; 1133 return ret;
1126 } 1134 }
1127 1135
1136 bdev->controlled_remotely = of_property_read_bool(pdev->dev.of_node,
1137 "qcom,controlled-remotely");
1138
1128 bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk"); 1139 bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk");
1129 if (IS_ERR(bdev->bamclk)) 1140 if (IS_ERR(bdev->bamclk))
1130 return PTR_ERR(bdev->bamclk); 1141 return PTR_ERR(bdev->bamclk);
@@ -1163,7 +1174,7 @@ static int bam_dma_probe(struct platform_device *pdev)
1163 /* set max dma segment size */ 1174 /* set max dma segment size */
1164 bdev->common.dev = bdev->dev; 1175 bdev->common.dev = bdev->dev;
1165 bdev->common.dev->dma_parms = &bdev->dma_parms; 1176 bdev->common.dev->dma_parms = &bdev->dma_parms;
1166 ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE); 1177 ret = dma_set_max_seg_size(bdev->common.dev, BAM_FIFO_SIZE);
1167 if (ret) { 1178 if (ret) {
1168 dev_err(bdev->dev, "cannot set maximum segment size\n"); 1179 dev_err(bdev->dev, "cannot set maximum segment size\n");
1169 goto err_bam_channel_exit; 1180 goto err_bam_channel_exit;
@@ -1234,6 +1245,9 @@ static int bam_dma_remove(struct platform_device *pdev)
1234 bam_dma_terminate_all(&bdev->channels[i].vc.chan); 1245 bam_dma_terminate_all(&bdev->channels[i].vc.chan);
1235 tasklet_kill(&bdev->channels[i].vc.task); 1246 tasklet_kill(&bdev->channels[i].vc.task);
1236 1247
1248 if (!bdev->channels[i].fifo_virt)
1249 continue;
1250
1237 dma_free_wc(bdev->dev, BAM_DESC_FIFO_SIZE, 1251 dma_free_wc(bdev->dev, BAM_DESC_FIFO_SIZE,
1238 bdev->channels[i].fifo_virt, 1252 bdev->channels[i].fifo_virt,
1239 bdev->channels[i].fifo_phys); 1253 bdev->channels[i].fifo_phys);