diff --git a/dsp/q6afe.c b/dsp/q6afe.c index da8dc5a8033a..cbd87863f86b 100644 --- a/dsp/q6afe.c +++ b/dsp/q6afe.c @@ -3442,15 +3442,21 @@ exit: static int q6afe_send_dec_config(u16 port_id, union afe_port_config afe_config, - struct afe_dec_config *cfg) + struct afe_dec_config *cfg, + u32 format, + u16 afe_in_channels, u16 afe_in_bit_width) { + struct afe_dec_media_fmt_t dec_media_fmt; struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; + struct avs_dec_congestion_buffer_param_t dec_buffer_id_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_port_media_type_t media_type; struct param_hdr_v3 param_hdr; int ret; + u32 dec_fmt; memset(&dec_depkt_id_param, 0, sizeof(dec_depkt_id_param)); + memset(&dec_media_fmt, 0, sizeof(dec_media_fmt)); memset(&imc_info_param, 0, sizeof(imc_info_param)); memset(&media_type, 0, sizeof(media_type)); memset(¶m_hdr, 0, sizeof(param_hdr)); @@ -3463,10 +3469,10 @@ static int q6afe_send_dec_config(u16 port_id, param_hdr.param_id = AFE_DECODER_PARAM_ID_DEPACKETIZER_ID; param_hdr.param_size = sizeof(struct avs_dec_depacketizer_id_param_t); dec_depkt_id_param.dec_depacketizer_id = - AFE_MODULE_ID_DEPACKETIZER_COP; - if (cfg->format == ASM_MEDIA_FMT_APTX_ADAPTIVE) - dec_depkt_id_param.dec_depacketizer_id = AFE_MODULE_ID_DEPACKETIZER_COP_V1; + if (cfg->format == ENC_CODEC_TYPE_LDAC) + dec_depkt_id_param.dec_depacketizer_id = + AFE_MODULE_ID_DEPACKETIZER_COP; ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, @@ -3477,19 +3483,52 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } - pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", - __func__); - param_hdr.param_id = AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; - param_hdr.param_size = sizeof(struct afe_enc_dec_imc_info_param_t); - imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info; - ret = q6afe_pack_and_set_param_in_band(port_id, - q6audio_get_port_index(port_id), - param_hdr, - (u8 *) &imc_info_param); - if (ret) { - pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", - __func__, port_id, ret); - goto exit; + switch (cfg->format) { + case ASM_MEDIA_FMT_SBC: + case ASM_MEDIA_FMT_AAC_V2: + case ASM_MEDIA_FMT_MP3: + if (port_id == SLIMBUS_9_TX) { + dec_buffer_id_param.max_nr_buffers = 200; + dec_buffer_id_param.pre_buffer_size = 200; + } else { + dec_buffer_id_param.max_nr_buffers = 0; + dec_buffer_id_param.pre_buffer_size = 0; + } + pr_debug("%s: sending AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE to DSP payload\n", + __func__); + param_hdr.param_id = + AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE; + param_hdr.param_size = + sizeof(struct avs_dec_congestion_buffer_param_t); + dec_buffer_id_param.version = 0; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &dec_buffer_id_param); + if (ret) { + pr_err("%s: AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; + default: + pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n", + __func__); + param_hdr.param_id = + AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION; + param_hdr.param_size = + sizeof(struct afe_enc_dec_imc_info_param_t); + imc_info_param.imc_info = cfg->abr_dec_cfg.imc_info; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &imc_info_param); + if (ret) { + pr_err("%s: AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; } pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); @@ -3497,9 +3536,24 @@ static int q6afe_send_dec_config(u16 port_id, param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; param_hdr.param_size = sizeof(struct afe_port_media_type_t); media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; - media_type.sample_rate = afe_config.slim_sch.sample_rate; - media_type.bit_width = afe_config.slim_sch.bit_width; - media_type.num_channels = afe_config.slim_sch.num_channels; + switch (cfg->format) { + case ASM_MEDIA_FMT_AAC_V2: + media_type.sample_rate = + cfg->data.aac_config.sample_rate; + break; + default: + media_type.sample_rate = + afe_config.slim_sch.sample_rate; + } + if (afe_in_bit_width) + media_type.bit_width = afe_in_bit_width; + else + media_type.bit_width = afe_config.slim_sch.bit_width; + + if (afe_in_channels) + media_type.num_channels = afe_in_channels; + else + media_type.num_channels = afe_config.slim_sch.num_channels; media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; media_type.reserved = 0; @@ -3512,6 +3566,50 @@ static int q6afe_send_dec_config(u16 port_id, goto exit; } + if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2) { + pr_debug("%s:Unsuppported dec format. Ignore AFE config %u\n", + __func__, format); + goto exit; + } + pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n", + __func__); + param_hdr.module_id = AFE_MODULE_ID_DECODER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_DECODER_PARAM_ID_DEC_FMT_ID; + param_hdr.param_size = sizeof(dec_fmt); + dec_fmt = format; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &dec_fmt); + if (ret) { + pr_err("%s: AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + + switch (cfg->format) { + case ASM_MEDIA_FMT_AAC_V2: + param_hdr.param_size = sizeof(struct afe_dec_media_fmt_t); + + pr_debug("%s:send AFE_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n", + __func__); + param_hdr.param_id = AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT; + dec_media_fmt.dec_media_config = cfg->data; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &dec_media_fmt); + if (ret) { + pr_err("%s: AFE_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n", + __func__, port_id, ret); + goto exit; + } + break; + default: + pr_debug("%s:No need to send DEC_MEDIA_FMT to DSP payload\n", + __func__); + } + exit: return ret; } @@ -3550,7 +3648,8 @@ static int q6afe_send_enc_config(u16 port_id, format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD && format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC && format != ASM_MEDIA_FMT_APTX_ADAPTIVE) { - pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); + pr_err("%s:Unsuppported enc format. Ignore AFE config\n", + __func__); return 0; } @@ -3582,7 +3681,7 @@ static int q6afe_send_enc_config(u16 port_id, enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); } - pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn", + pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload\n", __func__); param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; enc_blk_param.enc_blk_config = *cfg; @@ -4064,7 +4163,9 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, pr_debug("%s: Found AFE decoder support for SLIMBUS format = %d\n", __func__, codec_format); ret = q6afe_send_dec_config(port_id, *afe_config, - dec_cfg); + dec_cfg, codec_format, + afe_in_channels, + afe_in_bit_width); if (ret) { pr_err("%s: AFE decoder config for port 0x%x failed %d\n", __func__, port_id, ret); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index ddcc101a3215..eb529dc1e8e6 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -3875,6 +3875,12 @@ struct afe_id_aptx_adaptive_enc_init */ #define AFE_ENCODER_PARAM_ID_ENC_FMT_ID 0x0001322B +/* + * Decoder format ID parameter for the #AVS_MODULE_ID_DECODER module. + * This parameter cannot be set runtime. + */ +#define AFE_DECODER_PARAM_ID_DEC_FMT_ID 0x00013234 + /* * Encoder scrambler parameter for the #AVS_MODULE_ID_ENCODER module. * This parameter cannot be set runtime. @@ -3915,6 +3921,12 @@ struct afe_id_aptx_adaptive_enc_init */ #define AFE_DECODER_PARAM_ID_DEPACKETIZER_ID 0x00013235 +/* + * Decoder buffer ID parameter for the #AVS_MODULE_ID_DECODER module. + * This parameter cannot be set runtime. + */ +#define AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE 0x000132ec + /* * Data format to send compressed data * is transmitted/received over Slimbus lines. @@ -4185,6 +4197,7 @@ struct asm_celt_enc_cfg_t { } __packed; #define ASM_MEDIA_FMT_LDAC 0x00013224 +#define ENC_CODEC_TYPE_LDAC 0x23000000 struct asm_ldac_specific_enc_cfg_t { /* * This is used to calculate the encoder output @@ -4293,6 +4306,98 @@ struct afe_port_media_type_t { uint16_t reserved; } __packed; +/* + * Payload of the SBC decoder configuration parameters in the + * #ASM_MEDIA_FMT_SBC media format. + */ +struct asm_sbc_dec_cfg_t { + /* All configuration is extracted from the stream */ +} __packed; + +/* + * Payload of the MP3 decoder configuration parameters in the + * #ASM_MEDIA_FMT_MP3 media format. + */ +struct asm_mp3_dec_cfg_t { + /* All configuration is extracted from the stream */ +} __packed; + +struct asm_aac_dec_cfg_v2_t { + uint16_t aac_fmt_flag; + /* + * Bit stream format option. + * + * @values + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADTS + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_LOAS + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_ADIF + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_RAW + * - #ASM_MEDIA_FMT_AAC_FORMAT_FLAG_LATM + */ + + uint16_t audio_obj_type; + /* + * Audio Object Type (AOT) present in the AAC stream. + * + * @values + * - #ASM_MEDIA_FMT_AAC_AOT_LC + * - #ASM_MEDIA_FMT_AAC_AOT_SBR + * - #ASM_MEDIA_FMT_AAC_AOT_BSAC + * - #ASM_MEDIA_FMT_AAC_AOT_PS + * + * Other values are not supported. + */ + + uint16_t channel_config; + /* + * Number of channels present in the AAC stream. + * + * @values + * - 0 -- PCE + * - 1 -- Mono + * - 2 -- Stereo + * - 6 -- 5.1 content + */ + + uint16_t total_size_of_PCE_bits; + /* + * For RAW formats and if channel_config=0 (PCE), + * the client can send the bit stream containing PCE + * immediately following this structure (in band). + * + * @values @ge 0 (does not include the bits required + * for 32-bit alignment) + * + * If this field is set to 0, the PCE information is + * assumed to be available in the audio bit stream + * and not in band. + * + * If this field is greater than 0, the PCE information + * follows this structure. Additional bits might + * be required for 32-bit alignment. + */ + + uint32_t sample_rate; + /* + * Number of samples per second. + * + * @values 8000, 11025, 12000, 16000, 22050, 24000, 32000, + * 44100, 48000, 64000, 88200, 96000 Hz + * + * This field must be equal to the sample rate of the + * AAC-LC decoder output. + * - For MP4 or 3GP containers, this sample rate + * is indicated by the + * samplingFrequencyIndex field in the + * AudioSpecificConfig element. + * - For ADTS format, this sample rate is indicated by the + * samplingFrequencyIndex in the ADTS fixed header. + * - For ADIF format, this sample rate is indicated by the + * samplingFrequencyIndex in the program_config_element + * present in the ADIF header. + */ +} __packed; + union afe_enc_config_data { struct asm_sbc_enc_cfg_t sbc_config; struct asm_aac_enc_cfg_v2_t aac_config; @@ -4309,9 +4414,16 @@ struct afe_enc_config { union afe_enc_config_data data; }; +union afe_dec_config_data { + struct asm_sbc_dec_cfg_t sbc_config; + struct asm_aac_dec_cfg_v2_t aac_config; + struct asm_mp3_dec_cfg_t mp3_config; +}; + struct afe_dec_config { u32 format; struct afe_abr_dec_cfg_t abr_dec_cfg; + union afe_dec_config_data data; }; struct afe_enc_cfg_blk_param_t { @@ -4322,6 +4434,14 @@ struct afe_enc_cfg_blk_param_t { union afe_enc_config_data enc_blk_config; }; +/* + * Payload of the AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT parameter used by + * AVS_MODULE_ID_DECODER. + */ +struct afe_dec_media_fmt_t { + union afe_dec_config_data dec_media_config; +} __packed; + /* * Payload of the AVS_ENCODER_PARAM_ID_PACKETIZER_ID parameter. */ @@ -4373,12 +4493,34 @@ struct afe_enc_dec_imc_info_param_t { struct avs_dec_depacketizer_id_param_t { /* * Supported values: - * #AVS_MODULE_ID_DEPACKETIZER_COP + * #AFE_MODULE_ID_DEPACKETIZER_COP + * #AFE_MODULE_ID_DEPACKETIZER_COP_V1 * Any OpenDSP supported values */ uint32_t dec_depacketizer_id; }; +struct avs_dec_congestion_buffer_param_t { + uint32_t version; + uint16_t max_nr_buffers; + /* + * Maximum number of 1ms buffers: + * 0 - 256 + */ + uint16_t pre_buffer_size; + /* + * Pre-buffering size in 1ms: + * 1 - 128 + */ +}; + +/* + * ID of the parameter used by #AVS_MODULE_ID_DECODER to configure + * the decoder mode for the AFE module. + * This parameter cannot be set at runtime. + */ +#define AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT 0x00013232 + /* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure * the island mode for a given AFE port. */ @@ -4492,6 +4634,7 @@ union afe_port_config { struct avs_enc_packetizer_id_param_t enc_pkt_id_param; struct avs_enc_set_scrambler_param_t enc_set_scrambler_param; struct avs_dec_depacketizer_id_param_t dec_depkt_id_param; + struct afe_dec_media_fmt_t dec_media_fmt; struct afe_enc_level_to_bitrate_map_param_t map_param; struct afe_enc_dec_imc_info_param_t imc_info_param; struct afe_param_id_cdc_dma_cfg_t cdc_dma;