This commit is contained in:
Seppo Ingalsuo 2024-09-19 16:39:34 +03:00 committed by GitHub
commit a02ab41e09
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 240 additions and 62 deletions

View file

@ -13,14 +13,118 @@
#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;
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);
}
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);
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]);
}
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);
fprintf(stdout, "ts_group[0] 0x%08x\n", blob30->ts_group[0]);
fprintf(stdout, "ts_group[1] 0x%08x\n", blob30->ts_group[1]);
fprintf(stdout, "ts_group[2] 0x%08x\n", blob30->ts_group[2]);
fprintf(stdout, "ts_group[3] 0x%08x\n", blob30->ts_group[3]);
fprintf(stdout, "ts_group[4] 0x%08x\n", blob30->ts_group[4]);
fprintf(stdout, "ts_group[5] 0x%08x\n", blob30->ts_group[5]);
fprintf(stdout, "ts_group[6] 0x%08x\n", blob30->ts_group[6]);
fprintf(stdout, "ts_group[7] 0x%08x\n", blob30->ts_group[7]);
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 +142,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 +178,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];

View file

@ -31,6 +31,7 @@ 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;
@ -52,6 +53,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[8];
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;

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

View file

@ -38,6 +38,47 @@ 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 < 8; 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;
@ -115,11 +156,17 @@ static int ssp_calculate_intern(struct intel_nhlt_params *nhlt, int hwi)
/* reset SSP settings */
/* sscr0 dynamic settings are DSS, EDSS, SCR, FRDC, ECS */
ssp->ssp_blob[di][hwi].ssc0 = SSCR0_PSP | SSCR0_RIM | SSCR0_TIM;
ssp->ssp_blob[di][hwi].ssc0 = SSCR0_MOD | SSCR0_PSP | SSCR0_RIM | SSCR0_TIM;
/* sscr1 dynamic settings are SFRMDIR, SCLKDIR, SCFR */
ssp->ssp_blob[di][hwi].ssc1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_TRAIL | SSCR1_RSRE |
SSCR1_TSRE;
if (ssp->ssp_prm[di].version == SSP_BLOB_VER_3_0)
/* bits 21 and 20, TSRE and RSRE do not exist in ACE3.x
* Note: Assuming SSP_BLOB_VER_3_0 is ACE3.x
*/
ssp->ssp_blob[di][hwi].ssc1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_TRAIL;
else
ssp->ssp_blob[di][hwi].ssc1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_TRAIL |
SSCR1_RSRE | SSCR1_TSRE;
/* sscr2 dynamic setting is LJDFD */
ssp->ssp_blob[di][hwi].ssc2 = SSCR2_SDFD | SSCR2_TURM1;
@ -197,7 +244,13 @@ static int ssp_calculate_intern(struct intel_nhlt_params *nhlt, int hwi)
ssp->ssp_blob[di][hwi].sspsp |= SSPSP_SCMODE(inverted_bclk);
}
ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_MOD | SSCR0_ACS;
/* Note: ACS as SSCR0(30) does not exist in any ACE version, or cAVS2.x. This disables
* it for ACE3.x. It might be good to fix later for other platforms. In cAVS this is 30:29
* reserved, in ACE1.x this is DLE as 30:29, in ACE2.x this is RSVD30 as 30:29, in ACE3.x this
* is DLE as 30:29.
*/
if (ssp->ssp_prm[di].version != SSP_BLOB_VER_3_0)
ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_ACS;
/* Additional hardware settings */
@ -538,13 +591,23 @@ static int ssp_calculate_intern(struct intel_nhlt_params *nhlt, int hwi)
ssp->ssp_blob[di][hwi].mdivr = clk_div;
/* clock will always go through the divider */
/* Note: There is no SSC0(6) ECS in ACE3.x but RSVD6 in same bit position
* that must be set to one.
*/
ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_ECS;
/* enable divider for this clock id */
ssp->ssp_blob[di][hwi].mdivc |= BIT(ssp->ssp_prm[di].mclk_id);
/* set mclk source always for audio cardinal clock */
ssp->ssp_blob[di][hwi].mdivc |= MCDSS(SSP_CLOCK_AUDIO_CARDINAL);
/* set bclk source for audio cardinal clock */
ssp->ssp_blob[di][hwi].mdivc |= MNDSS(SSP_CLOCK_AUDIO_CARDINAL);
/* set bclk source for audio cardinal clock
* Note: There is no MDIVXCTRL(21:20) MNDSS in any ACE version 1.x - 3.x. MNDSS
* exists in cAVS2.x. This removes the set for ACE3.x. May need to address other
* ACE platforms later.
*/
if (ssp->ssp_prm[di].version != SSP_BLOB_VER_3_0)
ssp->ssp_blob[di][hwi].mdivc |= MNDSS(SSP_CLOCK_AUDIO_CARDINAL);
return 0;
}
@ -748,6 +811,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 +892,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 +935,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 +993,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