diff --git a/topology/nhlt/intel/ssp/ssp-debug.c b/topology/nhlt/intel/ssp/ssp-debug.c index 2d2f6b0..154c83a 100644 --- a/topology/nhlt/intel/ssp/ssp-debug.c +++ b/topology/nhlt/intel/ssp/ssp-debug.c @@ -13,14 +13,104 @@ #ifdef NHLT_DEBUG -void ssp_print_calculated(struct intel_ssp_params *ssp) +static void ssp_print_blob10(struct intel_ssp_params *ssp, int i) { struct ssp_intel_config_data *blob; + int ssp_index = ssp->ssp_count; + int j; + + blob = &ssp->ssp_blob[ssp_index][i]; + fprintf(stdout, "gateway_attributes %u\n", blob->gateway_attributes); + for (j = 0; j < SSP_TS_GROUP_SIZE; j++) + fprintf(stdout, "ts_group[%d] 0x%08x\n", j, blob->ts_group[j]); + + 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); +} + +static void ssp_print_blob15(struct intel_ssp_params *ssp, int i) +{ struct ssp_intel_config_data_1_5 *blob15; + int ssp_index = ssp->ssp_count; + uint32_t j; + + 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); + for (j = 0; j < SSP_TS_GROUP_SIZE; j++) + fprintf(stdout, "ts_group[%d] 0x%08x\n", j, blob15->ts_group[j]); + + 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]); +} + +static void ssp_print_blob30(struct intel_ssp_params *ssp, int i) +{ + struct ssp_intel_config_data_3_0 *blob30; + int ssp_index = ssp->ssp_count; + uint32_t j; + + blob30 = &ssp->ssp_blob_3_0[ssp_index][i]; + fprintf(stdout, "gateway_attributes %u\n", blob30->gateway_attributes); + fprintf(stdout, "version %u\n", blob30->version); + fprintf(stdout, "size %u\n", blob30->size); + for (j = 0; j < SSP_TS_GROUP_SIZE; j++) + fprintf(stdout, "ts_group[%d] 0x%08x\n", j, blob30->ts_group[j]); + + fprintf(stdout, "ssc0 0x%08x\n", blob30->ssc0); + fprintf(stdout, "ssc1 0x%08x\n", blob30->ssc1); + fprintf(stdout, "sscto 0x%08x\n", blob30->sscto); + fprintf(stdout, "sspsp 0x%08x\n", blob30->sspsp); + fprintf(stdout, "ssc2 0x%08x\n", blob30->ssc2); + fprintf(stdout, "sspsp2 0x%08x\n", blob30->sspsp2); + fprintf(stdout, "rsvd2 0x%08x\n", blob30->rsvd2); + fprintf(stdout, "ssioc 0x%08x\n", blob30->ssioc); + for (j = 0; j < I2SIPCMC; j++) { + fprintf(stdout, "rx_dir[%d] 0x%08x\n", j * 2, (uint32_t)(blob30->rx_dir[j].ssmidytsa & 0xffffffff)); + fprintf(stdout, "rx_dir[%d] 0x%08x\n", j * 2 + 1, (uint32_t)(blob30->rx_dir[j].ssmidytsa >> 32)); + } + for (j = 0; j < I2SOPCMC; j++) { + fprintf(stdout, "tx_dir[%d] 0x%08x\n", j * 2, (uint32_t)(blob30->tx_dir[j].ssmodytsa & 0xffffffff)); + fprintf(stdout, "tx_dir[%d] 0x%08x\n", j * 2 + 1, (uint32_t)(blob30->tx_dir[j].ssmodytsa >> 32)); + } + + fprintf(stdout, "mdivc 0x%08x\n", blob30->mdivctlr); + fprintf(stdout, "mdivr count 0x%08x\n", blob30->mdivrcnt); + for (j = 0; j < blob30->mdivrcnt; j++) + fprintf(stdout, "mdivr 0x%08x\n", + ssp->ssp_prm[ssp_index].mdivr[i].mdivrs[j]); +} + +void ssp_print_calculated(struct intel_ssp_params *ssp) +{ struct ssp_aux_blob *blob_aux; int ssp_index = ssp->ssp_count; uint32_t *ptr; - int i, j; + uint32_t i, j; fprintf(stdout, "printing ssp nhlt calculated data:\n"); @@ -38,58 +128,17 @@ void ssp_print_calculated(struct intel_ssp_params *ssp) for (i = 0; i < ssp->ssp_hw_config_count[ssp_index]; i++) { fprintf(stdout, "ssp blob %d hw_config %d\n", ssp->ssp_count, i); - 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); + switch (ssp->ssp_prm[ssp_index].version) { + case SSP_BLOB_VER_1_5: + ssp_print_blob15(ssp, i); + break; + case SSP_BLOB_VER_3_0: + ssp_print_blob30(ssp, i); + break; + default: + ssp_print_blob10(ssp, i); } + 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) { @@ -115,7 +164,7 @@ void ssp_print_internal(struct intel_ssp_params *ssp) struct ssp_config_dai *dai; struct ssp_config_hw *hw_conf; uint32_t enabled; - int i, j; + uint32_t i, j; dai = &ssp->ssp_prm[ssp->ssp_count]; diff --git a/topology/nhlt/intel/ssp/ssp-intel.h b/topology/nhlt/intel/ssp/ssp-intel.h index 9c92424..ac141c8 100644 --- a/topology/nhlt/intel/ssp/ssp-intel.h +++ b/topology/nhlt/intel/ssp/ssp-intel.h @@ -12,10 +12,12 @@ #include +#define SSP_TS_GROUP_SIZE 8 + /* struct for intel ssp nhlt vendor specific blob generation */ struct ssp_intel_config_data { uint32_t gateway_attributes; - uint32_t ts_group[8]; + uint32_t ts_group[SSP_TS_GROUP_SIZE]; uint32_t ssc0; uint32_t ssc1; uint32_t sscto; @@ -31,12 +33,13 @@ struct ssp_intel_config_data { } __attribute__((packed)); #define SSP_BLOB_VER_1_5 0xEE000105 +#define SSP_BLOB_VER_3_0 0xEE000300 struct ssp_intel_config_data_1_5 { uint32_t gateway_attributes; uint32_t version; uint32_t size; - uint32_t ts_group[8]; + uint32_t ts_group[SSP_TS_GROUP_SIZE]; uint32_t ssc0; uint32_t ssc1; uint32_t sscto; @@ -52,6 +55,37 @@ struct ssp_intel_config_data_1_5 { uint32_t mdivr[]; } __attribute__((packed)); +#define I2SIPCMC 8 +#define I2SOPCMC 8 + +struct ssp_rx_dir { + uint64_t ssmidytsa; +} __attribute__((packed)); + +struct ssp_tx_dir { + uint64_t ssmodytsa; +} __attribute__((packed)); + +struct ssp_intel_config_data_3_0 { + uint32_t gateway_attributes; + uint32_t version; + uint32_t size; + uint32_t ts_group[SSP_TS_GROUP_SIZE]; + uint32_t ssc0; + uint32_t ssc1; + uint32_t sscto; + uint32_t sspsp; + uint32_t ssc2; + uint32_t sspsp2; + uint32_t rsvd2; + uint32_t ssioc; + struct ssp_rx_dir rx_dir[I2SIPCMC]; + struct ssp_tx_dir tx_dir[I2SOPCMC]; + uint32_t mdivctlr; + uint32_t mdivrcnt; + uint32_t mdivr[]; +} __attribute__((packed)); + struct ssp_intel_aux_tlv { uint32_t type; uint32_t size; diff --git a/topology/nhlt/intel/ssp/ssp-internal.h b/topology/nhlt/intel/ssp/ssp-internal.h index 23a8489..82815bc 100644 --- a/topology/nhlt/intel/ssp/ssp-internal.h +++ b/topology/nhlt/intel/ssp/ssp-internal.h @@ -147,6 +147,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_intel_config_data_3_0 ssp_blob_3_0[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 6a0e853..89202c2 100644 --- a/topology/nhlt/intel/ssp/ssp-process.c +++ b/topology/nhlt/intel/ssp/ssp-process.c @@ -38,10 +38,51 @@ static int popcount(uint32_t value) return bits_set; } +static void ssp_calculate_intern_v30(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_3_0 *blob30 = &ssp->ssp_blob_3_0[di][hwi]; + struct ssp_intel_config_data *blob = &ssp->ssp_blob[di][hwi]; + int i; + + blob30->gateway_attributes = blob->gateway_attributes; + blob30->version = SSP_BLOB_VER_3_0; + for (i = 0; i < SSP_TS_GROUP_SIZE; i++) + blob30->ts_group[i] = blob->ts_group[i]; + + blob30->ssc0 = blob->ssc0; + blob30->ssc1 = blob->ssc1; + blob30->sscto = blob->sscto; + blob30->sspsp = blob->sspsp; + blob30->ssc2 = blob->ssc2; + blob30->sspsp2 = blob->sspsp2; + blob30->rsvd2 = 0; + blob30->ssioc = blob->ssioc; + + blob30->rx_dir[0].ssmidytsa = 3; + for (i = 1; i < I2SIPCMC; i++) + blob30->rx_dir[i].ssmidytsa = 0; + + blob30->tx_dir[0].ssmodytsa = 3; + for (i = 1; i < I2SOPCMC; i++) + blob30->tx_dir[i].ssmodytsa = 0; + + /* mdivr count is always 1 */ + blob30->mdivctlr = blob->mdivc; + ssp->ssp_prm[di].mdivr[hwi].count = 1; + blob30->mdivrcnt = ssp->ssp_prm[di].mdivr[hwi].count; + ssp->ssp_prm[di].mdivr[hwi].mdivrs[0] = blob->mdivr; + + blob30->size = sizeof(struct ssp_intel_config_data_3_0) + + blob30->mdivrcnt * sizeof(uint32_t) + + ssp->ssp_blob_ext[di][hwi].size; +} + 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;; + 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; @@ -49,7 +90,7 @@ static void ssp_calculate_intern_v15(struct intel_nhlt_params *nhlt, int hwi) blob15->gateway_attributes = ssp->ssp_blob[di][hwi].gateway_attributes; blob15->version = SSP_BLOB_VER_1_5; - for (i = 0; i < 8; i++) + for (i = 0; i < SSP_TS_GROUP_SIZE; i++) blob15->ts_group[i] = blob->ts_group[i]; blob15->ssc0 = blob->ssc0; @@ -748,6 +789,9 @@ int ssp_calculate(struct intel_nhlt_params *nhlt) return -EINVAL; /* v15 blob is made from legacy blob, so it can't fail */ ssp_calculate_intern_v15(nhlt, i); + + /* v30 blob is made from legacy blob, so it can't fail */ + ssp_calculate_intern_v30(nhlt, i); } ssp_print_internal(ssp); @@ -826,6 +870,8 @@ int ssp_get_vendor_blob_size(struct intel_nhlt_params *nhlt, int dai_index, /* 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 if (ssp->ssp_prm[dai_index].version == SSP_BLOB_VER_3_0) + *size = ssp->ssp_blob_3_0[dai_index][hw_config_index].size; else /* legacy */ *size = sizeof(struct ssp_intel_config_data) + @@ -867,8 +913,19 @@ int ssp_get_vendor_blob(struct intel_nhlt_params *nhlt, uint8_t *vendor_blob, 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 { + } else if (ssp->ssp_prm[dai_index].version == SSP_BLOB_VER_3_0) { + basic_len = sizeof(struct ssp_intel_config_data_3_0); + clock_len = sizeof(uint32_t) * ssp->ssp_prm[dai_index].mdivr[hw_config_index].count; + /* basic data */ + memcpy(vendor_blob, &ssp->ssp_blob_3_0[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); @@ -914,6 +971,9 @@ int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_inde /* 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; + else if (version == (SSP_BLOB_VER_3_0 & ((1 << 16) - 1))) + ssp->ssp_prm[ssp->ssp_count].version = SSP_BLOB_VER_3_0; + if (tdm_padding_per_slot && !strcmp(tdm_padding_per_slot, "true")) ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 1; else