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 <jaska.uimonen@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaska Uimonen 2022-12-16 18:25:35 +02:00 committed by Jaroslav Kysela
parent 1ad140f641
commit df3da091cc
5 changed files with 148 additions and 35 deletions

View file

@ -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 */

View file

@ -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");

View file

@ -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];
};

View file

@ -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

View file

@ -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,