dmaengine: fsl-edma: add trace event support
authorFrank Li <Frank.Li@nxp.com>
Thu, 25 Apr 2024 20:59:45 +0000 (16:59 -0400)
committerVinod Koul <vkoul@kernel.org>
Sat, 4 May 2024 12:30:16 +0000 (18:00 +0530)
Implement trace event support to enhance logging functionality for
register access and the transfer control descriptor (TCD) context.
This will enable more comprehensive monitoring and analysis of system
activities

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240425205947.3436501-1-Frank.Li@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/Makefile
drivers/dma/fsl-edma-common.c
drivers/dma/fsl-edma-common.h
drivers/dma/fsl-edma-trace.c [new file with mode: 0644]
drivers/dma/fsl-edma-trace.h [new file with mode: 0644]

index dfd40d14e4089d81ce489429f141a896bfc549e7..802ca916f05f509f9e7645a8c6c8b5f43ae80325 100644 (file)
@@ -31,10 +31,12 @@ obj-$(CONFIG_DW_AXI_DMAC) += dw-axi-dmac/
 obj-$(CONFIG_DW_DMAC_CORE) += dw/
 obj-$(CONFIG_DW_EDMA) += dw-edma/
 obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
+fsl-edma-trace-$(CONFIG_TRACING) := fsl-edma-trace.o
+CFLAGS_fsl-edma-trace.o := -I$(src)
 obj-$(CONFIG_FSL_DMA) += fsldma.o
-fsl-edma-objs := fsl-edma-main.o fsl-edma-common.o
+fsl-edma-objs := fsl-edma-main.o fsl-edma-common.o ${fsl-edma-trace-y}
 obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
-mcf-edma-objs := mcf-edma-main.o fsl-edma-common.o
+mcf-edma-objs := mcf-edma-main.o fsl-edma-common.o ${fsl-edma-trace-y}
 obj-$(CONFIG_MCF_EDMA) += mcf-edma.o
 obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o
 obj-$(CONFIG_FSL_RAID) += fsl_raid.o
index d62f5f452a4304c30937426a611a3d8b0f1754be..3af4307873157e6cfbf44009e56f83645911b412 100644 (file)
@@ -540,6 +540,8 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
                csr |= EDMA_TCD_CSR_START;
 
        fsl_edma_set_tcd_to_le(fsl_chan, tcd, csr, csr);
+
+       trace_edma_fill_tcd(fsl_chan, tcd);
 }
 
 static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,
index 3f93ebb890b359b991a10b526db08a3cc282b0b1..010ea6940c1c942b39a1d4a4d77e81d669a9a6d9 100644 (file)
@@ -246,6 +246,11 @@ struct fsl_edma_engine {
        struct fsl_edma_chan    chans[] __counted_by(n_chans);
 };
 
+static inline u32 fsl_edma_drvflags(struct fsl_edma_chan *fsl_chan)
+{
+       return fsl_chan->edma->drvdata->flags;
+}
+
 #define edma_read_tcdreg_c(chan, _tcd,  __name)                                \
 (sizeof((_tcd)->__name) == sizeof(u64) ?                               \
        edma_readq(chan->edma, &(_tcd)->__name) :                       \
@@ -349,6 +354,9 @@ do {                                                                \
                fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd *)_tcd, _val, _field);         \
 } while (0)
 
+/* Need after struct defination */
+#include "fsl-edma-trace.h"
+
 /*
  * R/W functions for big- or little-endian registers:
  * The eDMA controller's endian is independent of the CPU core's endian.
@@ -367,23 +375,38 @@ static inline u64 edma_readq(struct fsl_edma_engine *edma, void __iomem *addr)
                h = ioread32(addr + 4);
        }
 
+       trace_edma_readl(edma, addr, l);
+       trace_edma_readl(edma, addr + 4, h);
+
        return (h << 32) | l;
 }
 
 static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
 {
+       u32 val;
+
        if (edma->big_endian)
-               return ioread32be(addr);
+               val = ioread32be(addr);
        else
-               return ioread32(addr);
+               val = ioread32(addr);
+
+       trace_edma_readl(edma, addr, val);
+
+       return val;
 }
 
 static inline u16 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr)
 {
+       u16 val;
+
        if (edma->big_endian)
-               return ioread16be(addr);
+               val = ioread16be(addr);
        else
-               return ioread16(addr);
+               val = ioread16(addr);
+
+       trace_edma_readw(edma, addr, val);
+
+       return val;
 }
 
 static inline void edma_writeb(struct fsl_edma_engine *edma,
@@ -394,6 +417,8 @@ static inline void edma_writeb(struct fsl_edma_engine *edma,
                iowrite8(val, (void __iomem *)((unsigned long)addr ^ 0x3));
        else
                iowrite8(val, addr);
+
+       trace_edma_writeb(edma, addr, val);
 }
 
 static inline void edma_writew(struct fsl_edma_engine *edma,
@@ -404,6 +429,8 @@ static inline void edma_writew(struct fsl_edma_engine *edma,
                iowrite16be(val, (void __iomem *)((unsigned long)addr ^ 0x2));
        else
                iowrite16(val, addr);
+
+       trace_edma_writew(edma, addr, val);
 }
 
 static inline void edma_writel(struct fsl_edma_engine *edma,
@@ -413,6 +440,8 @@ static inline void edma_writel(struct fsl_edma_engine *edma,
                iowrite32be(val, addr);
        else
                iowrite32(val, addr);
+
+       trace_edma_writel(edma, addr, val);
 }
 
 static inline void edma_writeq(struct fsl_edma_engine *edma,
@@ -425,6 +454,9 @@ static inline void edma_writeq(struct fsl_edma_engine *edma,
                iowrite32(val & 0xFFFFFFFF, addr);
                iowrite32(val >> 32, addr + 4);
        }
+
+       trace_edma_writel(edma, addr, val & 0xFFFFFFFF);
+       trace_edma_writel(edma, addr + 4, val >> 32);
 }
 
 static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
@@ -432,11 +464,6 @@ static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
        return container_of(chan, struct fsl_edma_chan, vchan.chan);
 }
 
-static inline u32 fsl_edma_drvflags(struct fsl_edma_chan *fsl_chan)
-{
-       return fsl_chan->edma->drvdata->flags;
-}
-
 static inline struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd)
 {
        return container_of(vd, struct fsl_edma_desc, vdesc);
diff --git a/drivers/dma/fsl-edma-trace.c b/drivers/dma/fsl-edma-trace.c
new file mode 100644 (file)
index 0000000..28300ad
--- /dev/null
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define CREATE_TRACE_POINTS
+#include "fsl-edma-common.h"
diff --git a/drivers/dma/fsl-edma-trace.h b/drivers/dma/fsl-edma-trace.h
new file mode 100644 (file)
index 0000000..d354130
--- /dev/null
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2023 NXP.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM fsl_edma
+
+#if !defined(__LINUX_FSL_EDMA_TRACE) || defined(TRACE_HEADER_MULTI_READ)
+#define __LINUX_FSL_EDMA_TRACE
+
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(edma_log_io,
+       TP_PROTO(struct fsl_edma_engine *edma, void __iomem *addr, u32 value),
+       TP_ARGS(edma, addr, value),
+       TP_STRUCT__entry(
+               __field(struct fsl_edma_engine *, edma)
+               __field(void __iomem *, addr)
+               __field(u32, value)
+       ),
+       TP_fast_assign(
+               __entry->edma = edma;
+               __entry->addr = addr;
+               __entry->value = value;
+       ),
+       TP_printk("offset %08x: value %08x",
+               (u32)(__entry->addr - __entry->edma->membase), __entry->value)
+);
+
+DEFINE_EVENT(edma_log_io, edma_readl,
+       TP_PROTO(struct fsl_edma_engine *edma, void __iomem *addr, u32 value),
+       TP_ARGS(edma, addr, value)
+);
+
+DEFINE_EVENT(edma_log_io, edma_writel,
+       TP_PROTO(struct fsl_edma_engine *edma, void __iomem *addr,  u32 value),
+       TP_ARGS(edma, addr, value)
+);
+
+DEFINE_EVENT(edma_log_io, edma_readw,
+       TP_PROTO(struct fsl_edma_engine *edma, void __iomem *addr, u32 value),
+       TP_ARGS(edma, addr, value)
+);
+
+DEFINE_EVENT(edma_log_io, edma_writew,
+       TP_PROTO(struct fsl_edma_engine *edma, void __iomem *addr,  u32 value),
+       TP_ARGS(edma, addr, value)
+);
+
+DEFINE_EVENT(edma_log_io, edma_readb,
+       TP_PROTO(struct fsl_edma_engine *edma, void __iomem *addr, u32 value),
+       TP_ARGS(edma, addr, value)
+);
+
+DEFINE_EVENT(edma_log_io, edma_writeb,
+       TP_PROTO(struct fsl_edma_engine *edma, void __iomem *addr,  u32 value),
+       TP_ARGS(edma, addr, value)
+);
+
+DECLARE_EVENT_CLASS(edma_log_tcd,
+       TP_PROTO(struct fsl_edma_chan *chan, void *tcd),
+       TP_ARGS(chan, tcd),
+       TP_STRUCT__entry(
+               __field(u64, saddr)
+               __field(u16, soff)
+               __field(u16, attr)
+               __field(u32, nbytes)
+               __field(u64, slast)
+               __field(u64, daddr)
+               __field(u16, doff)
+               __field(u16, citer)
+               __field(u64, dlast_sga)
+               __field(u16, csr)
+               __field(u16, biter)
+
+       ),
+       TP_fast_assign(
+               __entry->saddr = fsl_edma_get_tcd_to_cpu(chan, tcd, saddr),
+               __entry->soff = fsl_edma_get_tcd_to_cpu(chan, tcd, soff),
+               __entry->attr = fsl_edma_get_tcd_to_cpu(chan, tcd, attr),
+               __entry->nbytes = fsl_edma_get_tcd_to_cpu(chan, tcd, nbytes),
+               __entry->slast = fsl_edma_get_tcd_to_cpu(chan, tcd, slast),
+               __entry->daddr = fsl_edma_get_tcd_to_cpu(chan, tcd, daddr),
+               __entry->doff = fsl_edma_get_tcd_to_cpu(chan, tcd, doff),
+               __entry->citer = fsl_edma_get_tcd_to_cpu(chan, tcd, citer),
+               __entry->dlast_sga = fsl_edma_get_tcd_to_cpu(chan, tcd, dlast_sga),
+               __entry->csr = fsl_edma_get_tcd_to_cpu(chan, tcd, csr),
+               __entry->biter = fsl_edma_get_tcd_to_cpu(chan, tcd, biter);
+       ),
+       TP_printk("\n==== TCD =====\n"
+                 "  saddr:  0x%016llx\n"
+                 "  soff:               0x%04x\n"
+                 "  attr:               0x%04x\n"
+                 "  nbytes:         0x%08x\n"
+                 "  slast:  0x%016llx\n"
+                 "  daddr:  0x%016llx\n"
+                 "  doff:               0x%04x\n"
+                 "  citer:              0x%04x\n"
+                 "  dlast:  0x%016llx\n"
+                 "  csr:                0x%04x\n"
+                 "  biter:              0x%04x\n",
+               __entry->saddr,
+               __entry->soff,
+               __entry->attr,
+               __entry->nbytes,
+               __entry->slast,
+               __entry->daddr,
+               __entry->doff,
+               __entry->citer,
+               __entry->dlast_sga,
+               __entry->csr,
+               __entry->biter)
+);
+
+DEFINE_EVENT(edma_log_tcd, edma_fill_tcd,
+       TP_PROTO(struct fsl_edma_chan *chan, void *tcd),
+       TP_ARGS(chan, tcd)
+);
+
+#endif
+
+/* this part must be outside header guard */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE fsl-edma-trace
+
+#include <trace/define_trace.h>