Skip to content

Commit 69a47b1

Browse files
basuamdvinodkoul
authored andcommitted
dmaengine: ptdma: Extend ptdma to support multi-channel and version
To support multi-channel functionality with AE4DMA engine, extend the PTDMA code with reusable components. Reviewed-by: Raju Rangoju <[email protected]> Signed-off-by: Basavaraj Natikar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 90a30e2 commit 69a47b1

File tree

3 files changed

+89
-20
lines changed

3 files changed

+89
-20
lines changed

drivers/dma/amd/ae4dma/ae4dma.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#define AE4_Q_BASE_H_OFF 0x1c
3535
#define AE4_Q_SZ 0x20
3636

37+
#define AE4_DMA_VERSION 4
38+
3739
struct ae4_msix {
3840
int msix_count;
3941
struct msix_entry msix_entry[MAX_AE4_HW_QUEUES];

drivers/dma/amd/ptdma/ptdma-dmaengine.c

Lines changed: 85 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,24 @@ static void pt_do_cleanup(struct virt_dma_desc *vd)
9393
kmem_cache_free(pt->dma_desc_cache, desc);
9494
}
9595

96-
static int pt_dma_start_desc(struct pt_dma_desc *desc)
96+
static struct pt_cmd_queue *pt_get_cmd_queue(struct pt_device *pt, struct pt_dma_chan *chan)
97+
{
98+
struct ae4_cmd_queue *ae4cmd_q;
99+
struct pt_cmd_queue *cmd_q;
100+
struct ae4_device *ae4;
101+
102+
if (pt->ver == AE4_DMA_VERSION) {
103+
ae4 = container_of(pt, struct ae4_device, pt);
104+
ae4cmd_q = &ae4->ae4cmd_q[chan->id];
105+
cmd_q = &ae4cmd_q->cmd_q;
106+
} else {
107+
cmd_q = &pt->cmd_q;
108+
}
109+
110+
return cmd_q;
111+
}
112+
113+
static int pt_dma_start_desc(struct pt_dma_desc *desc, struct pt_dma_chan *chan)
97114
{
98115
struct pt_passthru_engine *pt_engine;
99116
struct pt_device *pt;
@@ -104,7 +121,9 @@ static int pt_dma_start_desc(struct pt_dma_desc *desc)
104121

105122
pt_cmd = &desc->pt_cmd;
106123
pt = pt_cmd->pt;
107-
cmd_q = &pt->cmd_q;
124+
125+
cmd_q = pt_get_cmd_queue(pt, chan);
126+
108127
pt_engine = &pt_cmd->passthru;
109128

110129
pt->tdata.cmd = pt_cmd;
@@ -199,7 +218,7 @@ static void pt_cmd_callback(void *data, int err)
199218
if (!desc)
200219
break;
201220

202-
ret = pt_dma_start_desc(desc);
221+
ret = pt_dma_start_desc(desc, chan);
203222
if (!ret)
204223
break;
205224

@@ -234,15 +253,18 @@ static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
234253
{
235254
struct pt_dma_chan *chan = to_pt_chan(dma_chan);
236255
struct pt_passthru_engine *pt_engine;
256+
struct pt_device *pt = chan->pt;
257+
struct ae4_cmd_queue *ae4cmd_q;
237258
struct pt_dma_desc *desc;
259+
struct ae4_device *ae4;
238260
struct pt_cmd *pt_cmd;
239261

240262
desc = pt_alloc_dma_desc(chan, flags);
241263
if (!desc)
242264
return NULL;
243265

244266
pt_cmd = &desc->pt_cmd;
245-
pt_cmd->pt = chan->pt;
267+
pt_cmd->pt = pt;
246268
pt_engine = &pt_cmd->passthru;
247269
pt_cmd->engine = PT_ENGINE_PASSTHRU;
248270
pt_engine->src_dma = src;
@@ -253,6 +275,14 @@ static struct pt_dma_desc *pt_create_desc(struct dma_chan *dma_chan,
253275

254276
desc->len = len;
255277

278+
if (pt->ver == AE4_DMA_VERSION) {
279+
ae4 = container_of(pt, struct ae4_device, pt);
280+
ae4cmd_q = &ae4->ae4cmd_q[chan->id];
281+
mutex_lock(&ae4cmd_q->cmd_lock);
282+
list_add_tail(&pt_cmd->entry, &ae4cmd_q->cmd);
283+
mutex_unlock(&ae4cmd_q->cmd_lock);
284+
}
285+
256286
return desc;
257287
}
258288

@@ -310,8 +340,11 @@ static enum dma_status
310340
pt_tx_status(struct dma_chan *c, dma_cookie_t cookie,
311341
struct dma_tx_state *txstate)
312342
{
313-
struct pt_device *pt = to_pt_chan(c)->pt;
314-
struct pt_cmd_queue *cmd_q = &pt->cmd_q;
343+
struct pt_dma_chan *chan = to_pt_chan(c);
344+
struct pt_device *pt = chan->pt;
345+
struct pt_cmd_queue *cmd_q;
346+
347+
cmd_q = pt_get_cmd_queue(pt, chan);
315348

316349
pt_check_status_trans(pt, cmd_q);
317350
return dma_cookie_status(c, cookie, txstate);
@@ -320,10 +353,13 @@ pt_tx_status(struct dma_chan *c, dma_cookie_t cookie,
320353
static int pt_pause(struct dma_chan *dma_chan)
321354
{
322355
struct pt_dma_chan *chan = to_pt_chan(dma_chan);
356+
struct pt_device *pt = chan->pt;
357+
struct pt_cmd_queue *cmd_q;
323358
unsigned long flags;
324359

325360
spin_lock_irqsave(&chan->vc.lock, flags);
326-
pt_stop_queue(&chan->pt->cmd_q);
361+
cmd_q = pt_get_cmd_queue(pt, chan);
362+
pt_stop_queue(cmd_q);
327363
spin_unlock_irqrestore(&chan->vc.lock, flags);
328364

329365
return 0;
@@ -333,10 +369,13 @@ static int pt_resume(struct dma_chan *dma_chan)
333369
{
334370
struct pt_dma_chan *chan = to_pt_chan(dma_chan);
335371
struct pt_dma_desc *desc = NULL;
372+
struct pt_device *pt = chan->pt;
373+
struct pt_cmd_queue *cmd_q;
336374
unsigned long flags;
337375

338376
spin_lock_irqsave(&chan->vc.lock, flags);
339-
pt_start_queue(&chan->pt->cmd_q);
377+
cmd_q = pt_get_cmd_queue(pt, chan);
378+
pt_start_queue(cmd_q);
340379
desc = pt_next_dma_desc(chan);
341380
spin_unlock_irqrestore(&chan->vc.lock, flags);
342381

@@ -350,11 +389,17 @@ static int pt_resume(struct dma_chan *dma_chan)
350389
static int pt_terminate_all(struct dma_chan *dma_chan)
351390
{
352391
struct pt_dma_chan *chan = to_pt_chan(dma_chan);
392+
struct pt_device *pt = chan->pt;
393+
struct pt_cmd_queue *cmd_q;
353394
unsigned long flags;
354-
struct pt_cmd_queue *cmd_q = &chan->pt->cmd_q;
355395
LIST_HEAD(head);
356396

357-
iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_control + 0x0010);
397+
cmd_q = pt_get_cmd_queue(pt, chan);
398+
if (pt->ver == AE4_DMA_VERSION)
399+
pt_stop_queue(cmd_q);
400+
else
401+
iowrite32(SUPPORTED_INTERRUPTS, cmd_q->reg_control + 0x0010);
402+
358403
spin_lock_irqsave(&chan->vc.lock, flags);
359404
vchan_get_all_descriptors(&chan->vc, &head);
360405
spin_unlock_irqrestore(&chan->vc.lock, flags);
@@ -367,14 +412,24 @@ static int pt_terminate_all(struct dma_chan *dma_chan)
367412

368413
int pt_dmaengine_register(struct pt_device *pt)
369414
{
370-
struct pt_dma_chan *chan;
371415
struct dma_device *dma_dev = &pt->dma_dev;
372-
char *cmd_cache_name;
416+
struct ae4_cmd_queue *ae4cmd_q = NULL;
417+
struct ae4_device *ae4 = NULL;
418+
struct pt_dma_chan *chan;
373419
char *desc_cache_name;
374-
int ret;
420+
char *cmd_cache_name;
421+
int ret, i;
422+
423+
if (pt->ver == AE4_DMA_VERSION)
424+
ae4 = container_of(pt, struct ae4_device, pt);
425+
426+
if (ae4)
427+
pt->pt_dma_chan = devm_kcalloc(pt->dev, ae4->cmd_q_count,
428+
sizeof(*pt->pt_dma_chan), GFP_KERNEL);
429+
else
430+
pt->pt_dma_chan = devm_kzalloc(pt->dev, sizeof(*pt->pt_dma_chan),
431+
GFP_KERNEL);
375432

376-
pt->pt_dma_chan = devm_kzalloc(pt->dev, sizeof(*pt->pt_dma_chan),
377-
GFP_KERNEL);
378433
if (!pt->pt_dma_chan)
379434
return -ENOMEM;
380435

@@ -416,9 +471,6 @@ int pt_dmaengine_register(struct pt_device *pt)
416471

417472
INIT_LIST_HEAD(&dma_dev->channels);
418473

419-
chan = pt->pt_dma_chan;
420-
chan->pt = pt;
421-
422474
/* Set base and prep routines */
423475
dma_dev->device_free_chan_resources = pt_free_chan_resources;
424476
dma_dev->device_prep_dma_memcpy = pt_prep_dma_memcpy;
@@ -430,8 +482,21 @@ int pt_dmaengine_register(struct pt_device *pt)
430482
dma_dev->device_terminate_all = pt_terminate_all;
431483
dma_dev->device_synchronize = pt_synchronize;
432484

433-
chan->vc.desc_free = pt_do_cleanup;
434-
vchan_init(&chan->vc, dma_dev);
485+
if (ae4) {
486+
for (i = 0; i < ae4->cmd_q_count; i++) {
487+
chan = pt->pt_dma_chan + i;
488+
ae4cmd_q = &ae4->ae4cmd_q[i];
489+
chan->id = ae4cmd_q->id;
490+
chan->pt = pt;
491+
chan->vc.desc_free = pt_do_cleanup;
492+
vchan_init(&chan->vc, dma_dev);
493+
}
494+
} else {
495+
chan = pt->pt_dma_chan;
496+
chan->pt = pt;
497+
chan->vc.desc_free = pt_do_cleanup;
498+
vchan_init(&chan->vc, dma_dev);
499+
}
435500

436501
ret = dma_async_device_register(dma_dev);
437502
if (ret)

drivers/dma/amd/ptdma/ptdma.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ struct pt_dma_desc {
184184
struct pt_dma_chan {
185185
struct virt_dma_chan vc;
186186
struct pt_device *pt;
187+
u32 id;
187188
};
188189

189190
struct pt_cmd_queue {
@@ -262,6 +263,7 @@ struct pt_device {
262263
unsigned long total_interrupts;
263264

264265
struct pt_tasklet_data tdata;
266+
int ver;
265267
};
266268

267269
/*

0 commit comments

Comments
 (0)