aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/dma-jz4780.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c
index 7683de9fb9ee..184d1a2bf9ba 100644
--- a/drivers/dma/dma-jz4780.c
+++ b/drivers/dma/dma-jz4780.c
@@ -29,6 +29,9 @@
29#define JZ_DMA_REG_DIRQP 0x04 29#define JZ_DMA_REG_DIRQP 0x04
30#define JZ_DMA_REG_DDR 0x08 30#define JZ_DMA_REG_DDR 0x08
31#define JZ_DMA_REG_DDRS 0x0c 31#define JZ_DMA_REG_DDRS 0x0c
32#define JZ_DMA_REG_DCKE 0x10
33#define JZ_DMA_REG_DCKES 0x14
34#define JZ_DMA_REG_DCKEC 0x18
32#define JZ_DMA_REG_DMACP 0x1c 35#define JZ_DMA_REG_DMACP 0x1c
33#define JZ_DMA_REG_DSIRQP 0x20 36#define JZ_DMA_REG_DSIRQP 0x20
34#define JZ_DMA_REG_DSIRQM 0x24 37#define JZ_DMA_REG_DSIRQM 0x24
@@ -87,6 +90,11 @@
87 90
88#define JZ4780_DMA_CTRL_OFFSET 0x1000 91#define JZ4780_DMA_CTRL_OFFSET 0x1000
89 92
93/* macros for use with jz4780_dma_soc_data.flags */
94#define JZ_SOC_DATA_ALLOW_LEGACY_DT BIT(0)
95#define JZ_SOC_DATA_PROGRAMMABLE_DMA BIT(1)
96#define JZ_SOC_DATA_PER_CHAN_PM BIT(2)
97
90/** 98/**
91 * struct jz4780_dma_hwdesc - descriptor structure read by the DMA controller. 99 * struct jz4780_dma_hwdesc - descriptor structure read by the DMA controller.
92 * @dcm: value for the DCM (channel command) register 100 * @dcm: value for the DCM (channel command) register
@@ -133,6 +141,8 @@ struct jz4780_dma_chan {
133 141
134struct jz4780_dma_soc_data { 142struct jz4780_dma_soc_data {
135 unsigned int nb_channels; 143 unsigned int nb_channels;
144 unsigned int transfer_ord_max;
145 unsigned long flags;
136}; 146};
137 147
138struct jz4780_dma_dev { 148struct jz4780_dma_dev {
@@ -195,6 +205,20 @@ static inline void jz4780_dma_ctrl_writel(struct jz4780_dma_dev *jzdma,
195 writel(val, jzdma->ctrl_base + reg); 205 writel(val, jzdma->ctrl_base + reg);
196} 206}
197 207
208static inline void jz4780_dma_chan_enable(struct jz4780_dma_dev *jzdma,
209 unsigned int chn)
210{
211 if (jzdma->soc_data->flags & JZ_SOC_DATA_PER_CHAN_PM)
212 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DCKES, BIT(chn));
213}
214
215static inline void jz4780_dma_chan_disable(struct jz4780_dma_dev *jzdma,
216 unsigned int chn)
217{
218 if (jzdma->soc_data->flags & JZ_SOC_DATA_PER_CHAN_PM)
219 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DCKEC, BIT(chn));
220}
221
198static struct jz4780_dma_desc *jz4780_dma_desc_alloc( 222static struct jz4780_dma_desc *jz4780_dma_desc_alloc(
199 struct jz4780_dma_chan *jzchan, unsigned int count, 223 struct jz4780_dma_chan *jzchan, unsigned int count,
200 enum dma_transaction_type type) 224 enum dma_transaction_type type)
@@ -229,8 +253,10 @@ static void jz4780_dma_desc_free(struct virt_dma_desc *vdesc)
229 kfree(desc); 253 kfree(desc);
230} 254}
231 255
232static uint32_t jz4780_dma_transfer_size(unsigned long val, uint32_t *shift) 256static uint32_t jz4780_dma_transfer_size(struct jz4780_dma_chan *jzchan,
257 unsigned long val, uint32_t *shift)
233{ 258{
259 struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan);
234 int ord = ffs(val) - 1; 260 int ord = ffs(val) - 1;
235 261
236 /* 262 /*
@@ -242,8 +268,8 @@ static uint32_t jz4780_dma_transfer_size(unsigned long val, uint32_t *shift)
242 */ 268 */
243 if (ord == 3) 269 if (ord == 3)
244 ord = 2; 270 ord = 2;
245 else if (ord > 7) 271 else if (ord > jzdma->soc_data->transfer_ord_max)
246 ord = 7; 272 ord = jzdma->soc_data->transfer_ord_max;
247 273
248 *shift = ord; 274 *shift = ord;
249 275
@@ -295,7 +321,7 @@ static int jz4780_dma_setup_hwdesc(struct jz4780_dma_chan *jzchan,
295 * divisible by the transfer size, and we must not use more than the 321 * divisible by the transfer size, and we must not use more than the
296 * maximum burst specified by the user. 322 * maximum burst specified by the user.
297 */ 323 */
298 tsz = jz4780_dma_transfer_size(addr | len | (width * maxburst), 324 tsz = jz4780_dma_transfer_size(jzchan, addr | len | (width * maxburst),
299 &jzchan->transfer_shift); 325 &jzchan->transfer_shift);
300 326
301 switch (width) { 327 switch (width) {
@@ -424,7 +450,7 @@ static struct dma_async_tx_descriptor *jz4780_dma_prep_dma_memcpy(
424 if (!desc) 450 if (!desc)
425 return NULL; 451 return NULL;
426 452
427 tsz = jz4780_dma_transfer_size(dest | src | len, 453 tsz = jz4780_dma_transfer_size(jzchan, dest | src | len,
428 &jzchan->transfer_shift); 454 &jzchan->transfer_shift);
429 455
430 jzchan->transfer_type = JZ_DMA_DRT_AUTO; 456 jzchan->transfer_type = JZ_DMA_DRT_AUTO;
@@ -485,6 +511,9 @@ static void jz4780_dma_begin(struct jz4780_dma_chan *jzchan)
485 (jzchan->curr_hwdesc + 1) % jzchan->desc->count; 511 (jzchan->curr_hwdesc + 1) % jzchan->desc->count;
486 } 512 }
487 513
514 /* Enable the channel's clock. */
515 jz4780_dma_chan_enable(jzdma, jzchan->id);
516
488 /* Use 4-word descriptors. */ 517 /* Use 4-word descriptors. */
489 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0); 518 jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0);
490 519
@@ -532,6 +561,8 @@ static int jz4780_dma_terminate_all(struct dma_chan *chan)
532 jzchan->desc = NULL; 561 jzchan->desc = NULL;
533 } 562 }
534 563
564 jz4780_dma_chan_disable(jzdma, jzchan->id);
565
535 vchan_get_all_descriptors(&jzchan->vchan, &head); 566 vchan_get_all_descriptors(&jzchan->vchan, &head);
536 567
537 spin_unlock_irqrestore(&jzchan->vchan.lock, flags); 568 spin_unlock_irqrestore(&jzchan->vchan.lock, flags);
@@ -543,8 +574,10 @@ static int jz4780_dma_terminate_all(struct dma_chan *chan)
543static void jz4780_dma_synchronize(struct dma_chan *chan) 574static void jz4780_dma_synchronize(struct dma_chan *chan)
544{ 575{
545 struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan); 576 struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan);
577 struct jz4780_dma_dev *jzdma = jz4780_dma_chan_parent(jzchan);
546 578
547 vchan_synchronize(&jzchan->vchan); 579 vchan_synchronize(&jzchan->vchan);
580 jz4780_dma_chan_disable(jzdma, jzchan->id);
548} 581}
549 582
550static int jz4780_dma_config(struct dma_chan *chan, 583static int jz4780_dma_config(struct dma_chan *chan,
@@ -812,13 +845,16 @@ static int jz4780_dma_probe(struct platform_device *pdev)
812 jzdma->ctrl_base = devm_ioremap_resource(dev, res); 845 jzdma->ctrl_base = devm_ioremap_resource(dev, res);
813 if (IS_ERR(jzdma->ctrl_base)) 846 if (IS_ERR(jzdma->ctrl_base))
814 return PTR_ERR(jzdma->ctrl_base); 847 return PTR_ERR(jzdma->ctrl_base);
815 } else { 848 } else if (soc_data->flags & JZ_SOC_DATA_ALLOW_LEGACY_DT) {
816 /* 849 /*
817 * On JZ4780, if the second memory resource was not supplied, 850 * On JZ4780, if the second memory resource was not supplied,
818 * assume we're using an old devicetree, and calculate the 851 * assume we're using an old devicetree, and calculate the
819 * offset to the control registers. 852 * offset to the control registers.
820 */ 853 */
821 jzdma->ctrl_base = jzdma->chn_base + JZ4780_DMA_CTRL_OFFSET; 854 jzdma->ctrl_base = jzdma->chn_base + JZ4780_DMA_CTRL_OFFSET;
855 } else {
856 dev_err(dev, "failed to get I/O memory\n");
857 return -EINVAL;
822 } 858 }
823 859
824 ret = platform_get_irq(pdev, 0); 860 ret = platform_get_irq(pdev, 0);
@@ -879,7 +915,9 @@ static int jz4780_dma_probe(struct platform_device *pdev)
879 */ 915 */
880 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMAC, 916 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMAC,
881 JZ_DMA_DMAC_DMAE | JZ_DMA_DMAC_FMSC); 917 JZ_DMA_DMAC_DMAE | JZ_DMA_DMAC_FMSC);
882 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMACP, 0); 918
919 if (soc_data->flags & JZ_SOC_DATA_PROGRAMMABLE_DMA)
920 jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DMACP, 0);
883 921
884 INIT_LIST_HEAD(&dd->channels); 922 INIT_LIST_HEAD(&dd->channels);
885 923
@@ -935,11 +973,20 @@ static int jz4780_dma_remove(struct platform_device *pdev)
935 return 0; 973 return 0;
936} 974}
937 975
976static const struct jz4780_dma_soc_data jz4770_dma_soc_data = {
977 .nb_channels = 6,
978 .transfer_ord_max = 6,
979 .flags = JZ_SOC_DATA_PER_CHAN_PM,
980};
981
938static const struct jz4780_dma_soc_data jz4780_dma_soc_data = { 982static const struct jz4780_dma_soc_data jz4780_dma_soc_data = {
939 .nb_channels = 32, 983 .nb_channels = 32,
984 .transfer_ord_max = 7,
985 .flags = JZ_SOC_DATA_ALLOW_LEGACY_DT | JZ_SOC_DATA_PROGRAMMABLE_DMA,
940}; 986};
941 987
942static const struct of_device_id jz4780_dma_dt_match[] = { 988static const struct of_device_id jz4780_dma_dt_match[] = {
989 { .compatible = "ingenic,jz4770-dma", .data = &jz4770_dma_soc_data },
943 { .compatible = "ingenic,jz4780-dma", .data = &jz4780_dma_soc_data }, 990 { .compatible = "ingenic,jz4780-dma", .data = &jz4780_dma_soc_data },
944 {}, 991 {},
945}; 992};