Adds an sdhci-trace object file that is linked with the sdhci module.
This will allow sdhci-core to call the trace functions.

There weren't constants defined for some of the fields, so I just used
the raw values.

See the next change for usage.

Signed-off-by: Raul E Rangel <rran...@chromium.org>
---

 drivers/mmc/host/Makefile      |   5 +-
 drivers/mmc/host/sdhci-trace.c | 319 +++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci-trace.h |  93 ++++++++++
 3 files changed, 416 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/host/sdhci-trace.c
 create mode 100644 drivers/mmc/host/sdhci-trace.h

diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 11174945c116..1cb695a3b359 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -3,6 +3,9 @@
 # Makefile for MMC/SD host controller drivers
 #
 
+# tell define_trace.h where to find the sdhci trace header
+CFLAGS_sdhci-trace.o := -I$(src)
+
 obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o
 armmmci-y := mmci.o
 armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o
@@ -11,7 +14,7 @@ obj-$(CONFIG_MMC_PXA)         += pxamci.o
 obj-$(CONFIG_MMC_MXC)          += mxcmmc.o
 obj-$(CONFIG_MMC_MXS)          += mxs-mmc.o
 obj-$(CONFIG_MMC_SDHCI)                += sdhci.o
-sdhci-objs                     += sdhci-core.o
+sdhci-objs                     += sdhci-core.o sdhci-trace.o
 obj-$(CONFIG_MMC_SDHCI_PCI)    += sdhci-pci.o
 sdhci-pci-y                    += sdhci-pci-core.o sdhci-pci-o2micro.o 
sdhci-pci-arasan.o \
                                   sdhci-pci-dwc-mshc.o
diff --git a/drivers/mmc/host/sdhci-trace.c b/drivers/mmc/host/sdhci-trace.c
new file mode 100644
index 000000000000..a7d803470664
--- /dev/null
+++ b/drivers/mmc/host/sdhci-trace.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2019 Google LLC.
+
+#include <linux/trace_events.h>
+#include "sdhci.h"
+
+#define SDHCI_REGS \
+       {SDHCI_DMA_ADDRESS, "DMA_ADDRESS"}, \
+       {SDHCI_BLOCK_SIZE, "BLOCK_SIZE"}, \
+       {SDHCI_ARGUMENT, "ARGUMENT"}, \
+       {SDHCI_TRANSFER_MODE, "TRANSFER_MODE"}, \
+       {SDHCI_RESPONSE, "RESP10"}, \
+       {SDHCI_RESPONSE + 4, "RESP32"}, \
+       {SDHCI_RESPONSE + 8, "RESP54"}, \
+       {SDHCI_RESPONSE + 12, "RESP76"}, \
+       {SDHCI_BUFFER, "BUFFER"}, \
+       {SDHCI_PRESENT_STATE, "PRESENT_STATE"}, \
+       {SDHCI_HOST_CONTROL, "HOST_CONTROL"}, \
+       {SDHCI_CLOCK_CONTROL, "CLOCK_CONTROL"}, \
+       {SDHCI_INT_STATUS, "INT_STATUS"}, \
+       {SDHCI_INT_ENABLE, "INT_ENABLE"}, \
+       {SDHCI_SIGNAL_ENABLE, "SIGNAL_ENABLE"}, \
+       {SDHCI_ACMD12_ERR, "ACMD12_ERR"}, \
+       {SDHCI_CAPABILITIES, "CAPABILITIES"}, \
+       {SDHCI_CAPABILITIES_1, "CAPABILITIES_1"}, \
+       {SDHCI_MAX_CURRENT, "MAX_CURRENT"}, \
+       {SDHCI_SET_ACMD12_ERROR, "SET_ACMD12_ERROR"}, \
+       {SDHCI_ADMA_ERROR, "ADMA_ERROR"}, \
+       {SDHCI_ADMA_ADDRESS, "ADMA_ADDRESS"}, \
+       {SDHCI_ADMA_ADDRESS_HI, "ADMA_ADDRESS_HI"}, \
+       {SDHCI_SLOT_INT_STATUS, "SLOT_INT_STATUS"}
+
+static const struct trace_print_flags const int_flags[] = {
+       {SDHCI_INT_RESPONSE, "RESPONSE"},
+       {SDHCI_INT_DATA_END, "DATA_END"},
+       {SDHCI_INT_BLK_GAP, "BLK_GAP"},
+       {SDHCI_INT_DMA_END, "DMA_END"},
+       {SDHCI_INT_SPACE_AVAIL, "SPACE_AVAIL"},
+       {SDHCI_INT_DATA_AVAIL, "DATA_AVAIL"},
+       {SDHCI_INT_CARD_INSERT, "CARD_INSERT"},
+       {SDHCI_INT_CARD_REMOVE, "CARD_REMOVE"},
+       {SDHCI_INT_CARD_INT, "CARD_INT"},
+       {SDHCI_INT_RETUNE, "RETUNE"},
+       {SDHCI_INT_CQE, "CQE"},
+       {SDHCI_INT_ERROR, "ERROR"},
+       {SDHCI_INT_TIMEOUT, "TIMEOUT"},
+       {SDHCI_INT_CRC, "CRC"},
+       {SDHCI_INT_END_BIT, "END_BIT"},
+       {SDHCI_INT_INDEX, "INDEX"},
+       {SDHCI_INT_DATA_TIMEOUT, "DATA_TIMEOUT"},
+       {SDHCI_INT_DATA_CRC, "DATA_CRC"},
+       {SDHCI_INT_DATA_END_BIT, "DATA_END_BIT"},
+       {SDHCI_INT_BUS_POWER, "BUS_POWER"},
+       {SDHCI_INT_ACMD12ERR, "ACMD12ERR"},
+       {SDHCI_INT_ADMA_ERROR, "ADMA_ERROR"},
+       { -1, NULL }
+};
+
+static const struct trace_print_flags const present_state_flags[] = {
+       {SDHCI_CMD_INHIBIT, "CMD_INHIBIT"},
+       {SDHCI_DATA_INHIBIT, "DATA_INHIBIT"},
+       {1<<2, "DAT_LINE_ACTIVE"},
+       {SDHCI_DOING_WRITE, "DOING_WRITE"},
+       {SDHCI_DOING_READ, "DOING_READ"},
+       {SDHCI_SPACE_AVAILABLE, "SPACE_AVAILABLE"},
+       {SDHCI_DATA_AVAILABLE, "DATA_AVAILABLE"},
+       {SDHCI_CARD_PRESENT, "CARD_PRESENT"},
+       {1<<17, "CARD_STABLE"},
+       {1<<18, "CD_HIGH"},
+       {SDHCI_WRITE_PROTECT, "WRITE_PROTECT"},
+       {1<<20, "DATA0"},
+       {1<<21, "DATA1"},
+       {1<<22, "DATA2"},
+       {1<<23, "DATA3"},
+       {SDHCI_CMD_LVL, "CMD_LVL"},
+       { -1, NULL }
+};
+
+static const struct trace_print_field block_cnt_reg[] = {
+       {
+               .mask = 0xFFF,
+               .name = "BLOCK_SIZE"
+       },
+       {
+               .mask = 7 << 12,
+               .name = "DMA_BUF_BOUNDARY",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "4K"},
+                       {1, "8K"},
+                       {2, "16K"},
+                       {3, "32K"},
+                       {4, "64K"},
+                       {5, "128K"},
+                       {6, "256K"},
+                       {7, "512K"},
+                       {}
+               }
+       },
+       {
+               .mask = 0xFFFF << 16,
+               .name = "BLOCK_CNT"
+       },
+};
+
+static const struct trace_print_field host_control_reg[] = {
+       {
+               .mask = SDHCI_CTRL_LED,
+               .name = "LED",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "OFF"},
+                       {1, "ON"},
+                       {}
+               }
+       }, {
+               .mask = SDHCI_CTRL_4BITBUS,
+               .name = "TX_WIDTH",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "1-BIT"},
+                       {1, "4-BIT"},
+                       {}
+               }
+       }, {
+               .mask = SDHCI_CTRL_HISPD,
+               .name = "HIGH_SPEED"
+       }, {
+               .mask = SDHCI_CTRL_DMA_MASK,
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "SDMA"},
+                       {1, "ADMA-32"},
+                       {2, "ADMA2-32"},
+                       {3, "ADMA2-64"},
+                       {}
+               }
+       }, {
+               .mask = SDHCI_CTRL_8BITBUS,
+               .name = "MMC_WIDTH",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "DAT_WIDTH"},
+                       {1, "8-BIT"},
+                       {}
+               }
+       },
+       {SDHCI_CTRL_CDTEST_INS, "CDTEST_INS"},
+       {SDHCI_CTRL_CDTEST_EN, "CDTEST_EN"},
+       {1<<8, "BUS_POWER"},
+       {
+               .mask = 0x7 << 9,
+               .name = "BUS_VOLTAGE",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0x00, "0.0V"},
+                       {0x05, "1.8V"},
+                       {0x06, "3.0V"},
+                       {0x07, "3.3V"},
+                       {}
+               }
+       },
+       {1<<16, "BLOCK_GAP_STOP"},
+       {1<<17, "CONT_REQ"},
+       {1<<18, "READ_WAIT_EN"},
+       {1<<19, "BLOCK_GAP_INT_EN"},
+       {1<<24, "INT_WAKE_EN"},
+       {1<<25, "INS_WAKE_EN"},
+       {1<<26, "REM_WAKE_EN"},
+       {},
+};
+
+static const struct trace_print_field transfer_mode_reg[] = {
+       {SDHCI_TRNS_DMA, "DMA_EN"},
+       {SDHCI_TRNS_BLK_CNT_EN, "BLK_CNT_EN"},
+       {
+               .mask = 0xC,
+               .name = "AUTO_CMD",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "DISABLED"},
+                       {1, "12"},
+                       {2, "23"},
+                       {3, "RESERVED"},
+                       {}
+               }
+       }, {
+               .mask = SDHCI_TRNS_READ,
+               .name = "DATA_DIR",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "WRITE"},
+                       {1, "READ"},
+                       {}
+               }
+       },
+       {SDHCI_TRNS_MULTI, "MULTI_BLK"},
+       {
+               .mask = 0x3 << 16,
+               .name = "RESP_TYPE",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "NONE"},
+                       {1, "136-BITS"},
+                       {2, "48-BITS"},
+                       {3, "48-BITS W/ BUSY"},
+                       {}
+               }
+       },
+       {1<<19, "CRC_CHECK_EN"},
+       {1<<20, "CMD_IDX_CHECK_EN"},
+       {1<<21, "DATA_PRESENT"},
+       {
+               .mask = 0x3 << 22,
+               .name = "CMD_TYPE",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "NORMAL"},
+                       {1, "SUSPEND CMD52"},
+                       {2, "RESUME CMD52"},
+                       {3, "ABORT"},
+                       {}
+               }
+       },
+       {0x3f << 24, "CMD"},
+       {},
+};
+
+static const struct trace_print_field const clk_control_reg[] = {
+       {1<<0, "SYSCLK_EN"},
+       {1<<1, "SYSCLK_STABLE"},
+       {1<<2, "SDCLK_EN"},
+       {1<<5, "PRG_CLK_MODE"},
+       {0xc0, "SD_CLK_DIV[9:8]"},
+       {0xFF00, "SD_CLK_DIV"},
+       {0xF0000, "DATA_TIMEOUT_CNT"},
+       {1<<24, "SOFT_RESET_ALL"},
+       {1<<25, "SOFT_RESET_CMD"},
+       {1<<26, "SOFT_RESET_DAT"},
+       {}
+};
+
+static const struct trace_print_field const acmd_err_flags[] = {
+       {1<<0, "EXEC_ERROR"},
+       {1<<1, "TIMEOUT_ERROR"},
+       {1<<2, "CRC_ERROR"},
+       {1<<3, "END_BIT_ERROR"},
+       {1<<4, "INDEX_ERROR"},
+       {1<<7, "CMD_ERROR"},
+       {
+               .mask = 7 << 16,
+               .name = "UHS_MODE",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "SDR12"},
+                       {1, "SDR25"},
+                       {2, "SDR50"},
+                       {3, "SDR104"},
+                       {4, "DDR50"},
+                       {}
+               }
+       },
+       {
+               .mask = 1 << 19,
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "3.3V"},
+                       {1, "1.8V"},
+                       {}
+               }
+       },
+       {
+               .mask = 3 << 20,
+               .name = "DRIVE_STRENGTH",
+               .symbols = (const struct trace_print_flags[]) {
+                       {0, "B"},
+                       {1, "A"},
+                       {2, "C"},
+                       {3, "D"},
+                       {}
+               }
+       },
+       {1<<22, "TUNING"},
+       {1<<23, "SAMPLE_CLK"},
+       {1<<30, "ASYNC_INT_EN"},
+       {1<<31, "AUTO_PRESENT_VAL"},
+       {}
+};
+
+/**
+ * sdhci_decode_register() - Decodes a SDHCI register
+ *
+ * @reg: Register offset that was accessed
+ * @val: Value written to the register
+ * @mask: Mask containing the number of bits written to the register. e.g.,
+ *        byte = 0xFF, word = 0xFFFF, long = 0xFFFFFFFF.
+ */
+static const char *sdhci_decode_register(struct trace_seq *p, u32 reg, u32 val,
+                                        u32 mask)
+{
+       u32 aligned = reg & ~3UL;
+       int shift = (reg - aligned) * 8;
+
+       val <<= shift;
+       mask <<= shift;
+
+       switch (aligned) {
+       case SDHCI_BLOCK_SIZE:
+               return trace_print_register(p, block_cnt_reg, val, mask);
+       case SDHCI_INT_STATUS:
+       case SDHCI_INT_ENABLE:
+       case SDHCI_SIGNAL_ENABLE:
+               return trace_print_flags_seq(p, " | ", val, int_flags);
+       case SDHCI_PRESENT_STATE:
+               return trace_print_flags_seq(p, " | ", val,
+                                            present_state_flags);
+       case SDHCI_HOST_CONTROL:
+               return trace_print_register(p, host_control_reg, val, mask);
+       case SDHCI_TRANSFER_MODE:
+               return trace_print_register(p, transfer_mode_reg, val, mask);
+       case SDHCI_CLOCK_CONTROL:
+               return trace_print_register(p, clk_control_reg, val, mask);
+       case SDHCI_ACMD12_ERR:
+               return trace_print_register(p, acmd_err_flags, val, mask);
+       default:
+               return "";
+       }
+}
+
+#define CREATE_TRACE_POINTS
+#include "sdhci-trace.h"
diff --git a/drivers/mmc/host/sdhci-trace.h b/drivers/mmc/host/sdhci-trace.h
new file mode 100644
index 000000000000..938a032ea38a
--- /dev/null
+++ b/drivers/mmc/host/sdhci-trace.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright 2019 Google LLC. */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sdhci
+
+#if !defined(_TRACE_SDHCI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SDHCI_H
+
+#include <linux/mmc/host.h>
+#include <linux/tracepoint.h>
+#include "sdhci.h"
+
+TRACE_EVENT(sdhci_read,
+
+       TP_PROTO(struct sdhci_host *host, u32 reg, u32 val, u32 mask),
+
+       TP_ARGS(host, reg, val, mask),
+
+       TP_STRUCT__entry(
+               __field(u32,    reg)
+               __field(u32,    val)
+               __field(u32,    mask)
+               __string(name,  mmc_hostname(host->mmc))
+       ),
+
+       TP_fast_assign(
+               __entry->reg = reg;
+               __entry->val = val;
+               __entry->mask = mask;
+               __assign_str(name, mmc_hostname(host->mmc));
+       ),
+
+       TP_printk("%s: %#x [%s] => %#x: %s",
+                 __get_str(name),
+                 __entry->reg,
+                 __print_symbolic(__entry->reg & ~3UL, SDHCI_REGS),
+                 __entry->val,
+                 sdhci_decode_register(
+                       p,
+                       __entry->reg,
+                       __entry->val,
+                       __entry->mask
+                 )
+       )
+);
+
+TRACE_EVENT(sdhci_write,
+
+       TP_PROTO(struct sdhci_host *host, u32 reg, u32 val, u32 mask),
+
+       TP_ARGS(host, reg, val, mask),
+
+       TP_STRUCT__entry(
+               __field(u32,    reg)
+               __field(u32,    val)
+               __field(u32,    mask)
+               __string(name,  mmc_hostname(host->mmc))
+       ),
+
+       TP_fast_assign(
+               __entry->reg = reg;
+               __entry->val = val;
+               __entry->mask = mask;
+               __assign_str(name, mmc_hostname(host->mmc));
+       ),
+
+       TP_printk("%s: %#x [%s] <= %#x: %s",
+                 __get_str(name),
+                 __entry->reg,
+                 __print_symbolic(__entry->reg & ~3UL, SDHCI_REGS),
+                 __entry->val,
+                 sdhci_decode_register(
+                       p,
+                       __entry->reg,
+                       __entry->val,
+                       __entry->mask
+                 )
+       )
+);
+
+
+#endif /* _TRACE_SDHCI_H */
+
+/* this part must be outside header guard */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE sdhci-trace
+
+#include <trace/define_trace.h>
-- 
2.21.0.392.gf8f6787159e-goog

Reply via email to