162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/seq_file.h> 562306a36Sopenharmony_ci#include <linux/soc/mediatek/mtk_wed.h> 662306a36Sopenharmony_ci#include "mtk_wed.h" 762306a36Sopenharmony_ci#include "mtk_wed_regs.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistruct reg_dump { 1062306a36Sopenharmony_ci const char *name; 1162306a36Sopenharmony_ci u16 offset; 1262306a36Sopenharmony_ci u8 type; 1362306a36Sopenharmony_ci u8 base; 1462306a36Sopenharmony_ci}; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cienum { 1762306a36Sopenharmony_ci DUMP_TYPE_STRING, 1862306a36Sopenharmony_ci DUMP_TYPE_WED, 1962306a36Sopenharmony_ci DUMP_TYPE_WDMA, 2062306a36Sopenharmony_ci DUMP_TYPE_WPDMA_TX, 2162306a36Sopenharmony_ci DUMP_TYPE_WPDMA_TXFREE, 2262306a36Sopenharmony_ci DUMP_TYPE_WPDMA_RX, 2362306a36Sopenharmony_ci DUMP_TYPE_WED_RRO, 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING } 2762306a36Sopenharmony_ci#define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ } 2862306a36Sopenharmony_ci#define DUMP_RING(_prefix, _base, ...) \ 2962306a36Sopenharmony_ci { _prefix " BASE", _base, __VA_ARGS__ }, \ 3062306a36Sopenharmony_ci { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \ 3162306a36Sopenharmony_ci { _prefix " CIDX", _base + 0x8, __VA_ARGS__ }, \ 3262306a36Sopenharmony_ci { _prefix " DIDX", _base + 0xc, __VA_ARGS__ } 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED) 3562306a36Sopenharmony_ci#define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA) 3862306a36Sopenharmony_ci#define DUMP_WDMA_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WDMA) 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n) 4162306a36Sopenharmony_ci#define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE) 4262306a36Sopenharmony_ci#define DUMP_WPDMA_RX_RING(_n) DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n) 4362306a36Sopenharmony_ci#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO) 4462306a36Sopenharmony_ci#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO) 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic void 4762306a36Sopenharmony_ciprint_reg_val(struct seq_file *s, const char *name, u32 val) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci seq_printf(s, "%-32s %08x\n", name, val); 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic void 5362306a36Sopenharmony_cidump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev, 5462306a36Sopenharmony_ci const struct reg_dump *regs, int n_regs) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci const struct reg_dump *cur; 5762306a36Sopenharmony_ci u32 val; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci for (cur = regs; cur < ®s[n_regs]; cur++) { 6062306a36Sopenharmony_ci switch (cur->type) { 6162306a36Sopenharmony_ci case DUMP_TYPE_STRING: 6262306a36Sopenharmony_ci seq_printf(s, "%s======== %s:\n", 6362306a36Sopenharmony_ci cur > regs ? "\n" : "", 6462306a36Sopenharmony_ci cur->name); 6562306a36Sopenharmony_ci continue; 6662306a36Sopenharmony_ci case DUMP_TYPE_WED_RRO: 6762306a36Sopenharmony_ci case DUMP_TYPE_WED: 6862306a36Sopenharmony_ci val = wed_r32(dev, cur->offset); 6962306a36Sopenharmony_ci break; 7062306a36Sopenharmony_ci case DUMP_TYPE_WDMA: 7162306a36Sopenharmony_ci val = wdma_r32(dev, cur->offset); 7262306a36Sopenharmony_ci break; 7362306a36Sopenharmony_ci case DUMP_TYPE_WPDMA_TX: 7462306a36Sopenharmony_ci val = wpdma_tx_r32(dev, cur->base, cur->offset); 7562306a36Sopenharmony_ci break; 7662306a36Sopenharmony_ci case DUMP_TYPE_WPDMA_TXFREE: 7762306a36Sopenharmony_ci val = wpdma_txfree_r32(dev, cur->offset); 7862306a36Sopenharmony_ci break; 7962306a36Sopenharmony_ci case DUMP_TYPE_WPDMA_RX: 8062306a36Sopenharmony_ci val = wpdma_rx_r32(dev, cur->base, cur->offset); 8162306a36Sopenharmony_ci break; 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci print_reg_val(s, cur->name, val); 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic int 8862306a36Sopenharmony_ciwed_txinfo_show(struct seq_file *s, void *data) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci static const struct reg_dump regs[] = { 9162306a36Sopenharmony_ci DUMP_STR("WED TX"), 9262306a36Sopenharmony_ci DUMP_WED(WED_TX_MIB(0)), 9362306a36Sopenharmony_ci DUMP_WED_RING(WED_RING_TX(0)), 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci DUMP_WED(WED_TX_MIB(1)), 9662306a36Sopenharmony_ci DUMP_WED_RING(WED_RING_TX(1)), 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci DUMP_STR("WPDMA TX"), 9962306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_TX_MIB(0)), 10062306a36Sopenharmony_ci DUMP_WED_RING(WED_WPDMA_RING_TX(0)), 10162306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(0)), 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_TX_MIB(1)), 10462306a36Sopenharmony_ci DUMP_WED_RING(WED_WPDMA_RING_TX(1)), 10562306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(1)), 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci DUMP_STR("WPDMA TX"), 10862306a36Sopenharmony_ci DUMP_WPDMA_TX_RING(0), 10962306a36Sopenharmony_ci DUMP_WPDMA_TX_RING(1), 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci DUMP_STR("WED WDMA RX"), 11262306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_MIB(0)), 11362306a36Sopenharmony_ci DUMP_WED_RING(WED_WDMA_RING_RX(0)), 11462306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_THRES(0)), 11562306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(0)), 11662306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(0)), 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_MIB(1)), 11962306a36Sopenharmony_ci DUMP_WED_RING(WED_WDMA_RING_RX(1)), 12062306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_THRES(1)), 12162306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(1)), 12262306a36Sopenharmony_ci DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(1)), 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci DUMP_STR("WDMA RX"), 12562306a36Sopenharmony_ci DUMP_WDMA(WDMA_GLO_CFG), 12662306a36Sopenharmony_ci DUMP_WDMA_RING(WDMA_RING_RX(0)), 12762306a36Sopenharmony_ci DUMP_WDMA_RING(WDMA_RING_RX(1)), 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci DUMP_STR("WED TX FREE"), 13062306a36Sopenharmony_ci DUMP_WED(WED_RX_MIB(0)), 13162306a36Sopenharmony_ci DUMP_WED_RING(WED_RING_RX(0)), 13262306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)), 13362306a36Sopenharmony_ci DUMP_WED(WED_RX_MIB(1)), 13462306a36Sopenharmony_ci DUMP_WED_RING(WED_RING_RX(1)), 13562306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)), 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci DUMP_STR("WED WPDMA TX FREE"), 13862306a36Sopenharmony_ci DUMP_WED_RING(WED_WPDMA_RING_RX(0)), 13962306a36Sopenharmony_ci DUMP_WED_RING(WED_WPDMA_RING_RX(1)), 14062306a36Sopenharmony_ci }; 14162306a36Sopenharmony_ci struct mtk_wed_hw *hw = s->private; 14262306a36Sopenharmony_ci struct mtk_wed_device *dev = hw->wed_dev; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci if (dev) 14562306a36Sopenharmony_ci dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci return 0; 14862306a36Sopenharmony_ci} 14962306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(wed_txinfo); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic int 15262306a36Sopenharmony_ciwed_rxinfo_show(struct seq_file *s, void *data) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci static const struct reg_dump regs[] = { 15562306a36Sopenharmony_ci DUMP_STR("WPDMA RX"), 15662306a36Sopenharmony_ci DUMP_WPDMA_RX_RING(0), 15762306a36Sopenharmony_ci DUMP_WPDMA_RX_RING(1), 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci DUMP_STR("WPDMA RX"), 16062306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_RX_D_MIB(0)), 16162306a36Sopenharmony_ci DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)), 16262306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)), 16362306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_RX_D_MIB(1)), 16462306a36Sopenharmony_ci DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)), 16562306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)), 16662306a36Sopenharmony_ci DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB), 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci DUMP_STR("WED RX"), 16962306a36Sopenharmony_ci DUMP_WED_RING(WED_RING_RX_DATA(0)), 17062306a36Sopenharmony_ci DUMP_WED_RING(WED_RING_RX_DATA(1)), 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci DUMP_STR("WED RRO"), 17362306a36Sopenharmony_ci DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0), 17462306a36Sopenharmony_ci DUMP_WED(WED_RROQM_MID_MIB), 17562306a36Sopenharmony_ci DUMP_WED(WED_RROQM_MOD_MIB), 17662306a36Sopenharmony_ci DUMP_WED(WED_RROQM_MOD_COHERENT_MIB), 17762306a36Sopenharmony_ci DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0), 17862306a36Sopenharmony_ci DUMP_WED(WED_RROQM_FDBK_IND_MIB), 17962306a36Sopenharmony_ci DUMP_WED(WED_RROQM_FDBK_ENQ_MIB), 18062306a36Sopenharmony_ci DUMP_WED(WED_RROQM_FDBK_ANC_MIB), 18162306a36Sopenharmony_ci DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB), 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci DUMP_STR("WED Route QM"), 18462306a36Sopenharmony_ci DUMP_WED(WED_RTQM_R2H_MIB(0)), 18562306a36Sopenharmony_ci DUMP_WED(WED_RTQM_R2Q_MIB(0)), 18662306a36Sopenharmony_ci DUMP_WED(WED_RTQM_Q2H_MIB(0)), 18762306a36Sopenharmony_ci DUMP_WED(WED_RTQM_R2H_MIB(1)), 18862306a36Sopenharmony_ci DUMP_WED(WED_RTQM_R2Q_MIB(1)), 18962306a36Sopenharmony_ci DUMP_WED(WED_RTQM_Q2H_MIB(1)), 19062306a36Sopenharmony_ci DUMP_WED(WED_RTQM_Q2N_MIB), 19162306a36Sopenharmony_ci DUMP_WED(WED_RTQM_Q2B_MIB), 19262306a36Sopenharmony_ci DUMP_WED(WED_RTQM_PFDBK_MIB), 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci DUMP_STR("WED WDMA TX"), 19562306a36Sopenharmony_ci DUMP_WED(WED_WDMA_TX_MIB), 19662306a36Sopenharmony_ci DUMP_WED_RING(WED_WDMA_RING_TX), 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci DUMP_STR("WDMA TX"), 19962306a36Sopenharmony_ci DUMP_WDMA(WDMA_GLO_CFG), 20062306a36Sopenharmony_ci DUMP_WDMA_RING(WDMA_RING_TX(0)), 20162306a36Sopenharmony_ci DUMP_WDMA_RING(WDMA_RING_TX(1)), 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci DUMP_STR("WED RX BM"), 20462306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_BASE), 20562306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_RX_DMAD), 20662306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_PTR), 20762306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_TKID_MIB), 20862306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_BLEN), 20962306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_STS), 21062306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_INTF2), 21162306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_INTF), 21262306a36Sopenharmony_ci DUMP_WED(WED_RX_BM_ERR_STS), 21362306a36Sopenharmony_ci }; 21462306a36Sopenharmony_ci struct mtk_wed_hw *hw = s->private; 21562306a36Sopenharmony_ci struct mtk_wed_device *dev = hw->wed_dev; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci if (dev) 21862306a36Sopenharmony_ci dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci return 0; 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(wed_rxinfo); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistatic int 22562306a36Sopenharmony_cimtk_wed_reg_set(void *data, u64 val) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci struct mtk_wed_hw *hw = data; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci regmap_write(hw->regs, hw->debugfs_reg, val); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci return 0; 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic int 23562306a36Sopenharmony_cimtk_wed_reg_get(void *data, u64 *val) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci struct mtk_wed_hw *hw = data; 23862306a36Sopenharmony_ci unsigned int regval; 23962306a36Sopenharmony_ci int ret; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci ret = regmap_read(hw->regs, hw->debugfs_reg, ®val); 24262306a36Sopenharmony_ci if (ret) 24362306a36Sopenharmony_ci return ret; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci *val = regval; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci return 0; 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set, 25162306a36Sopenharmony_ci "0x%08llx\n"); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_civoid mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci struct dentry *dir; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci snprintf(hw->dirname, sizeof(hw->dirname), "wed%d", hw->index); 25862306a36Sopenharmony_ci dir = debugfs_create_dir(hw->dirname, NULL); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci hw->debugfs_dir = dir; 26162306a36Sopenharmony_ci debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); 26262306a36Sopenharmony_ci debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); 26362306a36Sopenharmony_ci debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); 26462306a36Sopenharmony_ci if (hw->version != 1) 26562306a36Sopenharmony_ci debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, 26662306a36Sopenharmony_ci &wed_rxinfo_fops); 26762306a36Sopenharmony_ci} 268