Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
0003 
0004 #include <linux/seq_file.h>
0005 #include "mtk_wed.h"
0006 #include "mtk_wed_regs.h"
0007 
0008 struct reg_dump {
0009     const char *name;
0010     u16 offset;
0011     u8 type;
0012     u8 base;
0013 };
0014 
0015 enum {
0016     DUMP_TYPE_STRING,
0017     DUMP_TYPE_WED,
0018     DUMP_TYPE_WDMA,
0019     DUMP_TYPE_WPDMA_TX,
0020     DUMP_TYPE_WPDMA_TXFREE,
0021 };
0022 
0023 #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
0024 #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
0025 #define DUMP_RING(_prefix, _base, ...)              \
0026     { _prefix " BASE", _base, __VA_ARGS__ },        \
0027     { _prefix " CNT",  _base + 0x4, __VA_ARGS__ },  \
0028     { _prefix " CIDX", _base + 0x8, __VA_ARGS__ },  \
0029     { _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
0030 
0031 #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
0032 #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
0033 
0034 #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
0035 #define DUMP_WDMA_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WDMA)
0036 
0037 #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n)
0038 #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE)
0039 
0040 static void
0041 print_reg_val(struct seq_file *s, const char *name, u32 val)
0042 {
0043     seq_printf(s, "%-32s %08x\n", name, val);
0044 }
0045 
0046 static void
0047 dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
0048           const struct reg_dump *regs, int n_regs)
0049 {
0050     const struct reg_dump *cur;
0051     u32 val;
0052 
0053     for (cur = regs; cur < &regs[n_regs]; cur++) {
0054         switch (cur->type) {
0055         case DUMP_TYPE_STRING:
0056             seq_printf(s, "%s======== %s:\n",
0057                    cur > regs ? "\n" : "",
0058                    cur->name);
0059             continue;
0060         case DUMP_TYPE_WED:
0061             val = wed_r32(dev, cur->offset);
0062             break;
0063         case DUMP_TYPE_WDMA:
0064             val = wdma_r32(dev, cur->offset);
0065             break;
0066         case DUMP_TYPE_WPDMA_TX:
0067             val = wpdma_tx_r32(dev, cur->base, cur->offset);
0068             break;
0069         case DUMP_TYPE_WPDMA_TXFREE:
0070             val = wpdma_txfree_r32(dev, cur->offset);
0071             break;
0072         }
0073         print_reg_val(s, cur->name, val);
0074     }
0075 }
0076 
0077 
0078 static int
0079 wed_txinfo_show(struct seq_file *s, void *data)
0080 {
0081     static const struct reg_dump regs[] = {
0082         DUMP_STR("WED TX"),
0083         DUMP_WED(WED_TX_MIB(0)),
0084         DUMP_WED_RING(WED_RING_TX(0)),
0085 
0086         DUMP_WED(WED_TX_MIB(1)),
0087         DUMP_WED_RING(WED_RING_TX(1)),
0088 
0089         DUMP_STR("WPDMA TX"),
0090         DUMP_WED(WED_WPDMA_TX_MIB(0)),
0091         DUMP_WED_RING(WED_WPDMA_RING_TX(0)),
0092         DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(0)),
0093 
0094         DUMP_WED(WED_WPDMA_TX_MIB(1)),
0095         DUMP_WED_RING(WED_WPDMA_RING_TX(1)),
0096         DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(1)),
0097 
0098         DUMP_STR("WPDMA TX"),
0099         DUMP_WPDMA_TX_RING(0),
0100         DUMP_WPDMA_TX_RING(1),
0101 
0102         DUMP_STR("WED WDMA RX"),
0103         DUMP_WED(WED_WDMA_RX_MIB(0)),
0104         DUMP_WED_RING(WED_WDMA_RING_RX(0)),
0105         DUMP_WED(WED_WDMA_RX_THRES(0)),
0106         DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(0)),
0107         DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(0)),
0108 
0109         DUMP_WED(WED_WDMA_RX_MIB(1)),
0110         DUMP_WED_RING(WED_WDMA_RING_RX(1)),
0111         DUMP_WED(WED_WDMA_RX_THRES(1)),
0112         DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(1)),
0113         DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(1)),
0114 
0115         DUMP_STR("WDMA RX"),
0116         DUMP_WDMA(WDMA_GLO_CFG),
0117         DUMP_WDMA_RING(WDMA_RING_RX(0)),
0118         DUMP_WDMA_RING(WDMA_RING_RX(1)),
0119     };
0120     struct mtk_wed_hw *hw = s->private;
0121     struct mtk_wed_device *dev = hw->wed_dev;
0122 
0123     if (!dev)
0124         return 0;
0125 
0126     dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
0127 
0128     return 0;
0129 }
0130 DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
0131 
0132 
0133 static int
0134 mtk_wed_reg_set(void *data, u64 val)
0135 {
0136     struct mtk_wed_hw *hw = data;
0137 
0138     regmap_write(hw->regs, hw->debugfs_reg, val);
0139 
0140     return 0;
0141 }
0142 
0143 static int
0144 mtk_wed_reg_get(void *data, u64 *val)
0145 {
0146     struct mtk_wed_hw *hw = data;
0147     unsigned int regval;
0148     int ret;
0149 
0150     ret = regmap_read(hw->regs, hw->debugfs_reg, &regval);
0151     if (ret)
0152         return ret;
0153 
0154     *val = regval;
0155 
0156     return 0;
0157 }
0158 
0159 DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set,
0160              "0x%08llx\n");
0161 
0162 void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
0163 {
0164     struct dentry *dir;
0165 
0166     snprintf(hw->dirname, sizeof(hw->dirname), "wed%d", hw->index);
0167     dir = debugfs_create_dir(hw->dirname, NULL);
0168     if (!dir)
0169         return;
0170 
0171     hw->debugfs_dir = dir;
0172     debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
0173     debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
0174     debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
0175 }