clear-pkgs-linux-iot-lts2018/0142-ASoC-Intel-Skylake-Add...

326 lines
8.1 KiB
Diff

From ad6578ae656bea9bf45e4e54e01ff4f930a2eb8e Mon Sep 17 00:00:00 2001
From: Mousumi Jana <mousumix.jana@intel.com>
Date: Thu, 26 Nov 2015 01:28:34 +0530
Subject: [PATCH 142/550] ASoC: Intel: Skylake:Add support to get fw
configuration
Debugfs gives the support to get the fw configuration depending on
base fw property.
Change-Id: Ib9bd67928939fdfc9443d9641a71a506e1ac22cb
Signed-off-by: Mousumi Jana <mousumix.jana@intel.com>
Reviewed-on:
Reviewed-by: Babu, Ramesh <ramesh.babu@intel.com>
Tested-by: Babu, Ramesh <ramesh.babu@intel.com>
---
sound/soc/intel/skylake/skl-debug.c | 206 +++++++++++++++++++++++++
sound/soc/intel/skylake/skl-sst-dsp.h | 2 +
sound/soc/intel/skylake/skl-topology.h | 26 ++++
3 files changed, 234 insertions(+)
diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c
index 23a5251e383b..ff6d8356cb4f 100644
--- a/sound/soc/intel/skylake/skl-debug.c
+++ b/sound/soc/intel/skylake/skl-debug.c
@@ -33,6 +33,19 @@
#define IPC_MOD_LARGE_CONFIG_SET 4
#define MOD_BUF1 (3 * PAGE_SIZE)
+#define DEFAULT_SZ 100
+#define DEFAULT_ID 0XFF
+#define ADSP_PROPERTIES_SZ 0x64
+#define ADSP_RESOURCE_STATE_SZ 0x18
+#define FIRMWARE_CONFIG_SZ 0x14c
+#define HARDWARE_CONFIG_SZ 0x84
+#define MODULES_INFO_SZ 0xa70
+#define PIPELINE_LIST_INFO_SZ 0xc
+#define SCHEDULERS_INFO_SZ 0x34
+#define GATEWAYS_INFO_SZ 0x4e4
+#define MEMORY_STATE_INFO_SZ 0x1000
+#define POWER_STATE_INFO_SZ 0x1000
+
struct nhlt_blob {
size_t size;
struct nhlt_specific_cfg *cfg;
@@ -49,6 +62,7 @@ struct skl_debug {
struct nhlt_blob ssp_blob[2*MAX_SSP];
struct nhlt_blob dmic_blob;
u32 ipc_data[MAX_SZ];
+ struct fw_ipc_data fw_ipc_data;
};
struct nhlt_specific_cfg
@@ -551,6 +565,196 @@ static int skl_init_nhlt(struct skl_debug *d)
return 0;
}
+static ssize_t adsp_control_read(struct file *file,
+ char __user *user_buf, size_t count, loff_t *ppos)
+{
+
+ struct skl_debug *d = file->private_data;
+ char *buf1;
+ ssize_t ret;
+ unsigned int data, ofs = 0;
+ int replysz = 0;
+
+ mutex_lock(&d->fw_ipc_data.mutex);
+ replysz = d->fw_ipc_data.replysz;
+ data = d->fw_ipc_data.adsp_id;
+
+ buf1 = kzalloc(MOD_BUF1, GFP_ATOMIC);
+ if (!buf1) {
+ mutex_unlock(&d->fw_ipc_data.mutex);
+ return -ENOMEM;
+ }
+
+ ret = snprintf(buf1, MOD_BUF1,
+ "\nADSP_PROP ID %x\n", data);
+ for (ofs = 0 ; ofs < replysz ; ofs += 16) {
+ ret += snprintf(buf1 + ret, MOD_BUF1 - ret,
+ "0x%.4x : ", ofs);
+ hex_dump_to_buffer((u8 *)(&(d->fw_ipc_data.mailbx[0])) + ofs,
+ 16, 16, 4,
+ buf1 + ret, MOD_BUF1 - ret, 0);
+ ret += strlen(buf1 + ret);
+ if (MOD_BUF1 - ret > 0)
+ buf1[ret++] = '\n';
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf1, ret);
+ mutex_unlock(&d->fw_ipc_data.mutex);
+ kfree(buf1);
+
+ return ret;
+}
+
+static ssize_t adsp_control_write(struct file *file,
+ const char __user *user_buf, size_t count, loff_t *ppos)
+{
+ struct skl_debug *d = file->private_data;
+ char buf[8];
+ int err, replysz;
+ unsigned int dsp_property;
+ u32 *ipc_data;
+ struct skl_sst *ctx = d->skl->skl_sst;
+ struct skl_ipc_large_config_msg msg;
+ char id[8];
+ u32 tx_data;
+ int j = 0, bufsize, tx_param = 0, tx_param_id;
+ int len = min(count, (sizeof(buf)-1));
+
+ mutex_lock(&d->fw_ipc_data.mutex);
+ if (copy_from_user(buf, user_buf, len)) {
+ mutex_unlock(&d->fw_ipc_data.mutex);
+ return -EFAULT;
+ }
+
+ buf[len] = '\0';
+ bufsize = strlen(buf);
+
+ while (buf[j] != '\0') {
+ if (buf[j] == ',') {
+ strncpy(id, &buf[j+1], (bufsize-j));
+ buf[j] = '\0';
+ tx_param = 1;
+ } else
+ j++;
+ }
+
+ err = kstrtouint(buf, 10, &dsp_property);
+
+ if ((dsp_property == DMA_CONTROL) || (dsp_property == ENABLE_LOGS)) {
+ dev_err(d->dev, "invalid input !! not readable\n");
+ mutex_unlock(&d->fw_ipc_data.mutex);
+ return -EINVAL;
+ }
+
+ if (tx_param == 1) {
+ err = kstrtouint(id, 10, &tx_param_id);
+ tx_data = (tx_param_id << 8) | dsp_property;
+ }
+
+ ipc_data = kzalloc(DSP_BUF, GFP_ATOMIC);
+ if (!ipc_data) {
+ mutex_unlock(&d->fw_ipc_data.mutex);
+ return -ENOMEM;
+ }
+
+ switch (dsp_property) {
+
+ case ADSP_PROPERTIES:
+ replysz = ADSP_PROPERTIES_SZ;
+ break;
+
+ case ADSP_RESOURCE_STATE:
+ replysz = ADSP_RESOURCE_STATE_SZ;
+ break;
+
+ case FIRMWARE_CONFIG:
+ replysz = FIRMWARE_CONFIG_SZ;
+ break;
+
+ case HARDWARE_CONFIG:
+ replysz = HARDWARE_CONFIG_SZ;
+ break;
+
+ case MODULES_INFO:
+ replysz = MODULES_INFO_SZ;
+ break;
+
+ case PIPELINE_LIST_INFO:
+ replysz = PIPELINE_LIST_INFO_SZ;
+ break;
+
+ case SCHEDULERS_INFO:
+ replysz = SCHEDULERS_INFO_SZ;
+ break;
+
+ case GATEWAYS_INFO:
+ replysz = GATEWAYS_INFO_SZ;
+ break;
+
+ case MEMORY_STATE_INFO:
+ replysz = MEMORY_STATE_INFO_SZ;
+ break;
+
+ case POWER_STATE_INFO:
+ replysz = POWER_STATE_INFO_SZ;
+ break;
+
+ default:
+ mutex_unlock(&d->fw_ipc_data.mutex);
+ kfree(ipc_data);
+ return -EINVAL;
+ }
+
+ msg.module_id = 0x0;
+ msg.instance_id = 0x0;
+ msg.large_param_id = dsp_property;
+ msg.param_data_size = replysz;
+
+ if (tx_param == 1)
+ skl_ipc_get_large_config(&ctx->ipc, &msg,
+ ipc_data, &tx_data, sizeof(u32));
+ else
+ skl_ipc_get_large_config(&ctx->ipc, &msg,
+ ipc_data, NULL, 0);
+
+ memset(&d->fw_ipc_data.mailbx[0], 0, DSP_BUF);
+
+ memcpy(&d->fw_ipc_data.mailbx[0], ipc_data, replysz);
+
+ d->fw_ipc_data.adsp_id = dsp_property;
+
+ d->fw_ipc_data.replysz = replysz;
+
+ /* Userspace has been fiddling around behindthe kernel's back*/
+ add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
+ mutex_unlock(&d->fw_ipc_data.mutex);
+ kfree(ipc_data);
+
+ return len;
+}
+
+static const struct file_operations ssp_cntrl_adsp_fops = {
+ .open = simple_open,
+ .read = adsp_control_read,
+ .write = adsp_control_write,
+ .llseek = default_llseek,
+};
+
+static int skl_init_adsp(struct skl_debug *d)
+{
+ if (!debugfs_create_file("adsp_prop_ctrl", 0644, d->fs, d,
+ &ssp_cntrl_adsp_fops)) {
+ dev_err(d->dev, "adsp control debugfs init failed\n");
+ return -EIO;
+ }
+
+ memset(&d->fw_ipc_data.mailbx[0], 0, DSP_BUF);
+ d->fw_ipc_data.replysz = DEFAULT_SZ;
+ d->fw_ipc_data.adsp_id = DEFAULT_ID;
+
+ return 0;
+}
+
struct skl_debug *skl_debugfs_init(struct skl *skl)
{
struct skl_debug *d;
@@ -559,6 +763,7 @@ struct skl_debug *skl_debugfs_init(struct skl *skl)
if (!d)
return NULL;
+ mutex_init(&d->fw_ipc_data.mutex);
/* create the debugfs dir with platform component's debugfs as parent */
d->fs = debugfs_create_dir("dsp",
skl->component->debugfs_root);
@@ -591,6 +796,7 @@ struct skl_debug *skl_debugfs_init(struct skl *skl)
}
skl_init_nhlt(d);
+ skl_init_adsp(d);
skl_init_mod_set_get(d);
return d;
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 33de8c939bc4..767c6edddc3a 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -127,6 +127,8 @@ struct skl_lib_info;
#define SKL_ADSPCS_CPA_SHIFT 24
#define SKL_ADSPCS_CPA_MASK(cm) ((cm) << SKL_ADSPCS_CPA_SHIFT)
+#define DSP_BUF PAGE_SIZE
+
/* DSP Core state */
enum skl_dsp_states {
SKL_DSP_RUNNING = 1,
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index c6158d37f557..b8a1d8b90fe1 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -32,6 +32,7 @@
#define MAX_TS_GROUPS 8
#define MAX_DMIC_TS_GROUPS 4
#define MAX_FIXED_DMIC_PARAMS_SIZE 727
+#define MAX_ADSP_SZ 1024
/* Maximum number of coefficients up down mixer module */
#define UP_DOWN_MIXER_MAX_COEFF 8
@@ -514,6 +515,31 @@ struct mod_set_get {
u32 mailbx[1024];
};
+enum base_fw_run_time_param {
+ ADSP_PROPERTIES = 0,
+ ADSP_RESOURCE_STATE = 1,
+ NOTIFICATION_MASK = 3,
+ ASTATE_TABLE = 4,
+ DMA_CONTROL = 5,
+ ENABLE_LOGS = 6,
+ FIRMWARE_CONFIG = 7,
+ HARDWARE_CONFIG = 8,
+ MODULES_INFO = 9,
+ PIPELINE_LIST_INFO = 10,
+ PIPELINE_PROPS = 11,
+ SCHEDULERS_INFO = 12,
+ GATEWAYS_INFO = 13,
+ MEMORY_STATE_INFO = 14,
+ POWER_STATE_INFO = 15
+};
+
+struct fw_ipc_data {
+ u32 replysz;
+ u32 adsp_id;
+ u32 mailbx[MAX_ADSP_SZ];
+ struct mutex mutex;
+};
+
int skl_tplg_be_update_params(struct snd_soc_dai *dai,
struct skl_pipe_params *params);
int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
--
2.19.1