From 5cdf6c09ca9de3f037ba2d770206f3374459602d Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 30 Jun 2017 09:06:05 +0530 Subject: ASoC: Intel: Skylake: Add debugfs support For debug, the kernel debugfs mechanism is available. We can add various debug options for driver like module configuration read, firmware register read etc. This patch adds debugfs as a child to asoc plaform component and caller is added for skylake driver to do init and cleanup of debugfs. Signed-off-by: Vinod Koul Signed-off-by: Vunny Sodhi Signed-off-by: Guneshwor Singh Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-debug.c | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 sound/soc/intel/skylake/skl-debug.c (limited to 'sound/soc/intel/skylake/skl-debug.c') diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c new file mode 100644 index 000000000000..6bc4565773c5 --- /dev/null +++ b/sound/soc/intel/skylake/skl-debug.c @@ -0,0 +1,55 @@ +/* + * skl-debug.c - Debugfs for skl driver + * + * Copyright (C) 2016-17 Intel Corp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include "skl.h" + +struct skl_debug { + struct skl *skl; + struct device *dev; + + struct dentry *fs; +}; + +struct skl_debug *skl_debugfs_init(struct skl *skl) +{ + struct skl_debug *d; + + d = devm_kzalloc(&skl->pci->dev, sizeof(*d), GFP_KERNEL); + if (!d) + return NULL; + + /* create the debugfs dir with platform component's debugfs as parent */ + d->fs = debugfs_create_dir("dsp", + skl->platform->component.debugfs_root); + if (IS_ERR(d->fs) || !d->fs) { + dev_err(&skl->pci->dev, "debugfs root creation failed\n"); + return NULL; + } + + d->skl = skl; + d->dev = &skl->pci->dev; + + return d; +} + +void skl_debugfs_exit(struct skl_debug *d) +{ + debugfs_remove_recursive(d->fs); + + kfree(d); + +} -- cgit v1.2.3 From d14700a01f9101c2bc75c24fc859c8d85ba7e623 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 30 Jun 2017 09:06:06 +0530 Subject: ASoC: Intel: Skylake: Debugfs facility to dump module config Driver modules have lot of information represented in struct skl_module_cfg. Knowing this is useful for debug, so enable debugfs for this structure. Signed-off-by: Vinod Koul Signed-off-by: Vunny Sodhi Signed-off-by: Guneshwor Singh Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-debug.c | 156 +++++++++++++++++++++++++++++++++ sound/soc/intel/skylake/skl-topology.c | 3 + sound/soc/intel/skylake/skl.h | 10 +++ 3 files changed, 169 insertions(+) (limited to 'sound/soc/intel/skylake/skl-debug.c') diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c index 6bc4565773c5..be3238c63200 100644 --- a/sound/soc/intel/skylake/skl-debug.c +++ b/sound/soc/intel/skylake/skl-debug.c @@ -16,14 +16,159 @@ #include #include #include "skl.h" +#include "skl-tplg-interface.h" +#include "skl-topology.h" + +#define MOD_BUF PAGE_SIZE struct skl_debug { struct skl *skl; struct device *dev; struct dentry *fs; + struct dentry *modules; }; +static ssize_t skl_print_pins(struct skl_module_pin *m_pin, char *buf, + int max_pin, ssize_t size, bool direction) +{ + int i; + ssize_t ret = 0; + + for (i = 0; i < max_pin; i++) + ret += snprintf(buf + size, MOD_BUF - size, + "%s %d\n\tModule %d\n\tInstance %d\n\t" + "In-used %s\n\tType %s\n" + "\tState %d\n\tIndex %d\n", + direction ? "Input Pin:" : "Output Pin:", + i, m_pin[i].id.module_id, + m_pin[i].id.instance_id, + m_pin[i].in_use ? "Used" : "Unused", + m_pin[i].is_dynamic ? "Dynamic" : "Static", + m_pin[i].pin_state, i); + return ret; +} + +static ssize_t skl_print_fmt(struct skl_module_fmt *fmt, char *buf, + ssize_t size, bool direction) +{ + return snprintf(buf + size, MOD_BUF - size, + "%s\n\tCh %d\n\tFreq %d\n\tBit depth %d\n\t" + "Valid bit depth %d\n\tCh config %#x\n\tInterleaving %d\n\t" + "Sample Type %d\n\tCh Map %#x\n", + direction ? "Input Format:" : "Output Format:", + fmt->channels, fmt->s_freq, fmt->bit_depth, + fmt->valid_bit_depth, fmt->ch_cfg, + fmt->interleaving_style, fmt->sample_type, + fmt->ch_map); +} + +static ssize_t module_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct skl_module_cfg *mconfig = file->private_data; + char *buf; + ssize_t ret; + + buf = kzalloc(MOD_BUF, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = snprintf(buf, MOD_BUF, "Module:\n\tUUID %pUL\n\tModule id %d\n" + "\tInstance id %d\n\tPvt_id %d\n", mconfig->guid, + mconfig->id.module_id, mconfig->id.instance_id, + mconfig->id.pvt_id); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "Resources:\n\tMCPS %#x\n\tIBS %#x\n\tOBS %#x\t\n", + mconfig->mcps, mconfig->ibs, mconfig->obs); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "Module data:\n\tCore %d\n\tIn queue %d\n\t" + "Out queue %d\n\tType %s\n", + mconfig->core_id, mconfig->max_in_queue, + mconfig->max_out_queue, + mconfig->is_loadable ? "loadable" : "inbuilt"); + + ret += skl_print_fmt(mconfig->in_fmt, buf, ret, true); + ret += skl_print_fmt(mconfig->out_fmt, buf, ret, false); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "Fixup:\n\tParams %#x\n\tConverter %#x\n", + mconfig->params_fixup, mconfig->converter); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "Module Gateway:\n\tType %#x\n\tVbus %#x\n\tHW conn %#x\n\tSlot %#x\n", + mconfig->dev_type, mconfig->vbus_id, + mconfig->hw_conn_type, mconfig->time_slot); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "Pipeline:\n\tID %d\n\tPriority %d\n\tConn Type %d\n\t" + "Pages %#x\n", mconfig->pipe->ppl_id, + mconfig->pipe->pipe_priority, mconfig->pipe->conn_type, + mconfig->pipe->memory_pages); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "\tParams:\n\t\tHost DMA %d\n\t\tLink DMA %d\n", + mconfig->pipe->p_params->host_dma_id, + mconfig->pipe->p_params->link_dma_id); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "\tPCM params:\n\t\tCh %d\n\t\tFreq %d\n\t\tFormat %d\n", + mconfig->pipe->p_params->ch, + mconfig->pipe->p_params->s_freq, + mconfig->pipe->p_params->s_fmt); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "\tLink %#x\n\tStream %#x\n", + mconfig->pipe->p_params->linktype, + mconfig->pipe->p_params->stream); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "\tState %d\n\tPassthru %s\n", + mconfig->pipe->state, + mconfig->pipe->passthru ? "true" : "false"); + + ret += skl_print_pins(mconfig->m_in_pin, buf, + mconfig->max_in_queue, ret, true); + ret += skl_print_pins(mconfig->m_out_pin, buf, + mconfig->max_out_queue, ret, false); + + ret += snprintf(buf + ret, MOD_BUF - ret, + "Other:\n\tDomain %d\n\tHomogenous Input %s\n\t" + "Homogenous Output %s\n\tIn Queue Mask %d\n\t" + "Out Queue Mask %d\n\tDMA ID %d\n\tMem Pages %d\n\t" + "Module Type %d\n\tModule State %d\n", + mconfig->domain, + mconfig->homogenous_inputs ? "true" : "false", + mconfig->homogenous_outputs ? "true" : "false", + mconfig->in_queue_mask, mconfig->out_queue_mask, + mconfig->dma_id, mconfig->mem_pages, mconfig->m_state, + mconfig->m_type); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); + + kfree(buf); + return ret; +} + +static const struct file_operations mcfg_fops = { + .open = simple_open, + .read = module_read, + .llseek = default_llseek, +}; + + +void skl_debug_init_module(struct skl_debug *d, + struct snd_soc_dapm_widget *w, + struct skl_module_cfg *mconfig) +{ + if (!debugfs_create_file(w->name, 0444, + d->modules, mconfig, + &mcfg_fops)) + dev_err(d->dev, "%s: module debugfs init failed\n", w->name); +} + struct skl_debug *skl_debugfs_init(struct skl *skl) { struct skl_debug *d; @@ -43,7 +188,18 @@ struct skl_debug *skl_debugfs_init(struct skl *skl) d->skl = skl; d->dev = &skl->pci->dev; + /* now create the module dir */ + d->modules = debugfs_create_dir("modules", d->fs); + if (IS_ERR(d->modules) || !d->modules) { + dev_err(&skl->pci->dev, "modules debugfs create failed\n"); + goto err; + } + return d; + +err: + debugfs_remove_recursive(d->fs); + return NULL; } void skl_debugfs_exit(struct skl_debug *d) diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 9569f118e97e..c02da16fdfd6 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -2472,6 +2472,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig); if (ret < 0) return ret; + + skl_debug_init_module(skl->debugfs, w, mconfig); + bind_event: if (tplg_w->event_type == 0) { dev_dbg(bus->dev, "ASoC: No event handler required\n"); diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index a47779c819d5..14e7778d7f80 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -23,6 +23,7 @@ #include #include +#include #include "skl-nhlt.h" #define SKL_SUSPEND_DELAY 2000 @@ -120,9 +121,14 @@ void skl_update_d0i3c(struct device *dev, bool enable); int skl_nhlt_create_sysfs(struct skl *skl); void skl_nhlt_remove_sysfs(struct skl *skl); +struct skl_module_cfg; + #ifdef CONFIG_DEBUG_FS struct skl_debug *skl_debugfs_init(struct skl *skl); void skl_debugfs_exit(struct skl_debug *d); +void skl_debug_init_module(struct skl_debug *d, + struct snd_soc_dapm_widget *w, + struct skl_module_cfg *mconfig); #else static inline struct skl_debug *skl_debugfs_init(struct skl *skl) { @@ -130,6 +136,10 @@ static inline struct skl_debug *skl_debugfs_init(struct skl *skl) } static inline void skl_debugfs_exit(struct skl_debug *d) {} +static inline void skl_debug_init_module(struct skl_debug *d, + struct snd_soc_dapm_widget *w, + struct skl_module_cfg *mconfig) +{} #endif #endif /* __SOUND_SOC_SKL_H */ -- cgit v1.2.3 From bdd0384a5ada8bb5745e5f29c10a5ba88827efad Mon Sep 17 00:00:00 2001 From: Vunny Sodhi Date: Fri, 30 Jun 2017 09:06:08 +0530 Subject: ASoC: Intel: Skylake: Add support to read firmware registers This patch adds debugfs support to read fw registers, mailbox offsets and sram address. Signed-off-by: Mousumi Jana Signed-off-by: Ramesh Babu Signed-off-by: Jayachandran B Signed-off-by: Pardha Saradhi K Signed-off-by: Vunny Sodhi Signed-off-by: Guneshwor Singh Acked-By: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-debug.c | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'sound/soc/intel/skylake/skl-debug.c') diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c index be3238c63200..75497b1fda45 100644 --- a/sound/soc/intel/skylake/skl-debug.c +++ b/sound/soc/intel/skylake/skl-debug.c @@ -16,10 +16,15 @@ #include #include #include "skl.h" +#include "skl-sst-dsp.h" +#include "skl-sst-ipc.h" #include "skl-tplg-interface.h" #include "skl-topology.h" +#include "../common/sst-dsp-priv.h" #define MOD_BUF PAGE_SIZE +#define FW_REG_BUF PAGE_SIZE +#define FW_REG_SIZE 0x60 struct skl_debug { struct skl *skl; @@ -27,6 +32,7 @@ struct skl_debug { struct dentry *fs; struct dentry *modules; + u8 fw_read_buff[FW_REG_BUF]; }; static ssize_t skl_print_pins(struct skl_module_pin *m_pin, char *buf, @@ -169,6 +175,51 @@ void skl_debug_init_module(struct skl_debug *d, dev_err(d->dev, "%s: module debugfs init failed\n", w->name); } +static ssize_t fw_softreg_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct skl_debug *d = file->private_data; + struct sst_dsp *sst = d->skl->skl_sst->dsp; + size_t w0_stat_sz = sst->addr.w0_stat_sz; + void __iomem *in_base = sst->mailbox.in_base; + void __iomem *fw_reg_addr; + unsigned int offset; + char *tmp; + ssize_t ret = 0; + + tmp = kzalloc(FW_REG_BUF, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + fw_reg_addr = in_base - w0_stat_sz; + memset(d->fw_read_buff, 0, FW_REG_BUF); + + if (w0_stat_sz > 0) + __iowrite32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2); + + for (offset = 0; offset < FW_REG_SIZE; offset += 16) { + ret += snprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset); + hex_dump_to_buffer(d->fw_read_buff + offset, 16, 16, 4, + tmp + ret, FW_REG_BUF - ret, 0); + ret += strlen(tmp + ret); + + /* print newline for each offset */ + if (FW_REG_BUF - ret > 0) + tmp[ret++] = '\n'; + } + + ret = simple_read_from_buffer(user_buf, count, ppos, tmp, ret); + kfree(tmp); + + return ret; +} + +static const struct file_operations soft_regs_ctrl_fops = { + .open = simple_open, + .read = fw_softreg_read, + .llseek = default_llseek, +}; + struct skl_debug *skl_debugfs_init(struct skl *skl) { struct skl_debug *d; @@ -195,6 +246,12 @@ struct skl_debug *skl_debugfs_init(struct skl *skl) goto err; } + if (!debugfs_create_file("fw_soft_regs_rd", 0444, d->fs, d, + &soft_regs_ctrl_fops)) { + dev_err(d->dev, "fw soft regs control debugfs init failed\n"); + goto err; + } + return d; err: -- cgit v1.2.3 From 58be77537aa12ca0c6c91eaf37902ad5f8c812bd Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 3 Jul 2017 13:54:46 +0530 Subject: ASoC: Intel: Skylake: explicitly add the headers sst-dsp.h Commit bdd0384a5ada ("ASoC: Intel: Skylake: Add support to read firmware registers") introduced firmware register read so added sst-dsp-priv.h but missed adding sst-dsp.h as that leads to below compiler warning: In file included from sound/soc/intel/skylake/skl-debug.c:23:0: >> sound/soc/intel/skylake/../common/sst-dsp-priv.h:63:42: warning: 'struct sst_pdata' declared inside parameter list [enabled by default] int (*init)(struct sst_dsp *sst, struct sst_pdata *pdata); ^ >> sound/soc/intel/skylake/../common/sst-dsp-priv.h:63:42: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] So add the missing header. Fixes: bdd0384a5ada ("ASoC: Intel: Skylake: Add support to read firmware registers") Reported-by: kbuild test robot Signed-off-by: Vinod Koul Signed-off-by: Guneshwor Singh Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-debug.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc/intel/skylake/skl-debug.c') diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c index 75497b1fda45..34d06abbf796 100644 --- a/sound/soc/intel/skylake/skl-debug.c +++ b/sound/soc/intel/skylake/skl-debug.c @@ -20,6 +20,7 @@ #include "skl-sst-ipc.h" #include "skl-tplg-interface.h" #include "skl-topology.h" +#include "../common/sst-dsp.h" #include "../common/sst-dsp-priv.h" #define MOD_BUF PAGE_SIZE -- cgit v1.2.3 From 7d3d6e0645dd3689e625161b9e312108e66b2b51 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 3 Jul 2017 13:54:47 +0530 Subject: ASoC: Intel: Skylake: Remove driver debugfs exit For driver debugfs, debugfs_remove_recursive() is called which is not needed as it is already done in ASoC core debugfs. And a device managed memory need not be freed explicitly as device core frees it up. So remove unnecessary skl_debugfs_exit(). Fixes: 5cdf6c09ca9d ASoC: ("Intel: Skylake: Add debugfs support") Reported-by: Julia Lawall Reported-by: kbuild test robot Signed-off-by: Vinod Koul Signed-off-by: Guneshwor Singh Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-debug.c | 8 -------- sound/soc/intel/skylake/skl.c | 1 - sound/soc/intel/skylake/skl.h | 3 --- 3 files changed, 12 deletions(-) (limited to 'sound/soc/intel/skylake/skl-debug.c') diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c index 34d06abbf796..dc20d91f62e6 100644 --- a/sound/soc/intel/skylake/skl-debug.c +++ b/sound/soc/intel/skylake/skl-debug.c @@ -259,11 +259,3 @@ err: debugfs_remove_recursive(d->fs); return NULL; } - -void skl_debugfs_exit(struct skl_debug *d) -{ - debugfs_remove_recursive(d->fs); - - kfree(d); - -} diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 410ce83f4a49..334917ee41cf 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -866,7 +866,6 @@ static void skl_remove(struct pci_dev *pci) /* codec removal, invoke bus_device_remove */ snd_hdac_ext_bus_device_remove(ebus); - skl_debugfs_exit(skl->debugfs); skl->debugfs = NULL; skl_platform_unregister(&pci->dev); skl_free_dsp(skl); diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index 14e7778d7f80..a6b134b4c037 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -125,7 +125,6 @@ struct skl_module_cfg; #ifdef CONFIG_DEBUG_FS struct skl_debug *skl_debugfs_init(struct skl *skl); -void skl_debugfs_exit(struct skl_debug *d); void skl_debug_init_module(struct skl_debug *d, struct snd_soc_dapm_widget *w, struct skl_module_cfg *mconfig); @@ -134,8 +133,6 @@ static inline struct skl_debug *skl_debugfs_init(struct skl *skl) { return NULL; } -static inline void skl_debugfs_exit(struct skl_debug *d) -{} static inline void skl_debug_init_module(struct skl_debug *d, struct snd_soc_dapm_widget *w, struct skl_module_cfg *mconfig) -- cgit v1.2.3