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,20 @@ struct ipc4_modules_info {
3741 struct sof_man_module modules [0 ];
3842} __packed __aligned (4 );
3943
44+ struct ipc4_uaol_link_capabilities {
45+ uint32_t input_streams_supported : 4 ;
46+ uint32_t output_streams_supported : 4 ;
47+ uint32_t bidirectional_streams_supported : 5 ;
48+ uint32_t rsvd : 19 ;
49+ uint32_t max_tx_fifo_size ;
50+ uint32_t max_rx_fifo_size ;
51+ } __packed __aligned (4 );
52+
53+ struct ipc4_uaol_capabilities {
54+ uint32_t link_count ;
55+ struct ipc4_uaol_link_capabilities link_caps [];
56+ } __packed __aligned (4 );
57+
4058/*
4159 * TODO: default to value of ACE1.x platforms. This is defined
4260 * in multiple places in Zephyr, mm_drv_intel_adsp.h and
@@ -67,7 +85,7 @@ __cold int basefw_vendor_fw_config(uint32_t *data_offset, char *data)
6785 tlv_value_uint32_set (tuple , IPC4_SLOW_CLOCK_FREQ_HZ_FW_CFG , IPC4_ALH_CAVS_1_8 );
6886
6987 tuple = tlv_next (tuple );
70- tlv_value_uint32_set (tuple , IPC4_UAOL_SUPPORT , 0 );
88+ tlv_value_uint32_set (tuple , IPC4_UAOL_SUPPORT , IS_ENABLED ( CONFIG_UAOL_INTEL_ADSP ) );
7189
7290 tuple = tlv_next (tuple );
7391 tlv_value_uint32_set (tuple , IPC4_ALH_SUPPORT_LEVEL_FW_CFG , IPC4_ALH_CAVS_1_8 );
@@ -78,6 +96,57 @@ __cold int basefw_vendor_fw_config(uint32_t *data_offset, char *data)
7896 return 0 ;
7997}
8098
99+ #if CONFIG_UAOL_INTEL_ADSP
100+
101+ #define UAOL_DEV (node ) DEVICE_DT_GET(node),
102+ static const struct device * uaol_devs [] = {
103+ DT_FOREACH_STATUS_OKAY (intel_adsp_uaol , UAOL_DEV )
104+ };
105+
106+ static void tlv_value_set_uaol_caps (struct sof_tlv * tuple , uint32_t type )
107+ {
108+ const unsigned int dev_count = ARRAY_SIZE (uaol_devs );
109+ struct uaol_capabilities dev_cap ;
110+ struct ipc4_uaol_capabilities * caps = (struct ipc4_uaol_capabilities * )tuple -> value ;
111+ size_t caps_size = offsetof(struct ipc4_uaol_capabilities , link_caps [dev_count ]);
112+ unsigned int i ;
113+ int ret ;
114+
115+ memset (caps , 0 , caps_size );
116+
117+ caps -> link_count = dev_count ;
118+ for (i = 0 ; i < dev_count ; i ++ ) {
119+ ret = uaol_get_capabilities (uaol_devs [i ], & dev_cap );
120+ if (ret )
121+ continue ;
122+
123+ caps -> link_caps [i ].input_streams_supported = dev_cap .input_streams ;
124+ caps -> link_caps [i ].output_streams_supported = dev_cap .output_streams ;
125+ caps -> link_caps [i ].bidirectional_streams_supported = dev_cap .bidirectional_streams ;
126+ caps -> link_caps [i ].max_tx_fifo_size = dev_cap .max_tx_fifo_size ;
127+ caps -> link_caps [i ].max_rx_fifo_size = dev_cap .max_rx_fifo_size ;
128+ }
129+
130+ tlv_value_set (tuple , type , caps_size , caps );
131+ }
132+
133+ static int uaol_stream_id_to_hda_link_stream_id (int uaol_stream_id )
134+ {
135+ size_t dev_count = ARRAY_SIZE (uaol_devs );
136+ size_t i ;
137+
138+ for (i = 0 ; i < dev_count ; i ++ ) {
139+ int hda_link_stream_id = uaol_get_mapped_hda_link_stream_id (uaol_devs [i ],
140+ uaol_stream_id );
141+ if (hda_link_stream_id >= 0 )
142+ return hda_link_stream_id ;
143+ }
144+
145+ return -1 ;
146+ }
147+
148+ #endif
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