2323
2424#include <sof/lib/memory.h>
2525
26+ #if CONFIG_UAOL_INTEL_ADSP
27+ #include <zephyr/drivers/uaol.h>
28+ #endif
29+
2630#include <ipc4/base_fw.h>
2731#include <ipc4/alh.h>
2832#include <rimage/sof/user/manifest.h>
@@ -37,6 +41,22 @@ struct ipc4_modules_info {
3741 struct sof_man_module modules [0 ];
3842} __packed __aligned (4 );
3943
44+ #if CONFIG_UAOL_INTEL_ADSP
45+ struct ipc4_uaol_link_capabilities {
46+ uint32_t input_streams_supported : 4 ;
47+ uint32_t output_streams_supported : 4 ;
48+ uint32_t bidirectional_streams_supported : 5 ;
49+ uint32_t rsvd : 19 ;
50+ uint32_t max_tx_fifo_size ;
51+ uint32_t max_rx_fifo_size ;
52+ } __packed __aligned (4 );
53+
54+ struct ipc4_uaol_capabilities {
55+ uint32_t link_count ;
56+ struct ipc4_uaol_link_capabilities link_caps [];
57+ } __packed __aligned (4 );
58+ #endif /* CONFIG_UAOL_INTEL_ADSP */
59+
4060/*
4161 * TODO: default to value of ACE1.x platforms. This is defined
4262 * in multiple places in Zephyr, mm_drv_intel_adsp.h and
@@ -67,7 +87,7 @@ __cold int basefw_vendor_fw_config(uint32_t *data_offset, char *data)
6787 tlv_value_uint32_set (tuple , IPC4_SLOW_CLOCK_FREQ_HZ_FW_CFG , IPC4_ALH_CAVS_1_8 );
6888
6989 tuple = tlv_next (tuple );
70- tlv_value_uint32_set (tuple , IPC4_UAOL_SUPPORT , 0 );
90+ tlv_value_uint32_set (tuple , IPC4_UAOL_SUPPORT , IS_ENABLED ( CONFIG_UAOL_INTEL_ADSP ) );
7191
7292 tuple = tlv_next (tuple );
7393 tlv_value_uint32_set (tuple , IPC4_ALH_SUPPORT_LEVEL_FW_CFG , IPC4_ALH_CAVS_1_8 );
@@ -78,6 +98,55 @@ __cold int basefw_vendor_fw_config(uint32_t *data_offset, char *data)
7898 return 0 ;
7999}
80100
101+ #if CONFIG_UAOL_INTEL_ADSP
102+ #define DEV_AND_COMMA (node ) DEVICE_DT_GET(node),
103+ static const struct device * uaol_devs [] = {
104+ DT_FOREACH_STATUS_OKAY (intel_adsp_uaol , DEV_AND_COMMA )
105+ };
106+
107+ static void tlv_value_set_uaol_caps (struct sof_tlv * tuple , uint32_t type )
108+ {
109+ const size_t dev_count = ARRAY_SIZE (uaol_devs );
110+ struct uaol_capabilities dev_cap ;
111+ struct ipc4_uaol_capabilities * caps = (struct ipc4_uaol_capabilities * )tuple -> value ;
112+ size_t caps_size = offsetof(struct ipc4_uaol_capabilities , link_caps [dev_count ]);
113+ size_t i ;
114+ int ret ;
115+
116+ memset (caps , 0 , caps_size );
117+
118+ caps -> link_count = dev_count ;
119+ for (i = 0 ; i < dev_count ; i ++ ) {
120+ ret = uaol_get_capabilities (uaol_devs [i ], & dev_cap );
121+ if (ret )
122+ continue ;
123+
124+ caps -> link_caps [i ].input_streams_supported = dev_cap .input_streams ;
125+ caps -> link_caps [i ].output_streams_supported = dev_cap .output_streams ;
126+ caps -> link_caps [i ].bidirectional_streams_supported = dev_cap .bidirectional_streams ;
127+ caps -> link_caps [i ].max_tx_fifo_size = dev_cap .max_tx_fifo_size ;
128+ caps -> link_caps [i ].max_rx_fifo_size = dev_cap .max_rx_fifo_size ;
129+ }
130+
131+ tlv_value_set (tuple , type , caps_size , caps );
132+ }
133+
134+ static int uaol_stream_id_to_hda_link_stream_id (int uaol_stream_id )
135+ {
136+ size_t dev_count = ARRAY_SIZE (uaol_devs );
137+ size_t i ;
138+
139+ for (i = 0 ; i < dev_count ; i ++ ) {
140+ int hda_link_stream_id = uaol_get_mapped_hda_link_stream_id (uaol_devs [i ],
141+ uaol_stream_id );
142+ if (hda_link_stream_id >= 0 )
143+ return hda_link_stream_id ;
144+ }
145+
146+ return -1 ;
147+ }
148+ #endif /* CONFIG_UAOL_INTEL_ADSP */
149+
81150__cold int basefw_vendor_hw_config (uint32_t * data_offset , char * data )
82151{
83152 struct sof_tlv * tuple = (struct sof_tlv * )data ;
@@ -120,6 +189,11 @@ __cold int basefw_vendor_hw_config(uint32_t *data_offset, char *data)
120189 tlv_value_set (tuple , IPC4_INTEL_MIC_PRIVACY_CAPS_HW_CFG , sizeof (priv_caps ), & priv_caps );
121190#endif
122191
192+ #if CONFIG_UAOL_INTEL_ADSP
193+ tuple = tlv_next (tuple );
194+ tlv_value_set_uaol_caps (tuple , IPC4_UAOL_CAPS_HW_CFG );
195+ #endif
196+
123197 tuple = tlv_next (tuple );
124198 * data_offset = (int )((char * )tuple - data );
125199
@@ -421,6 +495,7 @@ __cold int basefw_vendor_set_large_config(struct comp_dev *dev, uint32_t param_i
421495__cold int basefw_vendor_dma_control (uint32_t node_id , const char * config_data , size_t data_size )
422496{
423497 union ipc4_connector_node_id node = (union ipc4_connector_node_id )node_id ;
498+ int dai_index = node .f .v_index ;
424499 int ret , result ;
425500 enum sof_ipc_dai_type type ;
426501
@@ -444,11 +519,25 @@ __cold int basefw_vendor_dma_control(uint32_t node_id, const char *config_data,
444519 case ipc4_i2s_link_input_class :
445520 type = SOF_DAI_INTEL_SSP ;
446521 break ;
522+
523+ #if CONFIG_UAOL_INTEL_ADSP
524+ case ipc4_alh_uaol_stream_link_output_class :
525+ case ipc4_alh_uaol_stream_link_input_class :
526+ type = SOF_DAI_INTEL_UAOL ;
527+ dai_index = uaol_stream_id_to_hda_link_stream_id (node .f .v_index );
528+ if (dai_index < 0 ) {
529+ tr_err (& basefw_comp_tr ,
530+ "HDA link stream not found! UAOL node ID: 0x%x" , node_id );
531+ return IPC4_INVALID_RESOURCE_ID ;
532+ }
533+ break ;
534+ #endif
535+
447536 default :
448537 return IPC4_INVALID_RESOURCE_ID ;
449538 }
450539
451- const struct device * dev = dai_get_device (type , node . f . v_index );
540+ const struct device * dev = dai_get_device (type , dai_index );
452541
453542 if (!dev ) {
454543 tr_err (& basefw_comp_tr ,
0 commit comments