2424#include <sof/lib/memory.h>
2525#include <sof/lib_manager.h>
2626
27+ #if CONFIG_UAOL_INTEL_ADSP
28+ #include <zephyr/drivers/uaol.h>
29+ #endif
30+
2731#include <ipc4/base_fw.h>
2832#include <ipc4/alh.h>
2933#include <rimage/sof/user/manifest.h>
@@ -41,6 +45,23 @@ struct ipc4_modules_info {
4145/* Sanity check because a subtraction of those sizes is performed later on */
4246STATIC_ASSERT (sizeof (struct ipc4_modules_info ) < SOF_IPC_MSG_MAX_SIZE ,
4347 invalid_modules_info_struct_size );
48+
49+ #if CONFIG_UAOL_INTEL_ADSP
50+ struct ipc4_uaol_link_capabilities {
51+ uint32_t input_streams_supported : 4 ;
52+ uint32_t output_streams_supported : 4 ;
53+ uint32_t bidirectional_streams_supported : 5 ;
54+ uint32_t rsvd : 19 ;
55+ uint32_t max_tx_fifo_size ;
56+ uint32_t max_rx_fifo_size ;
57+ } __packed __aligned (4 );
58+
59+ struct ipc4_uaol_capabilities {
60+ uint32_t link_count ;
61+ struct ipc4_uaol_link_capabilities link_caps [];
62+ } __packed __aligned (4 );
63+ #endif /* CONFIG_UAOL_INTEL_ADSP */
64+
4465/*
4566 * TODO: default to value of ACE1.x platforms. This is defined
4667 * in multiple places in Zephyr, mm_drv_intel_adsp.h and
@@ -71,7 +92,7 @@ __cold int basefw_vendor_fw_config(uint32_t *data_offset, char *data)
7192 tlv_value_uint32_set (tuple , IPC4_SLOW_CLOCK_FREQ_HZ_FW_CFG , IPC4_ALH_CAVS_1_8 );
7293
7394 tuple = tlv_next (tuple );
74- tlv_value_uint32_set (tuple , IPC4_UAOL_SUPPORT , 0 );
95+ tlv_value_uint32_set (tuple , IPC4_UAOL_SUPPORT , IS_ENABLED ( CONFIG_UAOL_INTEL_ADSP ) );
7596
7697 tuple = tlv_next (tuple );
7798 tlv_value_uint32_set (tuple , IPC4_ALH_SUPPORT_LEVEL_FW_CFG , IPC4_ALH_CAVS_1_8 );
@@ -82,6 +103,55 @@ __cold int basefw_vendor_fw_config(uint32_t *data_offset, char *data)
82103 return 0 ;
83104}
84105
106+ #if CONFIG_UAOL_INTEL_ADSP
107+ #define DEV_AND_COMMA (node ) DEVICE_DT_GET(node),
108+ static const struct device * uaol_devs [] = {
109+ DT_FOREACH_STATUS_OKAY (intel_adsp_uaol , DEV_AND_COMMA )
110+ };
111+
112+ static void tlv_value_set_uaol_caps (struct sof_tlv * tuple , uint32_t type )
113+ {
114+ const size_t dev_count = ARRAY_SIZE (uaol_devs );
115+ struct uaol_capabilities dev_cap ;
116+ struct ipc4_uaol_capabilities * caps = (struct ipc4_uaol_capabilities * )tuple -> value ;
117+ size_t caps_size = offsetof(struct ipc4_uaol_capabilities , link_caps [dev_count ]);
118+ size_t i ;
119+ int ret ;
120+
121+ memset (caps , 0 , caps_size );
122+
123+ caps -> link_count = dev_count ;
124+ for (i = 0 ; i < dev_count ; i ++ ) {
125+ ret = uaol_get_capabilities (uaol_devs [i ], & dev_cap );
126+ if (ret )
127+ continue ;
128+
129+ caps -> link_caps [i ].input_streams_supported = dev_cap .input_streams ;
130+ caps -> link_caps [i ].output_streams_supported = dev_cap .output_streams ;
131+ caps -> link_caps [i ].bidirectional_streams_supported = dev_cap .bidirectional_streams ;
132+ caps -> link_caps [i ].max_tx_fifo_size = dev_cap .max_tx_fifo_size ;
133+ caps -> link_caps [i ].max_rx_fifo_size = dev_cap .max_rx_fifo_size ;
134+ }
135+
136+ tlv_value_set (tuple , type , caps_size , caps );
137+ }
138+
139+ static int uaol_stream_id_to_hda_link_stream_id (int uaol_stream_id )
140+ {
141+ size_t dev_count = ARRAY_SIZE (uaol_devs );
142+ size_t i ;
143+
144+ for (i = 0 ; i < dev_count ; i ++ ) {
145+ int hda_link_stream_id = uaol_get_mapped_hda_link_stream_id (uaol_devs [i ],
146+ uaol_stream_id );
147+ if (hda_link_stream_id >= 0 )
148+ return hda_link_stream_id ;
149+ }
150+
151+ return -1 ;
152+ }
153+ #endif /* CONFIG_UAOL_INTEL_ADSP */
154+
85155__cold int basefw_vendor_hw_config (uint32_t * data_offset , char * data )
86156{
87157 struct sof_tlv * tuple = (struct sof_tlv * )data ;
@@ -124,6 +194,11 @@ __cold int basefw_vendor_hw_config(uint32_t *data_offset, char *data)
124194 tlv_value_set (tuple , IPC4_INTEL_MIC_PRIVACY_CAPS_HW_CFG , sizeof (priv_caps ), & priv_caps );
125195#endif
126196
197+ #if CONFIG_UAOL_INTEL_ADSP
198+ tuple = tlv_next (tuple );
199+ tlv_value_set_uaol_caps (tuple , IPC4_UAOL_CAPS_HW_CFG );
200+ #endif
201+
127202 tuple = tlv_next (tuple );
128203 * data_offset = (int )((char * )tuple - data );
129204
@@ -454,6 +529,7 @@ __cold int basefw_vendor_set_large_config(struct comp_dev *dev, uint32_t param_i
454529__cold int basefw_vendor_dma_control (uint32_t node_id , const char * config_data , size_t data_size )
455530{
456531 union ipc4_connector_node_id node = (union ipc4_connector_node_id )node_id ;
532+ int dai_index = node .f .v_index ;
457533 int ret , result ;
458534 enum sof_ipc_dai_type type ;
459535
@@ -477,11 +553,25 @@ __cold int basefw_vendor_dma_control(uint32_t node_id, const char *config_data,
477553 case ipc4_i2s_link_input_class :
478554 type = SOF_DAI_INTEL_SSP ;
479555 break ;
556+
557+ #if CONFIG_UAOL_INTEL_ADSP
558+ case ipc4_alh_uaol_stream_link_output_class :
559+ case ipc4_alh_uaol_stream_link_input_class :
560+ type = SOF_DAI_INTEL_UAOL ;
561+ dai_index = uaol_stream_id_to_hda_link_stream_id (node .f .v_index );
562+ if (dai_index < 0 ) {
563+ tr_err (& basefw_comp_tr ,
564+ "HDA link stream not found! UAOL node ID: 0x%x" , node_id );
565+ return IPC4_INVALID_RESOURCE_ID ;
566+ }
567+ break ;
568+ #endif
569+
480570 default :
481571 return IPC4_INVALID_RESOURCE_ID ;
482572 }
483573
484- const struct device * dev = dai_get_device (type , node . f . v_index );
574+ const struct device * dev = dai_get_device (type , dai_index );
485575
486576 if (!dev ) {
487577 tr_err (& basefw_comp_tr ,
0 commit comments