diff options
Diffstat (limited to 'drivers/dma/qcom_bam_dma.c')
-rw-r--r-- | drivers/dma/qcom_bam_dma.c | 231 |
1 files changed, 161 insertions, 70 deletions
diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c index 7a4bbb0f80a5..3122a99ec06b 100644 --- a/drivers/dma/qcom_bam_dma.c +++ b/drivers/dma/qcom_bam_dma.c | |||
@@ -79,35 +79,97 @@ struct bam_async_desc { | |||
79 | struct bam_desc_hw desc[0]; | 79 | struct bam_desc_hw desc[0]; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | #define BAM_CTRL 0x0000 | 82 | enum bam_reg { |
83 | #define BAM_REVISION 0x0004 | 83 | BAM_CTRL, |
84 | #define BAM_SW_REVISION 0x0080 | 84 | BAM_REVISION, |
85 | #define BAM_NUM_PIPES 0x003C | 85 | BAM_NUM_PIPES, |
86 | #define BAM_TIMER 0x0040 | 86 | BAM_DESC_CNT_TRSHLD, |
87 | #define BAM_TIMER_CTRL 0x0044 | 87 | BAM_IRQ_SRCS, |
88 | #define BAM_DESC_CNT_TRSHLD 0x0008 | 88 | BAM_IRQ_SRCS_MSK, |
89 | #define BAM_IRQ_SRCS 0x000C | 89 | BAM_IRQ_SRCS_UNMASKED, |
90 | #define BAM_IRQ_SRCS_MSK 0x0010 | 90 | BAM_IRQ_STTS, |
91 | #define BAM_IRQ_SRCS_UNMASKED 0x0030 | 91 | BAM_IRQ_CLR, |
92 | #define BAM_IRQ_STTS 0x0014 | 92 | BAM_IRQ_EN, |
93 | #define BAM_IRQ_CLR 0x0018 | 93 | BAM_CNFG_BITS, |
94 | #define BAM_IRQ_EN 0x001C | 94 | BAM_IRQ_SRCS_EE, |
95 | #define BAM_CNFG_BITS 0x007C | 95 | BAM_IRQ_SRCS_MSK_EE, |
96 | #define BAM_IRQ_SRCS_EE(ee) (0x0800 + ((ee) * 0x80)) | 96 | BAM_P_CTRL, |
97 | #define BAM_IRQ_SRCS_MSK_EE(ee) (0x0804 + ((ee) * 0x80)) | 97 | BAM_P_RST, |
98 | #define BAM_P_CTRL(pipe) (0x1000 + ((pipe) * 0x1000)) | 98 | BAM_P_HALT, |
99 | #define BAM_P_RST(pipe) (0x1004 + ((pipe) * 0x1000)) | 99 | BAM_P_IRQ_STTS, |
100 | #define BAM_P_HALT(pipe) (0x1008 + ((pipe) * 0x1000)) | 100 | BAM_P_IRQ_CLR, |
101 | #define BAM_P_IRQ_STTS(pipe) (0x1010 + ((pipe) * 0x1000)) | 101 | BAM_P_IRQ_EN, |
102 | #define BAM_P_IRQ_CLR(pipe) (0x1014 + ((pipe) * 0x1000)) | 102 | BAM_P_EVNT_DEST_ADDR, |
103 | #define BAM_P_IRQ_EN(pipe) (0x1018 + ((pipe) * 0x1000)) | 103 | BAM_P_EVNT_REG, |
104 | #define BAM_P_EVNT_DEST_ADDR(pipe) (0x182C + ((pipe) * 0x1000)) | 104 | BAM_P_SW_OFSTS, |
105 | #define BAM_P_EVNT_REG(pipe) (0x1818 + ((pipe) * 0x1000)) | 105 | BAM_P_DATA_FIFO_ADDR, |
106 | #define BAM_P_SW_OFSTS(pipe) (0x1800 + ((pipe) * 0x1000)) | 106 | BAM_P_DESC_FIFO_ADDR, |
107 | #define BAM_P_DATA_FIFO_ADDR(pipe) (0x1824 + ((pipe) * 0x1000)) | 107 | BAM_P_EVNT_GEN_TRSHLD, |
108 | #define BAM_P_DESC_FIFO_ADDR(pipe) (0x181C + ((pipe) * 0x1000)) | 108 | BAM_P_FIFO_SIZES, |
109 | #define BAM_P_EVNT_TRSHLD(pipe) (0x1828 + ((pipe) * 0x1000)) | 109 | }; |
110 | #define BAM_P_FIFO_SIZES(pipe) (0x1820 + ((pipe) * 0x1000)) | 110 | |
111 | struct reg_offset_data { | ||
112 | u32 base_offset; | ||
113 | unsigned int pipe_mult, evnt_mult, ee_mult; | ||
114 | }; | ||
115 | |||
116 | static const struct reg_offset_data bam_v1_3_reg_info[] = { | ||
117 | [BAM_CTRL] = { 0x0F80, 0x00, 0x00, 0x00 }, | ||
118 | [BAM_REVISION] = { 0x0F84, 0x00, 0x00, 0x00 }, | ||
119 | [BAM_NUM_PIPES] = { 0x0FBC, 0x00, 0x00, 0x00 }, | ||
120 | [BAM_DESC_CNT_TRSHLD] = { 0x0F88, 0x00, 0x00, 0x00 }, | ||
121 | [BAM_IRQ_SRCS] = { 0x0F8C, 0x00, 0x00, 0x00 }, | ||
122 | [BAM_IRQ_SRCS_MSK] = { 0x0F90, 0x00, 0x00, 0x00 }, | ||
123 | [BAM_IRQ_SRCS_UNMASKED] = { 0x0FB0, 0x00, 0x00, 0x00 }, | ||
124 | [BAM_IRQ_STTS] = { 0x0F94, 0x00, 0x00, 0x00 }, | ||
125 | [BAM_IRQ_CLR] = { 0x0F98, 0x00, 0x00, 0x00 }, | ||
126 | [BAM_IRQ_EN] = { 0x0F9C, 0x00, 0x00, 0x00 }, | ||
127 | [BAM_CNFG_BITS] = { 0x0FFC, 0x00, 0x00, 0x00 }, | ||
128 | [BAM_IRQ_SRCS_EE] = { 0x1800, 0x00, 0x00, 0x80 }, | ||
129 | [BAM_IRQ_SRCS_MSK_EE] = { 0x1804, 0x00, 0x00, 0x80 }, | ||
130 | [BAM_P_CTRL] = { 0x0000, 0x80, 0x00, 0x00 }, | ||
131 | [BAM_P_RST] = { 0x0004, 0x80, 0x00, 0x00 }, | ||
132 | [BAM_P_HALT] = { 0x0008, 0x80, 0x00, 0x00 }, | ||
133 | [BAM_P_IRQ_STTS] = { 0x0010, 0x80, 0x00, 0x00 }, | ||
134 | [BAM_P_IRQ_CLR] = { 0x0014, 0x80, 0x00, 0x00 }, | ||
135 | [BAM_P_IRQ_EN] = { 0x0018, 0x80, 0x00, 0x00 }, | ||
136 | [BAM_P_EVNT_DEST_ADDR] = { 0x102C, 0x00, 0x40, 0x00 }, | ||
137 | [BAM_P_EVNT_REG] = { 0x1018, 0x00, 0x40, 0x00 }, | ||
138 | [BAM_P_SW_OFSTS] = { 0x1000, 0x00, 0x40, 0x00 }, | ||
139 | [BAM_P_DATA_FIFO_ADDR] = { 0x1024, 0x00, 0x40, 0x00 }, | ||
140 | [BAM_P_DESC_FIFO_ADDR] = { 0x101C, 0x00, 0x40, 0x00 }, | ||
141 | [BAM_P_EVNT_GEN_TRSHLD] = { 0x1028, 0x00, 0x40, 0x00 }, | ||
142 | [BAM_P_FIFO_SIZES] = { 0x1020, 0x00, 0x40, 0x00 }, | ||
143 | }; | ||
144 | |||
145 | static const struct reg_offset_data bam_v1_4_reg_info[] = { | ||
146 | [BAM_CTRL] = { 0x0000, 0x00, 0x00, 0x00 }, | ||
147 | [BAM_REVISION] = { 0x0004, 0x00, 0x00, 0x00 }, | ||
148 | [BAM_NUM_PIPES] = { 0x003C, 0x00, 0x00, 0x00 }, | ||
149 | [BAM_DESC_CNT_TRSHLD] = { 0x0008, 0x00, 0x00, 0x00 }, | ||
150 | [BAM_IRQ_SRCS] = { 0x000C, 0x00, 0x00, 0x00 }, | ||
151 | [BAM_IRQ_SRCS_MSK] = { 0x0010, 0x00, 0x00, 0x00 }, | ||
152 | [BAM_IRQ_SRCS_UNMASKED] = { 0x0030, 0x00, 0x00, 0x00 }, | ||
153 | [BAM_IRQ_STTS] = { 0x0014, 0x00, 0x00, 0x00 }, | ||
154 | [BAM_IRQ_CLR] = { 0x0018, 0x00, 0x00, 0x00 }, | ||
155 | [BAM_IRQ_EN] = { 0x001C, 0x00, 0x00, 0x00 }, | ||
156 | [BAM_CNFG_BITS] = { 0x007C, 0x00, 0x00, 0x00 }, | ||
157 | [BAM_IRQ_SRCS_EE] = { 0x0800, 0x00, 0x00, 0x80 }, | ||
158 | [BAM_IRQ_SRCS_MSK_EE] = { 0x0804, 0x00, 0x00, 0x80 }, | ||
159 | [BAM_P_CTRL] = { 0x1000, 0x1000, 0x00, 0x00 }, | ||
160 | [BAM_P_RST] = { 0x1004, 0x1000, 0x00, 0x00 }, | ||
161 | [BAM_P_HALT] = { 0x1008, 0x1000, 0x00, 0x00 }, | ||
162 | [BAM_P_IRQ_STTS] = { 0x1010, 0x1000, 0x00, 0x00 }, | ||
163 | [BAM_P_IRQ_CLR] = { 0x1014, 0x1000, 0x00, 0x00 }, | ||
164 | [BAM_P_IRQ_EN] = { 0x1018, 0x1000, 0x00, 0x00 }, | ||
165 | [BAM_P_EVNT_DEST_ADDR] = { 0x102C, 0x00, 0x1000, 0x00 }, | ||
166 | [BAM_P_EVNT_REG] = { 0x1018, 0x00, 0x1000, 0x00 }, | ||
167 | [BAM_P_SW_OFSTS] = { 0x1000, 0x00, 0x1000, 0x00 }, | ||
168 | [BAM_P_DATA_FIFO_ADDR] = { 0x1824, 0x00, 0x1000, 0x00 }, | ||
169 | [BAM_P_DESC_FIFO_ADDR] = { 0x181C, 0x00, 0x1000, 0x00 }, | ||
170 | [BAM_P_EVNT_GEN_TRSHLD] = { 0x1828, 0x00, 0x1000, 0x00 }, | ||
171 | [BAM_P_FIFO_SIZES] = { 0x1820, 0x00, 0x1000, 0x00 }, | ||
172 | }; | ||
111 | 173 | ||
112 | /* BAM CTRL */ | 174 | /* BAM CTRL */ |
113 | #define BAM_SW_RST BIT(0) | 175 | #define BAM_SW_RST BIT(0) |
@@ -297,6 +359,8 @@ struct bam_device { | |||
297 | /* execution environment ID, from DT */ | 359 | /* execution environment ID, from DT */ |
298 | u32 ee; | 360 | u32 ee; |
299 | 361 | ||
362 | const struct reg_offset_data *layout; | ||
363 | |||
300 | struct clk *bamclk; | 364 | struct clk *bamclk; |
301 | int irq; | 365 | int irq; |
302 | 366 | ||
@@ -305,6 +369,23 @@ struct bam_device { | |||
305 | }; | 369 | }; |
306 | 370 | ||
307 | /** | 371 | /** |
372 | * bam_addr - returns BAM register address | ||
373 | * @bdev: bam device | ||
374 | * @pipe: pipe instance (ignored when register doesn't have multiple instances) | ||
375 | * @reg: register enum | ||
376 | */ | ||
377 | static inline void __iomem *bam_addr(struct bam_device *bdev, u32 pipe, | ||
378 | enum bam_reg reg) | ||
379 | { | ||
380 | const struct reg_offset_data r = bdev->layout[reg]; | ||
381 | |||
382 | return bdev->regs + r.base_offset + | ||
383 | r.pipe_mult * pipe + | ||
384 | r.evnt_mult * pipe + | ||
385 | r.ee_mult * bdev->ee; | ||
386 | } | ||
387 | |||
388 | /** | ||
308 | * bam_reset_channel - Reset individual BAM DMA channel | 389 | * bam_reset_channel - Reset individual BAM DMA channel |
309 | * @bchan: bam channel | 390 | * @bchan: bam channel |
310 | * | 391 | * |
@@ -317,8 +398,8 @@ static void bam_reset_channel(struct bam_chan *bchan) | |||
317 | lockdep_assert_held(&bchan->vc.lock); | 398 | lockdep_assert_held(&bchan->vc.lock); |
318 | 399 | ||
319 | /* reset channel */ | 400 | /* reset channel */ |
320 | writel_relaxed(1, bdev->regs + BAM_P_RST(bchan->id)); | 401 | writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_RST)); |
321 | writel_relaxed(0, bdev->regs + BAM_P_RST(bchan->id)); | 402 | writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_RST)); |
322 | 403 | ||
323 | /* don't allow cpu to reorder BAM register accesses done after this */ | 404 | /* don't allow cpu to reorder BAM register accesses done after this */ |
324 | wmb(); | 405 | wmb(); |
@@ -347,17 +428,18 @@ static void bam_chan_init_hw(struct bam_chan *bchan, | |||
347 | * because we allocated 1 more descriptor (8 bytes) than we can use | 428 | * because we allocated 1 more descriptor (8 bytes) than we can use |
348 | */ | 429 | */ |
349 | writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)), | 430 | writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)), |
350 | bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id)); | 431 | bam_addr(bdev, bchan->id, BAM_P_DESC_FIFO_ADDR)); |
351 | writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs + | 432 | writel_relaxed(BAM_DESC_FIFO_SIZE, |
352 | BAM_P_FIFO_SIZES(bchan->id)); | 433 | bam_addr(bdev, bchan->id, BAM_P_FIFO_SIZES)); |
353 | 434 | ||
354 | /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */ | 435 | /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */ |
355 | writel_relaxed(P_DEFAULT_IRQS_EN, bdev->regs + BAM_P_IRQ_EN(bchan->id)); | 436 | writel_relaxed(P_DEFAULT_IRQS_EN, |
437 | bam_addr(bdev, bchan->id, BAM_P_IRQ_EN)); | ||
356 | 438 | ||
357 | /* unmask the specific pipe and EE combo */ | 439 | /* unmask the specific pipe and EE combo */ |
358 | val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); | 440 | val = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); |
359 | val |= BIT(bchan->id); | 441 | val |= BIT(bchan->id); |
360 | writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); | 442 | writel_relaxed(val, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); |
361 | 443 | ||
362 | /* don't allow cpu to reorder the channel enable done below */ | 444 | /* don't allow cpu to reorder the channel enable done below */ |
363 | wmb(); | 445 | wmb(); |
@@ -367,7 +449,7 @@ static void bam_chan_init_hw(struct bam_chan *bchan, | |||
367 | if (dir == DMA_DEV_TO_MEM) | 449 | if (dir == DMA_DEV_TO_MEM) |
368 | val |= P_DIRECTION; | 450 | val |= P_DIRECTION; |
369 | 451 | ||
370 | writel_relaxed(val, bdev->regs + BAM_P_CTRL(bchan->id)); | 452 | writel_relaxed(val, bam_addr(bdev, bchan->id, BAM_P_CTRL)); |
371 | 453 | ||
372 | bchan->initialized = 1; | 454 | bchan->initialized = 1; |
373 | 455 | ||
@@ -432,12 +514,12 @@ static void bam_free_chan(struct dma_chan *chan) | |||
432 | bchan->fifo_virt = NULL; | 514 | bchan->fifo_virt = NULL; |
433 | 515 | ||
434 | /* mask irq for pipe/channel */ | 516 | /* mask irq for pipe/channel */ |
435 | val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); | 517 | val = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); |
436 | val &= ~BIT(bchan->id); | 518 | val &= ~BIT(bchan->id); |
437 | writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); | 519 | writel_relaxed(val, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); |
438 | 520 | ||
439 | /* disable irq */ | 521 | /* disable irq */ |
440 | writel_relaxed(0, bdev->regs + BAM_P_IRQ_EN(bchan->id)); | 522 | writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN)); |
441 | } | 523 | } |
442 | 524 | ||
443 | /** | 525 | /** |
@@ -583,14 +665,14 @@ static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
583 | switch (cmd) { | 665 | switch (cmd) { |
584 | case DMA_PAUSE: | 666 | case DMA_PAUSE: |
585 | spin_lock_irqsave(&bchan->vc.lock, flag); | 667 | spin_lock_irqsave(&bchan->vc.lock, flag); |
586 | writel_relaxed(1, bdev->regs + BAM_P_HALT(bchan->id)); | 668 | writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT)); |
587 | bchan->paused = 1; | 669 | bchan->paused = 1; |
588 | spin_unlock_irqrestore(&bchan->vc.lock, flag); | 670 | spin_unlock_irqrestore(&bchan->vc.lock, flag); |
589 | break; | 671 | break; |
590 | 672 | ||
591 | case DMA_RESUME: | 673 | case DMA_RESUME: |
592 | spin_lock_irqsave(&bchan->vc.lock, flag); | 674 | spin_lock_irqsave(&bchan->vc.lock, flag); |
593 | writel_relaxed(0, bdev->regs + BAM_P_HALT(bchan->id)); | 675 | writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT)); |
594 | bchan->paused = 0; | 676 | bchan->paused = 0; |
595 | spin_unlock_irqrestore(&bchan->vc.lock, flag); | 677 | spin_unlock_irqrestore(&bchan->vc.lock, flag); |
596 | break; | 678 | break; |
@@ -626,7 +708,7 @@ static u32 process_channel_irqs(struct bam_device *bdev) | |||
626 | unsigned long flags; | 708 | unsigned long flags; |
627 | struct bam_async_desc *async_desc; | 709 | struct bam_async_desc *async_desc; |
628 | 710 | ||
629 | srcs = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_EE(bdev->ee)); | 711 | srcs = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_EE)); |
630 | 712 | ||
631 | /* return early if no pipe/channel interrupts are present */ | 713 | /* return early if no pipe/channel interrupts are present */ |
632 | if (!(srcs & P_IRQ)) | 714 | if (!(srcs & P_IRQ)) |
@@ -639,11 +721,9 @@ static u32 process_channel_irqs(struct bam_device *bdev) | |||
639 | continue; | 721 | continue; |
640 | 722 | ||
641 | /* clear pipe irq */ | 723 | /* clear pipe irq */ |
642 | pipe_stts = readl_relaxed(bdev->regs + | 724 | pipe_stts = readl_relaxed(bam_addr(bdev, i, BAM_P_IRQ_STTS)); |
643 | BAM_P_IRQ_STTS(i)); | ||
644 | 725 | ||
645 | writel_relaxed(pipe_stts, bdev->regs + | 726 | writel_relaxed(pipe_stts, bam_addr(bdev, i, BAM_P_IRQ_CLR)); |
646 | BAM_P_IRQ_CLR(i)); | ||
647 | 727 | ||
648 | spin_lock_irqsave(&bchan->vc.lock, flags); | 728 | spin_lock_irqsave(&bchan->vc.lock, flags); |
649 | async_desc = bchan->curr_txd; | 729 | async_desc = bchan->curr_txd; |
@@ -694,12 +774,12 @@ static irqreturn_t bam_dma_irq(int irq, void *data) | |||
694 | tasklet_schedule(&bdev->task); | 774 | tasklet_schedule(&bdev->task); |
695 | 775 | ||
696 | if (srcs & BAM_IRQ) | 776 | if (srcs & BAM_IRQ) |
697 | clr_mask = readl_relaxed(bdev->regs + BAM_IRQ_STTS); | 777 | clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS)); |
698 | 778 | ||
699 | /* don't allow reorder of the various accesses to the BAM registers */ | 779 | /* don't allow reorder of the various accesses to the BAM registers */ |
700 | mb(); | 780 | mb(); |
701 | 781 | ||
702 | writel_relaxed(clr_mask, bdev->regs + BAM_IRQ_CLR); | 782 | writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR)); |
703 | 783 | ||
704 | return IRQ_HANDLED; | 784 | return IRQ_HANDLED; |
705 | } | 785 | } |
@@ -763,7 +843,7 @@ static void bam_apply_new_config(struct bam_chan *bchan, | |||
763 | else | 843 | else |
764 | maxburst = bchan->slave.dst_maxburst; | 844 | maxburst = bchan->slave.dst_maxburst; |
765 | 845 | ||
766 | writel_relaxed(maxburst, bdev->regs + BAM_DESC_CNT_TRSHLD); | 846 | writel_relaxed(maxburst, bam_addr(bdev, 0, BAM_DESC_CNT_TRSHLD)); |
767 | 847 | ||
768 | bchan->reconfigure = 0; | 848 | bchan->reconfigure = 0; |
769 | } | 849 | } |
@@ -830,7 +910,7 @@ static void bam_start_dma(struct bam_chan *bchan) | |||
830 | /* ensure descriptor writes and dma start not reordered */ | 910 | /* ensure descriptor writes and dma start not reordered */ |
831 | wmb(); | 911 | wmb(); |
832 | writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw), | 912 | writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw), |
833 | bdev->regs + BAM_P_EVNT_REG(bchan->id)); | 913 | bam_addr(bdev, bchan->id, BAM_P_EVNT_REG)); |
834 | } | 914 | } |
835 | 915 | ||
836 | /** | 916 | /** |
@@ -918,43 +998,44 @@ static int bam_init(struct bam_device *bdev) | |||
918 | u32 val; | 998 | u32 val; |
919 | 999 | ||
920 | /* read revision and configuration information */ | 1000 | /* read revision and configuration information */ |
921 | val = readl_relaxed(bdev->regs + BAM_REVISION) >> NUM_EES_SHIFT; | 1001 | val = readl_relaxed(bam_addr(bdev, 0, BAM_REVISION)) >> NUM_EES_SHIFT; |
922 | val &= NUM_EES_MASK; | 1002 | val &= NUM_EES_MASK; |
923 | 1003 | ||
924 | /* check that configured EE is within range */ | 1004 | /* check that configured EE is within range */ |
925 | if (bdev->ee >= val) | 1005 | if (bdev->ee >= val) |
926 | return -EINVAL; | 1006 | return -EINVAL; |
927 | 1007 | ||
928 | val = readl_relaxed(bdev->regs + BAM_NUM_PIPES); | 1008 | val = readl_relaxed(bam_addr(bdev, 0, BAM_NUM_PIPES)); |
929 | bdev->num_channels = val & BAM_NUM_PIPES_MASK; | 1009 | bdev->num_channels = val & BAM_NUM_PIPES_MASK; |
930 | 1010 | ||
931 | /* s/w reset bam */ | 1011 | /* s/w reset bam */ |
932 | /* after reset all pipes are disabled and idle */ | 1012 | /* after reset all pipes are disabled and idle */ |
933 | val = readl_relaxed(bdev->regs + BAM_CTRL); | 1013 | val = readl_relaxed(bam_addr(bdev, 0, BAM_CTRL)); |
934 | val |= BAM_SW_RST; | 1014 | val |= BAM_SW_RST; |
935 | writel_relaxed(val, bdev->regs + BAM_CTRL); | 1015 | writel_relaxed(val, bam_addr(bdev, 0, BAM_CTRL)); |
936 | val &= ~BAM_SW_RST; | 1016 | val &= ~BAM_SW_RST; |
937 | writel_relaxed(val, bdev->regs + BAM_CTRL); | 1017 | writel_relaxed(val, bam_addr(bdev, 0, BAM_CTRL)); |
938 | 1018 | ||
939 | /* make sure previous stores are visible before enabling BAM */ | 1019 | /* make sure previous stores are visible before enabling BAM */ |
940 | wmb(); | 1020 | wmb(); |
941 | 1021 | ||
942 | /* enable bam */ | 1022 | /* enable bam */ |
943 | val |= BAM_EN; | 1023 | val |= BAM_EN; |
944 | writel_relaxed(val, bdev->regs + BAM_CTRL); | 1024 | writel_relaxed(val, bam_addr(bdev, 0, BAM_CTRL)); |
945 | 1025 | ||
946 | /* set descriptor threshhold, start with 4 bytes */ | 1026 | /* set descriptor threshhold, start with 4 bytes */ |
947 | writel_relaxed(DEFAULT_CNT_THRSHLD, bdev->regs + BAM_DESC_CNT_TRSHLD); | 1027 | writel_relaxed(DEFAULT_CNT_THRSHLD, |
1028 | bam_addr(bdev, 0, BAM_DESC_CNT_TRSHLD)); | ||
948 | 1029 | ||
949 | /* Enable default set of h/w workarounds, ie all except BAM_FULL_PIPE */ | 1030 | /* Enable default set of h/w workarounds, ie all except BAM_FULL_PIPE */ |
950 | writel_relaxed(BAM_CNFG_BITS_DEFAULT, bdev->regs + BAM_CNFG_BITS); | 1031 | writel_relaxed(BAM_CNFG_BITS_DEFAULT, bam_addr(bdev, 0, BAM_CNFG_BITS)); |
951 | 1032 | ||
952 | /* enable irqs for errors */ | 1033 | /* enable irqs for errors */ |
953 | writel_relaxed(BAM_ERROR_EN | BAM_HRESP_ERR_EN, | 1034 | writel_relaxed(BAM_ERROR_EN | BAM_HRESP_ERR_EN, |
954 | bdev->regs + BAM_IRQ_EN); | 1035 | bam_addr(bdev, 0, BAM_IRQ_EN)); |
955 | 1036 | ||
956 | /* unmask global bam interrupt */ | 1037 | /* unmask global bam interrupt */ |
957 | writel_relaxed(BAM_IRQ_MSK, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); | 1038 | writel_relaxed(BAM_IRQ_MSK, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); |
958 | 1039 | ||
959 | return 0; | 1040 | return 0; |
960 | } | 1041 | } |
@@ -969,9 +1050,18 @@ static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan, | |||
969 | bchan->vc.desc_free = bam_dma_free_desc; | 1050 | bchan->vc.desc_free = bam_dma_free_desc; |
970 | } | 1051 | } |
971 | 1052 | ||
1053 | static const struct of_device_id bam_of_match[] = { | ||
1054 | { .compatible = "qcom,bam-v1.3.0", .data = &bam_v1_3_reg_info }, | ||
1055 | { .compatible = "qcom,bam-v1.4.0", .data = &bam_v1_4_reg_info }, | ||
1056 | {} | ||
1057 | }; | ||
1058 | |||
1059 | MODULE_DEVICE_TABLE(of, bam_of_match); | ||
1060 | |||
972 | static int bam_dma_probe(struct platform_device *pdev) | 1061 | static int bam_dma_probe(struct platform_device *pdev) |
973 | { | 1062 | { |
974 | struct bam_device *bdev; | 1063 | struct bam_device *bdev; |
1064 | const struct of_device_id *match; | ||
975 | struct resource *iores; | 1065 | struct resource *iores; |
976 | int ret, i; | 1066 | int ret, i; |
977 | 1067 | ||
@@ -981,6 +1071,14 @@ static int bam_dma_probe(struct platform_device *pdev) | |||
981 | 1071 | ||
982 | bdev->dev = &pdev->dev; | 1072 | bdev->dev = &pdev->dev; |
983 | 1073 | ||
1074 | match = of_match_node(bam_of_match, pdev->dev.of_node); | ||
1075 | if (!match) { | ||
1076 | dev_err(&pdev->dev, "Unsupported BAM module\n"); | ||
1077 | return -ENODEV; | ||
1078 | } | ||
1079 | |||
1080 | bdev->layout = match->data; | ||
1081 | |||
984 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1082 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
985 | bdev->regs = devm_ioremap_resource(&pdev->dev, iores); | 1083 | bdev->regs = devm_ioremap_resource(&pdev->dev, iores); |
986 | if (IS_ERR(bdev->regs)) | 1084 | if (IS_ERR(bdev->regs)) |
@@ -1084,7 +1182,7 @@ static int bam_dma_remove(struct platform_device *pdev) | |||
1084 | dma_async_device_unregister(&bdev->common); | 1182 | dma_async_device_unregister(&bdev->common); |
1085 | 1183 | ||
1086 | /* mask all interrupts for this execution environment */ | 1184 | /* mask all interrupts for this execution environment */ |
1087 | writel_relaxed(0, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee)); | 1185 | writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); |
1088 | 1186 | ||
1089 | devm_free_irq(bdev->dev, bdev->irq, bdev); | 1187 | devm_free_irq(bdev->dev, bdev->irq, bdev); |
1090 | 1188 | ||
@@ -1104,18 +1202,11 @@ static int bam_dma_remove(struct platform_device *pdev) | |||
1104 | return 0; | 1202 | return 0; |
1105 | } | 1203 | } |
1106 | 1204 | ||
1107 | static const struct of_device_id bam_of_match[] = { | ||
1108 | { .compatible = "qcom,bam-v1.4.0", }, | ||
1109 | {} | ||
1110 | }; | ||
1111 | MODULE_DEVICE_TABLE(of, bam_of_match); | ||
1112 | |||
1113 | static struct platform_driver bam_dma_driver = { | 1205 | static struct platform_driver bam_dma_driver = { |
1114 | .probe = bam_dma_probe, | 1206 | .probe = bam_dma_probe, |
1115 | .remove = bam_dma_remove, | 1207 | .remove = bam_dma_remove, |
1116 | .driver = { | 1208 | .driver = { |
1117 | .name = "bam-dma-engine", | 1209 | .name = "bam-dma-engine", |
1118 | .owner = THIS_MODULE, | ||
1119 | .of_match_table = bam_of_match, | 1210 | .of_match_table = bam_of_match, |
1120 | }, | 1211 | }, |
1121 | }; | 1212 | }; |