:p
atchew
Login
=== Trace === echo 1 >/sys/kernel/debug/tracing/tracing_on echo 1 >/sys/kernel/debug/tracing/events/fsl_edma/enable Run any dma test ... cat /sys/kernel/debug/tracing/trace uart_testapp_11-448 [000] d..1. 69.185019: edma_fill_tcd: ==== TCD ===== saddr: 0x831ee020 soff: 0x8000 attr: 0xffff nbytes: 0xfba40000 slast: 0x00000000 daddr: 0x8aaa4800 doff: 0x0001 citer: 0x0800 dlast: 0xfba40020 csr: 0x0052 biter: 0x0800 uart_testapp_11-448 [000] d..2. 69.185022: edma_writew: offset 0001803c: value 00000000 uart_testapp_11-448 [000] d..2. 69.185023: edma_writel: offset 00018020: value 4259001c uart_testapp_11-448 [000] d..2. 69.185024: edma_writel: offset 00018030: value 8aaa4000 === DebugFS === cat /sys/kernel/debug/dmaengine/42000000.dma-controller/42000000.dma-controller-CH00/ch_sbr 0x00208003 Frank Li (2): dmaengine: fsl-edma: add debugfs support dmaengine: fsl-edma: add trace event support drivers/dma/Makefile | 7 +- drivers/dma/fsl-edma-common.c | 2 + drivers/dma/fsl-edma-common.h | 37 ++++++++-- drivers/dma/fsl-edma-debugfs.c | 120 +++++++++++++++++++++++++++++++++ drivers/dma/fsl-edma-main.c | 2 + drivers/dma/fsl-edma-trace.c | 4 ++ drivers/dma/fsl-edma-trace.h | 113 +++++++++++++++++++++++++++++++ 7 files changed, 279 insertions(+), 6 deletions(-) create mode 100644 drivers/dma/fsl-edma-debugfs.c create mode 100644 drivers/dma/fsl-edma-trace.c create mode 100644 drivers/dma/fsl-edma-trace.h -- 2.34.1
Add debugfs support to fsl-edma to enable dumping of register states. Signed-off-by: Frank Li <Frank.Li@nxp.com> --- drivers/dma/Makefile | 5 +- drivers/dma/fsl-edma-common.h | 8 +++ drivers/dma/fsl-edma-debugfs.c | 120 +++++++++++++++++++++++++++++++++ drivers/dma/fsl-edma-main.c | 2 + 4 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 drivers/dma/fsl-edma-debugfs.c diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -XXX,XX +XXX,XX @@ 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-debugfs-$(CONFIG_DEBUG_FS) := fsl-edma-debugfs.o 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-debugfs-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-debugfs-y) obj-$(CONFIG_MCF_EDMA) += mcf-edma.o obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o obj-$(CONFIG_FSL_RAID) += fsl_raid.o diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -XXX,XX +XXX,XX @@ void fsl_edma_free_chan_resources(struct dma_chan *chan); void fsl_edma_cleanup_vchan(struct dma_device *dmadev); void fsl_edma_setup_regs(struct fsl_edma_engine *edma); +#ifdef CONFIG_DEBUG_FS +void fsl_edma_debugfs_on(struct fsl_edma_engine *edma); +#else +static inline void fsl_edma_debugfs_on(struct dw_edma *edma) +{ +} +#endif /* CONFIG_DEBUG_FS */ + #endif /* _FSL_EDMA_COMMON_H_ */ diff --git a/drivers/dma/fsl-edma-debugfs.c b/drivers/dma/fsl-edma-debugfs.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/drivers/dma/fsl-edma-debugfs.c @@ -XXX,XX +XXX,XX @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2023 NXP + +#include <linux/debugfs.h> +#include <linux/bitfield.h> + +#include "fsl-edma-common.h" + +#define fsl_edma_debugfs_reg(reg, dir, __name) \ +((sizeof(reg->__name) == sizeof(u32)) ? \ + debugfs_create_x32(__stringify(__name), 0644, dir, (u32 *)®->__name) : \ + debugfs_create_x16(__stringify(__name), 0644, dir, (u16 *)®->__name) \ +) + +#define fsl_edma_debugfs_regv1(reg, dir, __name) \ + debugfs_create_x32(__stringify(__name), 0644, dir, reg.__name) + +static void fsl_edma_debufs_tcdreg(struct fsl_edma_chan *chan, struct dentry *dir) +{ + fsl_edma_debugfs_reg(chan->tcd, dir, saddr); + fsl_edma_debugfs_reg(chan->tcd, dir, soff); + fsl_edma_debugfs_reg(chan->tcd, dir, attr); + fsl_edma_debugfs_reg(chan->tcd, dir, nbytes); + fsl_edma_debugfs_reg(chan->tcd, dir, slast); + fsl_edma_debugfs_reg(chan->tcd, dir, daddr); + fsl_edma_debugfs_reg(chan->tcd, dir, doff); + fsl_edma_debugfs_reg(chan->tcd, dir, citer); + fsl_edma_debugfs_reg(chan->tcd, dir, dlast_sga); + fsl_edma_debugfs_reg(chan->tcd, dir, csr); + fsl_edma_debugfs_reg(chan->tcd, dir, biter); +} + +static void fsl_edma3_debufs_chan(struct fsl_edma_chan *chan, struct dentry *entry) +{ + struct fsl_edma3_ch_reg *reg; + struct dentry *dir; + + reg = container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd); + fsl_edma_debugfs_reg(reg, entry, ch_csr); + fsl_edma_debugfs_reg(reg, entry, ch_int); + fsl_edma_debugfs_reg(reg, entry, ch_sbr); + fsl_edma_debugfs_reg(reg, entry, ch_pri); + fsl_edma_debugfs_reg(reg, entry, ch_mux); + fsl_edma_debugfs_reg(reg, entry, ch_mattr); + + dir = debugfs_create_dir("tcd_regs", entry); + + fsl_edma_debufs_tcdreg(chan, dir); +} + +static void fsl_edma3_debugfs_init(struct fsl_edma_engine *edma) +{ + struct fsl_edma_chan *chan; + struct dentry *dir; + int i; + + for (i = 0; i < edma->n_chans; i++) { + if (edma->chan_masked & BIT(i)) + continue; + + chan = &edma->chans[i]; + dir = debugfs_create_dir(chan->chan_name, edma->dma_dev.dbg_dev_root); + + fsl_edma3_debufs_chan(chan, dir); + } + +} + +static void fsl_edma_debugfs_init(struct fsl_edma_engine *edma) +{ + struct fsl_edma_chan *chan; + struct dentry *dir; + int i; + + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cr); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, es); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, erqh); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, erql); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, eeih); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, eeil); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, seei); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, ceei); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, serq); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cerq); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cint); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cerr); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, ssrt); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cdne); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, inth); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, errh); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, errl); + + for (i = 0; i < edma->n_chans; i++) { + if (edma->chan_masked & BIT(i)) + continue; + + chan = &edma->chans[i]; + dir = debugfs_create_dir(chan->chan_name, edma->dma_dev.dbg_dev_root); + + fsl_edma_debufs_tcdreg(chan, dir); + } +} + +void fsl_edma_debugfs_on(struct fsl_edma_engine *edma) +{ + if (!debugfs_initialized()) + return; + + debugfs_create_bool("big_endian", 0444, edma->dma_dev.dbg_dev_root, &edma->big_endian); + debugfs_create_x64("chan_mask", 0444, edma->dma_dev.dbg_dev_root, &edma->chan_masked); + debugfs_create_x32("n_chans", 0444, edma->dma_dev.dbg_dev_root, &edma->n_chans); + + if (edma->drvdata->flags & FSL_EDMA_DRV_SPLIT_REG) + fsl_edma3_debugfs_init(edma); + else + fsl_edma_debugfs_init(edma); +} + + diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-main.c +++ b/drivers/dma/fsl-edma-main.c @@ -XXX,XX +XXX,XX @@ static int fsl_edma_probe(struct platform_device *pdev) if (!(drvdata->flags & FSL_EDMA_DRV_SPLIT_REG)) edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA, regs->cr); + fsl_edma_debugfs_on(fsl_edma); + return 0; } -- 2.34.1
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> --- drivers/dma/Makefile | 6 +- drivers/dma/fsl-edma-common.c | 2 + drivers/dma/fsl-edma-common.h | 29 +++++++-- drivers/dma/fsl-edma-trace.c | 4 ++ drivers/dma/fsl-edma-trace.h | 113 ++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 drivers/dma/fsl-edma-trace.c create mode 100644 drivers/dma/fsl-edma-trace.h diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_DW_DMAC_CORE) += dw/ obj-$(CONFIG_DW_EDMA) += dw-edma/ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o fsl-edma-debugfs-$(CONFIG_DEBUG_FS) := fsl-edma-debugfs.o +CFLAGS_fsl-edma-trace.o := -I$(src) +fsl-edma-trace-$(CONFIG_TRACING) := fsl-edma-trace.o obj-$(CONFIG_FSL_DMA) += fsldma.o -fsl-edma-objs := fsl-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) +fsl-edma-objs := fsl-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) ${fsl-edma-trace-y} obj-$(CONFIG_FSL_EDMA) += fsl-edma.o -mcf-edma-objs := mcf-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) +mcf-edma-objs := mcf-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) ${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 diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -XXX,XX +XXX,XX @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan, csr |= EDMA_TCD_CSR_START; tcd->csr = cpu_to_le16(csr); + + trace_edma_fill_tcd(fsl_chan->edma, tcd); } static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -XXX,XX +XXX,XX @@ struct fsl_edma_engine { edma_writel(chan->edma, val, \ (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name)) +/* 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. @@ -XXX,XX +XXX,XX @@ struct fsl_edma_engine { */ 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, @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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 struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan) diff --git a/drivers/dma/fsl-edma-trace.c b/drivers/dma/fsl-edma-trace.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/drivers/dma/fsl-edma-trace.c @@ -XXX,XX +XXX,XX @@ +// 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 index XXXXXXX..XXXXXXX --- /dev/null +++ b/drivers/dma/fsl-edma-trace.h @@ -XXX,XX +XXX,XX @@ +/* 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 %08lx: value %08x", + __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_engine *edma, struct fsl_edma_hw_tcd *tcd), + TP_ARGS(edma, tcd), + TP_STRUCT__entry( + __field(struct fsl_edma_engine *, edma) + __field(struct fsl_edma_hw_tcd *, tcd) + ), + TP_fast_assign( + __entry->edma = edma; + __entry->tcd = tcd; + ), + TP_printk("\n==== TCD =====\n" + " saddr: 0x%08x\n" + " soff: 0x%04x\n" + " attr: 0x%04x\n" + " nbytes: 0x%08x\n" + " slast: 0x%08x\n" + " daddr: 0x%08x\n" + " doff: 0x%04x\n" + " citer: 0x%04x\n" + " dlast: 0x%08x\n" + " csr: 0x%04x\n" + " biter: 0x%04x\n", + __entry->tcd->saddr, + __entry->tcd->soff, + __entry->tcd->attr, + __entry->tcd->nbytes, + __entry->tcd->slast, + __entry->tcd->daddr, + __entry->tcd->doff, + __entry->tcd->citer, + __entry->tcd->dlast_sga, + __entry->tcd->csr, + __entry->tcd->biter) +); + +DEFINE_EVENT(edma_log_tcd, edma_fill_tcd, + TP_PROTO(struct fsl_edma_engine *edma, struct fsl_edma_hw_tcd *tcd), + TP_ARGS(edma, 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> -- 2.34.1
Change from v1 to v2 Fixed tcd trace issue, data need be saved firstly. === Trace === echo 1 >/sys/kernel/debug/tracing/tracing_on echo 1 >/sys/kernel/debug/tracing/events/fsl_edma/enable Run any dma test ... cat /sys/kernel/debug/tracing/trace uart_testapp_11-448 [000] d..1. 69.185019: edma_fill_tcd: ==== TCD ===== saddr: 0x831ee020 soff: 0x8000 attr: 0xffff nbytes: 0xfba40000 slast: 0x00000000 daddr: 0x8aaa4800 doff: 0x0001 citer: 0x0800 dlast: 0xfba40020 csr: 0x0052 biter: 0x0800 uart_testapp_11-448 [000] d..2. 69.185022: edma_writew: offset 0001803c: value 00000000 uart_testapp_11-448 [000] d..2. 69.185023: edma_writel: offset 00018020: value 4259001c uart_testapp_11-448 [000] d..2. 69.185024: edma_writel: offset 00018030: value 8aaa4000 === DebugFS === cat /sys/kernel/debug/dmaengine/42000000.dma-controller/42000000.dma-controller-CH00/ch_sbr 0x00208003 Frank Li (2): dmaengine: fsl-emda: add debugfs support dmaengine: fsl-edma: add trace event support drivers/dma/Makefile | 7 +- drivers/dma/fsl-edma-common.c | 2 + drivers/dma/fsl-edma-common.h | 37 ++++++++- drivers/dma/fsl-edma-debugfs.c | 116 ++++++++++++++++++++++++++++ drivers/dma/fsl-edma-main.c | 2 + drivers/dma/fsl-edma-trace.c | 4 + drivers/dma/fsl-edma-trace.h | 134 +++++++++++++++++++++++++++++++++ 7 files changed, 296 insertions(+), 6 deletions(-) create mode 100644 drivers/dma/fsl-edma-debugfs.c create mode 100644 drivers/dma/fsl-edma-trace.c create mode 100644 drivers/dma/fsl-edma-trace.h -- 2.34.1
Add debugfs support to fsl-edma to enable dumping of register states. Signed-off-by: Frank Li <Frank.Li@nxp.com> --- drivers/dma/Makefile | 5 +- drivers/dma/fsl-edma-common.h | 8 +++ drivers/dma/fsl-edma-debugfs.c | 116 +++++++++++++++++++++++++++++++++ drivers/dma/fsl-edma-main.c | 2 + 4 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 drivers/dma/fsl-edma-debugfs.c diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -XXX,XX +XXX,XX @@ 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-debugfs-$(CONFIG_DEBUG_FS) := fsl-edma-debugfs.o 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-debugfs-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-debugfs-y) obj-$(CONFIG_MCF_EDMA) += mcf-edma.o obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o obj-$(CONFIG_FSL_RAID) += fsl_raid.o diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -XXX,XX +XXX,XX @@ void fsl_edma_free_chan_resources(struct dma_chan *chan); void fsl_edma_cleanup_vchan(struct dma_device *dmadev); void fsl_edma_setup_regs(struct fsl_edma_engine *edma); +#ifdef CONFIG_DEBUG_FS +void fsl_edma_debugfs_on(struct fsl_edma_engine *edma); +#else +static inline void fsl_edma_debugfs_on(struct dw_edma *edma) +{ +} +#endif /* CONFIG_DEBUG_FS */ + #endif /* _FSL_EDMA_COMMON_H_ */ diff --git a/drivers/dma/fsl-edma-debugfs.c b/drivers/dma/fsl-edma-debugfs.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/drivers/dma/fsl-edma-debugfs.c @@ -XXX,XX +XXX,XX @@ +#include <linux/debugfs.h> +#include <linux/bitfield.h> + +#include "fsl-edma-common.h" + +#define fsl_edma_debugfs_reg(reg, dir, __name) \ +((sizeof(reg->__name) == sizeof(u32)) ? \ + debugfs_create_x32(__stringify(__name), 0644, dir, (u32 *)®->__name) : \ + debugfs_create_x16(__stringify(__name), 0644, dir, (u16 *)®->__name) \ +) + +#define fsl_edma_debugfs_regv1(reg, dir, __name) \ + debugfs_create_x32(__stringify(__name), 0644, dir, reg.__name) + +static void fsl_edma_debufs_tcdreg(struct fsl_edma_chan *chan, struct dentry *dir) +{ + fsl_edma_debugfs_reg(chan->tcd, dir, saddr); + fsl_edma_debugfs_reg(chan->tcd, dir, soff); + fsl_edma_debugfs_reg(chan->tcd, dir, attr); + fsl_edma_debugfs_reg(chan->tcd, dir, nbytes); + fsl_edma_debugfs_reg(chan->tcd, dir, slast); + fsl_edma_debugfs_reg(chan->tcd, dir, daddr); + fsl_edma_debugfs_reg(chan->tcd, dir, doff); + fsl_edma_debugfs_reg(chan->tcd, dir, citer); + fsl_edma_debugfs_reg(chan->tcd, dir, dlast_sga); + fsl_edma_debugfs_reg(chan->tcd, dir, csr); + fsl_edma_debugfs_reg(chan->tcd, dir, biter); +} + +static void fsl_edma3_debufs_chan(struct fsl_edma_chan *chan, struct dentry *entry) +{ + struct fsl_edma3_ch_reg *reg; + struct dentry *dir; + + reg = container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd); + fsl_edma_debugfs_reg(reg, entry, ch_csr); + fsl_edma_debugfs_reg(reg, entry, ch_int); + fsl_edma_debugfs_reg(reg, entry, ch_sbr); + fsl_edma_debugfs_reg(reg, entry, ch_pri); + fsl_edma_debugfs_reg(reg, entry, ch_mux); + fsl_edma_debugfs_reg(reg, entry, ch_mattr); + + dir = debugfs_create_dir("tcd_regs", entry); + + fsl_edma_debufs_tcdreg(chan, dir); +} + +static void fsl_edma3_debugfs_init(struct fsl_edma_engine *edma) +{ + struct fsl_edma_chan *chan; + struct dentry *dir; + int i; + + for (i = 0; i < edma->n_chans; i++) { + if (edma->chan_masked & BIT(i)) + continue; + + chan = &edma->chans[i]; + dir = debugfs_create_dir(chan->chan_name, edma->dma_dev.dbg_dev_root); + + fsl_edma3_debufs_chan(chan, dir); + } + +} + +static void fsl_edma_debugfs_init(struct fsl_edma_engine *edma) +{ + struct fsl_edma_chan *chan; + struct dentry *dir; + int i; + + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cr); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, es); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, erqh); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, erql); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, eeih); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, eeil); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, seei); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, ceei); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, serq); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cerq); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cint); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cerr); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, ssrt); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, cdne); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, inth); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, errh); + fsl_edma_debugfs_regv1(edma->regs, edma->dma_dev.dbg_dev_root, errl); + + for (i = 0; i < edma->n_chans; i++) { + if (edma->chan_masked & BIT(i)) + continue; + + chan = &edma->chans[i]; + dir = debugfs_create_dir(chan->chan_name, edma->dma_dev.dbg_dev_root); + + fsl_edma_debufs_tcdreg(chan, dir); + } +} + +void fsl_edma_debugfs_on(struct fsl_edma_engine *edma) +{ + if (!debugfs_initialized()) + return; + + debugfs_create_bool("big_endian", 0444, edma->dma_dev.dbg_dev_root, &edma->big_endian); + debugfs_create_x64("chan_mask", 0444, edma->dma_dev.dbg_dev_root, &edma->chan_masked); + debugfs_create_x32("n_chans", 0444, edma->dma_dev.dbg_dev_root, &edma->n_chans); + + if (edma->drvdata->flags & FSL_EDMA_DRV_SPLIT_REG) + fsl_edma3_debugfs_init(edma); + else + fsl_edma_debugfs_init(edma); +} + + diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-main.c +++ b/drivers/dma/fsl-edma-main.c @@ -XXX,XX +XXX,XX @@ static int fsl_edma_probe(struct platform_device *pdev) if (!(drvdata->flags & FSL_EDMA_DRV_SPLIT_REG)) edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA, regs->cr); + fsl_edma_debugfs_on(fsl_edma); + return 0; } -- 2.34.1
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> --- drivers/dma/Makefile | 6 +- drivers/dma/fsl-edma-common.c | 2 + drivers/dma/fsl-edma-common.h | 29 +++++++- drivers/dma/fsl-edma-trace.c | 4 + drivers/dma/fsl-edma-trace.h | 134 ++++++++++++++++++++++++++++++++++ 5 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 drivers/dma/fsl-edma-trace.c create mode 100644 drivers/dma/fsl-edma-trace.h diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_DW_DMAC_CORE) += dw/ obj-$(CONFIG_DW_EDMA) += dw-edma/ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o fsl-edma-debugfs-$(CONFIG_DEBUG_FS) := fsl-edma-debugfs.o +CFLAGS_fsl-edma-trace.o := -I$(src) +fsl-edma-trace-$(CONFIG_TRACING) := fsl-edma-trace.o obj-$(CONFIG_FSL_DMA) += fsldma.o -fsl-edma-objs := fsl-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) +fsl-edma-objs := fsl-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) ${fsl-edma-trace-y} obj-$(CONFIG_FSL_EDMA) += fsl-edma.o -mcf-edma-objs := mcf-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) +mcf-edma-objs := mcf-edma-main.o fsl-edma-common.o $(fsl-edma-debugfs-y) ${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 diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -XXX,XX +XXX,XX @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan, csr |= EDMA_TCD_CSR_START; tcd->csr = cpu_to_le16(csr); + + trace_edma_fill_tcd(fsl_chan->edma, tcd); } static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index XXXXXXX..XXXXXXX 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -XXX,XX +XXX,XX @@ struct fsl_edma_engine { edma_writel(chan->edma, val, \ (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name)) +/* 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. @@ -XXX,XX +XXX,XX @@ struct fsl_edma_engine { */ 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, @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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 struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan) diff --git a/drivers/dma/fsl-edma-trace.c b/drivers/dma/fsl-edma-trace.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/drivers/dma/fsl-edma-trace.c @@ -XXX,XX +XXX,XX @@ +// 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 index XXXXXXX..XXXXXXX --- /dev/null +++ b/drivers/dma/fsl-edma-trace.h @@ -XXX,XX +XXX,XX @@ +/* 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 %08lx: value %08x", + __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_engine *edma, struct fsl_edma_hw_tcd *tcd), + TP_ARGS(edma, tcd), + TP_STRUCT__entry( + __field(struct fsl_edma_engine *, edma) + __field(u32, saddr) + __field(u16, soff) + __field(u16, attr) + __field(u32, nbytes) + __field(u32, slast) + __field(u32, daddr) + __field(u16, doff) + __field(u16, citer) + __field(u32, dlast_sga) + __field(u16, csr) + __field(u16, biter) + + ), + TP_fast_assign( + __entry->edma = edma; + __entry->saddr = tcd->saddr, + __entry->soff = tcd->soff, + __entry->attr = tcd->attr, + __entry->nbytes = tcd->nbytes, + __entry->slast = tcd->slast, + __entry->daddr = tcd->daddr, + __entry->doff = tcd->doff, + __entry->citer = tcd->citer, + __entry->dlast_sga = tcd->dlast_sga, + __entry->csr = tcd->csr, + __entry->biter = tcd->biter; + ), + TP_printk("\n==== TCD =====\n" + " saddr: 0x%08x\n" + " soff: 0x%04x\n" + " attr: 0x%04x\n" + " nbytes: 0x%08x\n" + " slast: 0x%08x\n" + " daddr: 0x%08x\n" + " doff: 0x%04x\n" + " citer: 0x%04x\n" + " dlast: 0x%08x\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_engine *edma, struct fsl_edma_hw_tcd *tcd), + TP_ARGS(edma, 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> -- 2.34.1