]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Topology: NHLT: Intel: SSP: Add support for blob format
authorSeppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Mon, 15 Apr 2024 10:26:51 +0000 (13:26 +0300)
committerJaroslav Kysela <perex@perex.cz>
Wed, 23 Oct 2024 11:01:07 +0000 (13:01 +0200)
This patch adds the 3.0 format that is used for the PTL
ACE3.x platform. Blob 3.0 is based on blob 1.5 but it adds
DMA control registers settings and has some changes in
registers bitfields.

This patch also fixes some compile warnings when NHLT_DEBUG is
set for comparing int with unsigned in ssp-debug.c for code for
all blobs variants.

Closes: https://github.com/alsa-project/alsa-utils/pull/276
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
topology/nhlt/intel/ssp/ssp-debug.c
topology/nhlt/intel/ssp/ssp-intel.h
topology/nhlt/intel/ssp/ssp-internal.h
topology/nhlt/intel/ssp/ssp-process.c

index 2d2f6b0fc5ab238019cbac3bb878c5da25f8925c..154c83a6add4cca21af2f22d296c8963d1fe1a50 100644 (file)
 
 #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];
 
index 9c924241b390715c4fd2eb6f5f3baea5c5ac29a7..ac141c8d3d88a63281cb8bed366b18954e1b84a6 100644 (file)
 
 #include <stdint.h>
 
+#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;
index 23a8489b6b5a129d85be82fc8770dee140204b9a..82815bc1dd073953c57999d1cff3181d77060a5c 100644 (file)
@@ -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];
 };
 
index 6a0e853187a2be966316a262aeae8d75cbf729fa..89202c2f80a1dd9cf1a307797ef4c6ba36a92033 100644 (file)
@@ -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