瀏覽代碼

ASoC: Intel: Skylake: Parse vendor tokens to build A-State table

A-State table is a power management table which allows the driver to
configure the DSP clock source corresponding to various load thresholds.
The table contains upto 3 A-State entries. The patch adds and parses the
corresponding A-State tokens to build the table.

Signed-off-by: Pradeep Tewani <pradeep.d.tewani@intel.com>
Signed-off-by: Guneshwor Singh <guneshwor.o.singh@intel.com>
Acked-By: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Pradeep Tewani 7 年之前
父節點
當前提交
437623554e
共有 3 個文件被更改,包括 76 次插入2 次删除
  1. 16 1
      include/uapi/sound/snd_sst_tokens.h
  2. 43 1
      sound/soc/intel/skylake/skl-topology.c
  3. 17 0
      sound/soc/intel/skylake/skl.h

+ 16 - 1
include/uapi/sound/snd_sst_tokens.h

@@ -221,6 +221,17 @@
  * %SKL_TKN_MM_U32_NUM_IN_FMT:  Number of input formats
  * %SKL_TKN_MM_U32_NUM_IN_FMT:  Number of input formats
  * %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats
  * %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats
  *
  *
+ * %SKL_TKN_U32_ASTATE_IDX:     Table Index for the A-State entry to be filled
+ *                              with kcps and clock source
+ *
+ * %SKL_TKN_U32_ASTATE_COUNT:   Number of valid entries in A-State table
+ *
+ * %SKL_TKN_U32_ASTATE_KCPS:    Specifies the core load threshold (in kilo
+ *                              cycles per second) below which DSP is clocked
+ *                              from source specified by clock source.
+ *
+ * %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry
+ *
  * module_id and loadable flags dont have tokens as these values will be
  * module_id and loadable flags dont have tokens as these values will be
  * read from the DSP FW manifest
  * read from the DSP FW manifest
  *
  *
@@ -308,7 +319,11 @@ enum SKL_TKNS {
 	SKL_TKN_MM_U32_NUM_IN_FMT,
 	SKL_TKN_MM_U32_NUM_IN_FMT,
 	SKL_TKN_MM_U32_NUM_OUT_FMT,
 	SKL_TKN_MM_U32_NUM_OUT_FMT,
 
 
-	SKL_TKN_MAX = SKL_TKN_MM_U32_NUM_OUT_FMT,
+	SKL_TKN_U32_ASTATE_IDX,
+	SKL_TKN_U32_ASTATE_COUNT,
+	SKL_TKN_U32_ASTATE_KCPS,
+	SKL_TKN_U32_ASTATE_CLK_SRC,
+	SKL_TKN_MAX = SKL_TKN_U32_ASTATE_CLK_SRC,
 };
 };
 
 
 #endif
 #endif

+ 43 - 1
sound/soc/intel/skylake/skl-topology.c

@@ -3037,11 +3037,13 @@ static int skl_tplg_get_int_tkn(struct device *dev,
 		struct snd_soc_tplg_vendor_value_elem *tkn_elem,
 		struct snd_soc_tplg_vendor_value_elem *tkn_elem,
 		struct skl *skl)
 		struct skl *skl)
 {
 {
-	int tkn_count = 0, ret;
+	int tkn_count = 0, ret, size;
 	static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx;
 	static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx;
 	struct skl_module_res *res = NULL;
 	struct skl_module_res *res = NULL;
 	struct skl_module_iface *fmt = NULL;
 	struct skl_module_iface *fmt = NULL;
 	struct skl_module *mod = NULL;
 	struct skl_module *mod = NULL;
+	static struct skl_astate_param *astate_table;
+	static int astate_cfg_idx, count;
 	int i;
 	int i;
 
 
 	if (skl->modules) {
 	if (skl->modules) {
@@ -3074,6 +3076,46 @@ static int skl_tplg_get_int_tkn(struct device *dev,
 		mod_idx = tkn_elem->value;
 		mod_idx = tkn_elem->value;
 		break;
 		break;
 
 
+	case SKL_TKN_U32_ASTATE_COUNT:
+		if (astate_table != NULL) {
+			dev_err(dev, "More than one entry for A-State count");
+			return -EINVAL;
+		}
+
+		if (tkn_elem->value > SKL_MAX_ASTATE_CFG) {
+			dev_err(dev, "Invalid A-State count %d\n",
+				tkn_elem->value);
+			return -EINVAL;
+		}
+
+		size = tkn_elem->value * sizeof(struct skl_astate_param) +
+				sizeof(count);
+		skl->cfg.astate_cfg = devm_kzalloc(dev, size, GFP_KERNEL);
+		if (!skl->cfg.astate_cfg)
+			return -ENOMEM;
+
+		astate_table = skl->cfg.astate_cfg->astate_table;
+		count = skl->cfg.astate_cfg->count = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_ASTATE_IDX:
+		if (tkn_elem->value >= count) {
+			dev_err(dev, "Invalid A-State index %d\n",
+				tkn_elem->value);
+			return -EINVAL;
+		}
+
+		astate_cfg_idx = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_ASTATE_KCPS:
+		astate_table[astate_cfg_idx].kcps = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_ASTATE_CLK_SRC:
+		astate_table[astate_cfg_idx].clk_src = tkn_elem->value;
+		break;
+
 	case SKL_TKN_U8_IN_PIN_TYPE:
 	case SKL_TKN_U8_IN_PIN_TYPE:
 	case SKL_TKN_U8_OUT_PIN_TYPE:
 	case SKL_TKN_U8_OUT_PIN_TYPE:
 	case SKL_TKN_U8_IN_QUEUE_COUNT:
 	case SKL_TKN_U8_IN_QUEUE_COUNT:

+ 17 - 0
sound/soc/intel/skylake/skl.h

@@ -29,6 +29,8 @@
 
 
 #define SKL_SUSPEND_DELAY 2000
 #define SKL_SUSPEND_DELAY 2000
 
 
+#define SKL_MAX_ASTATE_CFG		3
+
 #define AZX_PCIREG_PGCTL		0x44
 #define AZX_PCIREG_PGCTL		0x44
 #define AZX_PGCTL_LSRMD_MASK		(1 << 4)
 #define AZX_PGCTL_LSRMD_MASK		(1 << 4)
 #define AZX_PCIREG_CGCTL		0x48
 #define AZX_PCIREG_CGCTL		0x48
@@ -46,6 +48,20 @@ struct skl_dsp_resource {
 
 
 struct skl_debug;
 struct skl_debug;
 
 
+struct skl_astate_param {
+	u32 kcps;
+	u32 clk_src;
+};
+
+struct skl_astate_config {
+	u32 count;
+	struct skl_astate_param astate_table[0];
+};
+
+struct skl_fw_config {
+	struct skl_astate_config *astate_cfg;
+};
+
 struct skl {
 struct skl {
 	struct hdac_ext_bus ebus;
 	struct hdac_ext_bus ebus;
 	struct pci_dev *pci;
 	struct pci_dev *pci;
@@ -77,6 +93,7 @@ struct skl {
 	u8 nr_modules;
 	u8 nr_modules;
 	struct skl_module **modules;
 	struct skl_module **modules;
 	bool use_tplg_pcm;
 	bool use_tplg_pcm;
+	struct skl_fw_config cfg;
 };
 };
 
 
 #define skl_to_ebus(s)	(&(s)->ebus)
 #define skl_to_ebus(s)	(&(s)->ebus)