From df3da091cc753bc55365fc20ce92aade3f32b387 Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Fri, 16 Dec 2022 18:25:35 +0200 Subject: [PATCH] topology: nhlt: intel: add support for ssp blob ver 1.5 Ssp plugin had already a definition for newer nhlt blob version 1.5. Add support to generate that instead of legacy blob. Never blob can be generated by adding "version" field in SSP dai topology2 definition and setting it to lower 16 bits of SSP_BLOB_VER_1_5 (0xee000105) -> 0x105 i.e 8 bits for major and 8 bits for minor version. SSP."0" { id 0 dai_index 0 direction "duplex" name NoCodec-0 version 0x105 } Fixes: https://github.com/alsa-project/alsa-utils/pull/184 Signed-off-by: Jaska Uimonen Signed-off-by: Jaroslav Kysela --- topology/nhlt/intel/ssp-nhlt.c | 5 +- topology/nhlt/intel/ssp/ssp-debug.c | 79 ++++++++++++++++------- topology/nhlt/intel/ssp/ssp-internal.h | 8 +++ topology/nhlt/intel/ssp/ssp-process.c | 88 +++++++++++++++++++++++--- topology/nhlt/intel/ssp/ssp-process.h | 3 +- 5 files changed, 148 insertions(+), 35 deletions(-) diff --git a/topology/nhlt/intel/ssp-nhlt.c b/topology/nhlt/intel/ssp-nhlt.c index 4a6980f..f1e4fc3 100644 --- a/topology/nhlt/intel/ssp-nhlt.c +++ b/topology/nhlt/intel/ssp-nhlt.c @@ -398,6 +398,7 @@ static int set_ssp_data(struct intel_nhlt_params *nhlt, snd_config_t *dai_cfg, s long clks_control = 0; long sample_bits = 0; long bclk_delay = 0; + long version = 0; long dai_index = 0; long mclk_id = 0; long io_clk = 0; @@ -415,6 +416,7 @@ static int set_ssp_data(struct intel_nhlt_params *nhlt, snd_config_t *dai_cfg, s { "frame_pulse_width", SND_CONFIG_TYPE_INTEGER, NULL, &frame_pulse_width, NULL}, { "tdm_padding_per_slot", SND_CONFIG_TYPE_STRING, NULL, NULL, &tdm_padding_per_slot}, + { "version", SND_CONFIG_TYPE_INTEGER, NULL, &version, NULL}, }; ret = find_set_values(&ssp_data[0], ARRAY_SIZE(ssp_data), dai_cfg, top, "Class.Dai.SSP"); @@ -422,7 +424,8 @@ static int set_ssp_data(struct intel_nhlt_params *nhlt, snd_config_t *dai_cfg, s return ret; return ssp_set_params(nhlt, direction, dai_index, io_clk, bclk_delay, sample_bits, mclk_id, - clks_control, frame_pulse_width, tdm_padding_per_slot, quirks); + clks_control, frame_pulse_width, tdm_padding_per_slot, quirks, + version); } /* init ssp parameters, should be called before parsing dais */ diff --git a/topology/nhlt/intel/ssp/ssp-debug.c b/topology/nhlt/intel/ssp/ssp-debug.c index 3e73078..e472793 100644 --- a/topology/nhlt/intel/ssp/ssp-debug.c +++ b/topology/nhlt/intel/ssp/ssp-debug.c @@ -14,6 +14,7 @@ void ssp_print_calculated(struct intel_ssp_params *ssp) { struct ssp_intel_config_data *blob; + struct ssp_intel_config_data_1_5 *blob15; struct ssp_aux_blob *blob_aux; int ssp_index = ssp->ssp_count; uint32_t *ptr; @@ -26,36 +27,67 @@ void ssp_print_calculated(struct intel_ssp_params *ssp) fprintf(stdout, "ssp %d dai_index: %u\n", ssp_index, ssp->ssp_dai_index[ssp_index]); + fprintf(stdout, "ssp blob version %u\n", ssp->ssp_prm[ssp_index].version); + fprintf(stdout, "ssp %d hw_config_count: %u\n", ssp_index, ssp->ssp_hw_config_count[ssp_index]); fprintf(stdout, "\n"); for (i = 0; i < ssp->ssp_hw_config_count[ssp_index]; i++) { - blob = &ssp->ssp_blob[ssp_index][i]; fprintf(stdout, "ssp blob %d hw_config %d\n", ssp->ssp_count, i); - fprintf(stdout, "gateway_attributes %u\n", blob->gateway_attributes); - fprintf(stdout, "ts_group[0] 0x%08x\n", blob->ts_group[0]); - fprintf(stdout, "ts_group[1] 0x%08x\n", blob->ts_group[1]); - fprintf(stdout, "ts_group[2] 0x%08x\n", blob->ts_group[2]); - fprintf(stdout, "ts_group[3] 0x%08x\n", blob->ts_group[3]); - fprintf(stdout, "ts_group[4] 0x%08x\n", blob->ts_group[4]); - fprintf(stdout, "ts_group[5] 0x%08x\n", blob->ts_group[5]); - fprintf(stdout, "ts_group[6] 0x%08x\n", blob->ts_group[6]); - fprintf(stdout, "ts_group[7] 0x%08x\n", blob->ts_group[7]); - fprintf(stdout, "ssc0 0x%08x\n", blob->ssc0); - fprintf(stdout, "ssc1 0x%08x\n", blob->ssc1); - fprintf(stdout, "sscto 0x%08x\n", blob->sscto); - fprintf(stdout, "sspsp 0x%08x\n", blob->sspsp); - fprintf(stdout, "sstsa 0x%08x\n", blob->sstsa); - fprintf(stdout, "ssrsa 0x%08x\n", blob->ssrsa); - fprintf(stdout, "ssc2 0x%08x\n", blob->ssc2); - fprintf(stdout, "sspsp2 0x%08x\n", blob->sspsp2); - fprintf(stdout, "ssc3 0x%08x\n", blob->ssc3); - fprintf(stdout, "ssioc 0x%08x\n", blob->ssioc); - fprintf(stdout, "mdivc 0x%08x\n", blob->mdivc); - fprintf(stdout, "mdivr 0x%08x\n", blob->mdivr); - + if (ssp->ssp_prm[ssp_index].version == SSP_BLOB_VER_1_5) { + blob15 = &ssp->ssp_blob_1_5[ssp_index][i]; + fprintf(stdout, "gateway_attributes %u\n", blob15->gateway_attributes); + fprintf(stdout, "version %u\n", blob15->version); + fprintf(stdout, "size %u\n", blob15->size); + fprintf(stdout, "ts_group[0] 0x%08x\n", blob15->ts_group[0]); + fprintf(stdout, "ts_group[1] 0x%08x\n", blob15->ts_group[1]); + fprintf(stdout, "ts_group[2] 0x%08x\n", blob15->ts_group[2]); + fprintf(stdout, "ts_group[3] 0x%08x\n", blob15->ts_group[3]); + fprintf(stdout, "ts_group[4] 0x%08x\n", blob15->ts_group[4]); + fprintf(stdout, "ts_group[5] 0x%08x\n", blob15->ts_group[5]); + fprintf(stdout, "ts_group[6] 0x%08x\n", blob15->ts_group[6]); + fprintf(stdout, "ts_group[7] 0x%08x\n", blob15->ts_group[7]); + fprintf(stdout, "ssc0 0x%08x\n", blob15->ssc0); + fprintf(stdout, "ssc1 0x%08x\n", blob15->ssc1); + fprintf(stdout, "sscto 0x%08x\n", blob15->sscto); + fprintf(stdout, "sspsp 0x%08x\n", blob15->sspsp); + fprintf(stdout, "sstsa 0x%08x\n", blob15->sstsa); + fprintf(stdout, "ssrsa 0x%08x\n", blob15->ssrsa); + fprintf(stdout, "ssc2 0x%08x\n", blob15->ssc2); + fprintf(stdout, "sspsp2 0x%08x\n", blob15->sspsp2); + fprintf(stdout, "ssc3 0x%08x\n", blob15->ssc3); + fprintf(stdout, "ssioc 0x%08x\n", blob15->ssioc); + fprintf(stdout, "mdivc 0x%08x\n", blob15->mdivctlr); + fprintf(stdout, "mdivr count 0x%08x\n", blob15->mdivrcnt); + for (j = 0; j < blob15->mdivrcnt; j++) + fprintf(stdout, "mdivr 0x%08x\n", + ssp->ssp_prm[ssp_index].mdivr[i].mdivrs[j]); + } else { + blob = &ssp->ssp_blob[ssp_index][i]; + fprintf(stdout, "gateway_attributes %u\n", blob->gateway_attributes); + fprintf(stdout, "ts_group[0] 0x%08x\n", blob->ts_group[0]); + fprintf(stdout, "ts_group[1] 0x%08x\n", blob->ts_group[1]); + fprintf(stdout, "ts_group[2] 0x%08x\n", blob->ts_group[2]); + fprintf(stdout, "ts_group[3] 0x%08x\n", blob->ts_group[3]); + fprintf(stdout, "ts_group[4] 0x%08x\n", blob->ts_group[4]); + fprintf(stdout, "ts_group[5] 0x%08x\n", blob->ts_group[5]); + fprintf(stdout, "ts_group[6] 0x%08x\n", blob->ts_group[6]); + fprintf(stdout, "ts_group[7] 0x%08x\n", blob->ts_group[7]); + fprintf(stdout, "ssc0 0x%08x\n", blob->ssc0); + fprintf(stdout, "ssc1 0x%08x\n", blob->ssc1); + fprintf(stdout, "sscto 0x%08x\n", blob->sscto); + fprintf(stdout, "sspsp 0x%08x\n", blob->sspsp); + fprintf(stdout, "sstsa 0x%08x\n", blob->sstsa); + fprintf(stdout, "ssrsa 0x%08x\n", blob->ssrsa); + fprintf(stdout, "ssc2 0x%08x\n", blob->ssc2); + fprintf(stdout, "sspsp2 0x%08x\n", blob->sspsp2); + fprintf(stdout, "ssc3 0x%08x\n", blob->ssc3); + fprintf(stdout, "ssioc 0x%08x\n", blob->ssioc); + fprintf(stdout, "mdivc 0x%08x\n", blob->mdivc); + fprintf(stdout, "mdivr 0x%08x\n", blob->mdivr); + } blob_aux = (struct ssp_aux_blob *)&(ssp->ssp_blob_ext[ssp_index][i]); fprintf(stdout, "aux_blob size %u\n", blob_aux->size); for (j = 0; j < blob_aux->size; j += 4) { @@ -97,6 +129,7 @@ void ssp_print_internal(struct intel_ssp_params *ssp) fprintf(stdout, "clks_control %u\n", dai->clks_control); fprintf(stdout, "quirks %u\n", dai->quirks); fprintf(stdout, "bclk_delay %u\n", dai->bclk_delay); + fprintf(stdout, "version %u\n", dai->version); fprintf(stdout, "\n"); diff --git a/topology/nhlt/intel/ssp/ssp-internal.h b/topology/nhlt/intel/ssp/ssp-internal.h index 6c2894e..ab6a875 100644 --- a/topology/nhlt/intel/ssp/ssp-internal.h +++ b/topology/nhlt/intel/ssp/ssp-internal.h @@ -102,6 +102,11 @@ struct ssp_aux_blob { uint8_t aux_blob[256]; }; +struct ssp_config_mdivr { + uint32_t count; + uint32_t mdivrs[8]; +}; + /* structs for gathering the ssp parameters from topology */ struct ssp_config_hw { uint32_t mclk_rate; @@ -126,8 +131,10 @@ struct ssp_config_dai { uint32_t quirks; uint32_t bclk_delay; uint8_t direction; + uint32_t version; struct ssp_config_hw hw_cfg[SSP_MAX_HW_CONFIG]; struct ssp_config_aux aux_cfg[SSP_MAX_HW_CONFIG]; + struct ssp_config_mdivr mdivr[SSP_MAX_HW_CONFIG]; }; struct intel_ssp_params { @@ -139,6 +146,7 @@ struct intel_ssp_params { /* ssp vendor blob structs */ struct ssp_intel_config_data ssp_blob[SSP_MAX_DAIS][SSP_MAX_HW_CONFIG]; + struct ssp_intel_config_data_1_5 ssp_blob_1_5[SSP_MAX_DAIS][SSP_MAX_HW_CONFIG]; struct ssp_aux_blob ssp_blob_ext[SSP_MAX_DAIS][SSP_MAX_HW_CONFIG]; }; diff --git a/topology/nhlt/intel/ssp/ssp-process.c b/topology/nhlt/intel/ssp/ssp-process.c index cebb5b5..e5ff26c 100644 --- a/topology/nhlt/intel/ssp/ssp-process.c +++ b/topology/nhlt/intel/ssp/ssp-process.c @@ -36,6 +36,42 @@ static int popcount(uint32_t value) return bits_set; } +static void ssp_calculate_intern_v15(struct intel_nhlt_params *nhlt, int hwi) +{ + struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; + int di = ssp->ssp_count;; + struct ssp_intel_config_data_1_5 *blob15 = &ssp->ssp_blob_1_5[di][hwi]; + struct ssp_intel_config_data *blob = &ssp->ssp_blob[di][hwi]; + int i; + + blob15->gateway_attributes = ssp->ssp_blob[di][hwi].gateway_attributes; + blob15->version = SSP_BLOB_VER_1_5; + + for (i = 0; i < 8; i++) + blob15->ts_group[i] = blob->ts_group[i]; + + blob15->ssc0 = blob->ssc0; + blob15->ssc1 = blob->ssc1; + blob15->sscto = blob->sscto; + blob15->sspsp = blob->sspsp; + blob15->sstsa = blob->sstsa; + blob15->ssrsa = blob->ssrsa; + blob15->ssc2 = blob->ssc2; + blob15->sspsp2 = blob->sspsp2; + blob15->ssc3 = blob->ssc3; + blob15->ssioc = blob->ssioc; + + /* for now we use only 1 divider as in legacy */ + blob15->mdivctlr = blob->mdivc; + ssp->ssp_prm[di].mdivr[hwi].count = 1; + blob15->mdivrcnt = ssp->ssp_prm[di].mdivr[hwi].count; + ssp->ssp_prm[di].mdivr[hwi].mdivrs[0] = blob->mdivr; + + blob15->size = sizeof(struct ssp_intel_config_data_1_5) + + blob15->mdivrcnt * sizeof(uint32_t) + + ssp->ssp_blob_ext[di][hwi].size; +} + static int ssp_calculate_intern(struct intel_nhlt_params *nhlt, int hwi) { struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; @@ -691,6 +727,8 @@ static int ssp_calculate_intern_ext(struct intel_nhlt_params *nhlt, int hwi) return 0; } + + int ssp_calculate(struct intel_nhlt_params *nhlt) { struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; @@ -705,6 +743,8 @@ int ssp_calculate(struct intel_nhlt_params *nhlt) return -EINVAL; if (ssp_calculate_intern_ext(nhlt, i) < 0) return -EINVAL; + /* v15 blob is made from legacy blob, so it can't fail */ + ssp_calculate_intern_v15(nhlt, i); } ssp_print_internal(ssp); @@ -767,8 +807,16 @@ int ssp_get_vendor_blob_size(struct intel_nhlt_params *nhlt, int dai_index, { struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; - *size = sizeof(struct ssp_intel_config_data) + - ssp->ssp_blob_ext[dai_index][hw_config_index].size; + if (!ssp) + return -EINVAL; + + /* set size for the blob */ + if (ssp->ssp_prm[dai_index].version == SSP_BLOB_VER_1_5) + *size = ssp->ssp_blob_1_5[dai_index][hw_config_index].size; + else + /* legacy */ + *size = sizeof(struct ssp_intel_config_data) + + ssp->ssp_blob_ext[dai_index][hw_config_index].size; return 0; } @@ -788,25 +836,42 @@ int ssp_get_vendor_blob(struct intel_nhlt_params *nhlt, uint8_t *vendor_blob, int dai_index, int hw_config_index) { struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; + uint32_t basic_len, clock_len; if (!ssp) return -EINVAL; /* top level struct */ - memcpy(vendor_blob, &ssp->ssp_blob[dai_index][hw_config_index], - sizeof(struct ssp_intel_config_data)); - - /* ext data */ - memcpy(vendor_blob + sizeof(struct ssp_intel_config_data), - ssp->ssp_blob_ext[dai_index][hw_config_index].aux_blob, - ssp->ssp_blob_ext[dai_index][hw_config_index].size); + if (ssp->ssp_prm[dai_index].version == SSP_BLOB_VER_1_5) { + basic_len = sizeof(struct ssp_intel_config_data_1_5); + clock_len = sizeof(uint32_t) * ssp->ssp_prm[dai_index].mdivr[hw_config_index].count; + /* basic data */ + memcpy(vendor_blob, &ssp->ssp_blob_1_5[dai_index][hw_config_index], basic_len); + /* clock data */ + memcpy(vendor_blob + basic_len, + &ssp->ssp_prm[dai_index].mdivr[hw_config_index].mdivrs[0], clock_len); + /* ext data */ + memcpy(vendor_blob + basic_len + clock_len, + ssp->ssp_blob_ext[dai_index][hw_config_index].aux_blob, + ssp->ssp_blob_ext[dai_index][hw_config_index].size); + } + else { + basic_len = sizeof(struct ssp_intel_config_data); + /*basic data */ + memcpy(vendor_blob, &ssp->ssp_blob[dai_index][hw_config_index], basic_len); + /* ext data */ + memcpy(vendor_blob + basic_len, + ssp->ssp_blob_ext[dai_index][hw_config_index].aux_blob, + ssp->ssp_blob_ext[dai_index][hw_config_index].size); + } return 0; } int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_index, int io_clk, int bclk_delay, int sample_bits, int mclk_id, int clks_control, - int frame_pulse_width, const char *tdm_padding_per_slot, const char *quirks) + int frame_pulse_width, const char *tdm_padding_per_slot, const char *quirks, + int version) { struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params; @@ -831,6 +896,9 @@ int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_inde ssp->ssp_prm[ssp->ssp_count].mclk_id = mclk_id; ssp->ssp_prm[ssp->ssp_count].clks_control = clks_control; ssp->ssp_prm[ssp->ssp_count].frame_pulse_width = frame_pulse_width; + /* let's compare the lower 16 bits as we don't send the signature from topology */ + if (version == (SSP_BLOB_VER_1_5 & ((1 << 16) - 1))) + ssp->ssp_prm[ssp->ssp_count].version = SSP_BLOB_VER_1_5; if (tdm_padding_per_slot && !strcmp(tdm_padding_per_slot, "true")) ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 1; else diff --git a/topology/nhlt/intel/ssp/ssp-process.h b/topology/nhlt/intel/ssp/ssp-process.h index e59b50a..6830fa1 100644 --- a/topology/nhlt/intel/ssp/ssp-process.h +++ b/topology/nhlt/intel/ssp/ssp-process.h @@ -18,7 +18,8 @@ int ssp_init_params(struct intel_nhlt_params *nhlt); /* set parameters when parsing topology2 conf */ int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_index, int io_clk, int bclk_delay, int sample_bits, int mclk_id, int clks_control, - int frame_pulse_width, const char *tdm_padding_per_slot, const char *quirks); + int frame_pulse_width, const char *tdm_padding_per_slot, const char *quirks, + int version); int ssp_hw_set_params(struct intel_nhlt_params *nhlt, const char *format, const char *mclk, const char *bclk, const char *bclk_invert, const char *fsync, const char *fsync_invert, int mclk_freq, int bclk_freq, int fsync_freq,