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,