Skip to content

Commit 6f9e40d

Browse files
Atomar25vinodkoul
authored andcommitted
dmaengine: Actions: Add support for S700 DMA engine
DMA controller present on S700 SoC is compatible with the one on S900 (as most of registers are same), but it has different DMA descriptor structure where registers "fcnt" and "ctrlb" uses different encoding. For instance, on S900 "fcnt" starts at offset 0x0c and uses upper 12 bits whereas on S700, it starts at offset 0x1c and uses lower 12 bits. This commit adds support for DMA controller present on S700. Signed-off-by: Amit Singh Tomar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 57937fa commit 6f9e40d

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

drivers/dma/owl-dma.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ enum owl_dmadesc_offsets {
149149
OWL_DMADESC_SIZE
150150
};
151151

152+
enum owl_dma_id {
153+
S900_DMA,
154+
S700_DMA,
155+
};
156+
152157
/**
153158
* struct owl_dma_lli - Link list for dma transfer
154159
* @hw: hardware link list
@@ -213,6 +218,7 @@ struct owl_dma_vchan {
213218
* @pchans: array of data for the physical channels
214219
* @nr_vchans: the number of physical channels
215220
* @vchans: array of data for the physical channels
221+
* @devid: device id based on OWL SoC
216222
*/
217223
struct owl_dma {
218224
struct dma_device dma;
@@ -227,6 +233,7 @@ struct owl_dma {
227233

228234
unsigned int nr_vchans;
229235
struct owl_dma_vchan *vchans;
236+
enum owl_dma_id devid;
230237
};
231238

232239
static void pchan_update(struct owl_dma_pchan *pchan, u32 reg,
@@ -316,6 +323,10 @@ static inline u32 llc_hw_ctrlb(u32 int_ctl)
316323
{
317324
u32 ctl;
318325

326+
/*
327+
* Irrespective of the SoC, ctrlb value starts filling from
328+
* bit 18.
329+
*/
319330
ctl = BIT_FIELD(int_ctl, 7, 0, 18);
320331

321332
return ctl;
@@ -372,6 +383,7 @@ static inline int owl_dma_cfg_lli(struct owl_dma_vchan *vchan,
372383
struct dma_slave_config *sconfig,
373384
bool is_cyclic)
374385
{
386+
struct owl_dma *od = to_owl_dma(vchan->vc.chan.device);
375387
u32 mode, ctrlb;
376388

377389
mode = OWL_DMA_MODE_PW(0);
@@ -427,14 +439,26 @@ static inline int owl_dma_cfg_lli(struct owl_dma_vchan *vchan,
427439
lli->hw[OWL_DMADESC_DADDR] = dst;
428440
lli->hw[OWL_DMADESC_SRC_STRIDE] = 0;
429441
lli->hw[OWL_DMADESC_DST_STRIDE] = 0;
430-
/*
431-
* Word starts from offset 0xC is shared between frame length
432-
* (max frame length is 1MB) and frame count, where first 20
433-
* bits are for frame length and rest of 12 bits are for frame
434-
* count.
435-
*/
436-
lli->hw[OWL_DMADESC_FLEN] = len | FCNT_VAL << 20;
437-
lli->hw[OWL_DMADESC_CTRLB] = ctrlb;
442+
443+
if (od->devid == S700_DMA) {
444+
/* Max frame length is 1MB */
445+
lli->hw[OWL_DMADESC_FLEN] = len;
446+
/*
447+
* On S700, word starts from offset 0x1C is shared between
448+
* frame count and ctrlb, where first 12 bits are for frame
449+
* count and rest of 20 bits are for ctrlb.
450+
*/
451+
lli->hw[OWL_DMADESC_CTRLB] = FCNT_VAL | ctrlb;
452+
} else {
453+
/*
454+
* On S900, word starts from offset 0xC is shared between
455+
* frame length (max frame length is 1MB) and frame count,
456+
* where first 20 bits are for frame length and rest of
457+
* 12 bits are for frame count.
458+
*/
459+
lli->hw[OWL_DMADESC_FLEN] = len | FCNT_VAL << 20;
460+
lli->hw[OWL_DMADESC_CTRLB] = ctrlb;
461+
}
438462

439463
return 0;
440464
}
@@ -596,7 +620,7 @@ static irqreturn_t owl_dma_interrupt(int irq, void *dev_id)
596620

597621
global_irq_pending = dma_readl(od, OWL_DMA_IRQ_PD0);
598622

599-
if (chan_irq_pending && !(global_irq_pending & BIT(i))) {
623+
if (chan_irq_pending && !(global_irq_pending & BIT(i))) {
600624
dev_dbg(od->dma.dev,
601625
"global and channel IRQ pending match err\n");
602626

@@ -1054,6 +1078,13 @@ static struct dma_chan *owl_dma_of_xlate(struct of_phandle_args *dma_spec,
10541078
return chan;
10551079
}
10561080

1081+
static const struct of_device_id owl_dma_match[] = {
1082+
{ .compatible = "actions,s900-dma", .data = (void *)S900_DMA,},
1083+
{ .compatible = "actions,s700-dma", .data = (void *)S700_DMA,},
1084+
{ /* sentinel */ },
1085+
};
1086+
MODULE_DEVICE_TABLE(of, owl_dma_match);
1087+
10571088
static int owl_dma_probe(struct platform_device *pdev)
10581089
{
10591090
struct device_node *np = pdev->dev.of_node;
@@ -1083,6 +1114,8 @@ static int owl_dma_probe(struct platform_device *pdev)
10831114
dev_info(&pdev->dev, "dma-channels %d, dma-requests %d\n",
10841115
nr_channels, nr_requests);
10851116

1117+
od->devid = (enum owl_dma_id)of_device_get_match_data(&pdev->dev);
1118+
10861119
od->nr_pchans = nr_channels;
10871120
od->nr_vchans = nr_requests;
10881121

@@ -1215,12 +1248,6 @@ static int owl_dma_remove(struct platform_device *pdev)
12151248
return 0;
12161249
}
12171250

1218-
static const struct of_device_id owl_dma_match[] = {
1219-
{ .compatible = "actions,s900-dma", },
1220-
{ /* sentinel */ }
1221-
};
1222-
MODULE_DEVICE_TABLE(of, owl_dma_match);
1223-
12241251
static struct platform_driver owl_dma_driver = {
12251252
.probe = owl_dma_probe,
12261253
.remove = owl_dma_remove,

0 commit comments

Comments
 (0)