1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019 Intel Corporation. All rights reserved. 4 * 5 * Author: Marcin Rajwa <marcin.rajwa@linux.intel.com> 6 */ 7 8 #ifndef __SOF_AUDIO_KPB_H__ 9 #define __SOF_AUDIO_KPB_H__ 10 11 #include <sof/trace/trace.h> 12 #include <user/trace.h> 13 #include <stdint.h> 14 15 struct comp_buffer; 16 17 /* KPB internal defines */ 18 19 #ifdef CONFIG_TIGERLAKE 20 #define KPB_MAX_BUFF_TIME 3000 /**< time of buffering in miliseconds */ 21 #define HOST_WAKEUP_TIME 1000 /* aprox. time of host DMA wakup from suspend [ms] */ 22 #else 23 /** Due to memory constraints on non-TGL platforms, the buffers are smaller. */ 24 #define KPB_MAX_BUFF_TIME 2100 /**< time of buffering in miliseconds */ 25 #define HOST_WAKEUP_TIME 0 /* aprox. time of host DMA wakup from suspend [ms] */ 26 #endif 27 28 #define KPB_MAX_DRAINING_REQ (KPB_MAX_BUFF_TIME - HOST_WAKEUP_TIME) 29 #define KPB_MAX_SUPPORTED_CHANNELS 2 /**< number of supported channels */ 30 /**< number of samples taken each milisecond */ 31 #define KPB_SAMPLES_PER_MS (KPB_SAMPLNG_FREQUENCY / 1000) 32 #define KPB_SAMPLNG_FREQUENCY 16000 /**< supported sampling frequency in Hz */ 33 #define KPB_NUM_OF_CHANNELS 2 34 #define KPB_SAMPLE_CONTAINER_SIZE(sw) ((sw == 16) ? 16 : 32) 35 #define KPB_MAX_BUFFER_SIZE(sw) ((KPB_SAMPLNG_FREQUENCY / 1000) * \ 36 (KPB_SAMPLE_CONTAINER_SIZE(sw) / 8) * KPB_MAX_BUFF_TIME * \ 37 KPB_NUM_OF_CHANNELS) 38 #define KPB_MAX_NO_OF_CLIENTS 2 39 #define KPB_NO_OF_HISTORY_BUFFERS 2 /**< no of internal buffers */ 40 #define KPB_ALLOCATION_STEP 0x100 41 #define KPB_NO_OF_MEM_POOLS 3 42 #define KPB_BYTES_TO_FRAMES(bytes, sample_width) \ 43 (bytes / ((KPB_SAMPLE_CONTAINER_SIZE(sample_width) / 8) * \ 44 KPB_NUM_OF_CHANNELS)) 45 /**< Defines how much faster draining is in comparison to pipeline copy. */ 46 #define KPB_DRAIN_NUM_OF_PPL_PERIODS_AT_ONCE 2 47 /**< Host buffer shall be at least two times bigger than history buffer. */ 48 #define HOST_BUFFER_MIN_SIZE(hb) (hb * 2) 49 50 /** All states below as well as relations between them are documented in 51 * the sof-dosc in [kpbm-state-diagram] 52 * Therefore any addition of new states or modification of existing ones 53 * should have a corresponding update in the sof-docs. 54 * [kpbm-state-diagram]: 55 https://thesofproject.github.io/latest/developer_guides/firmware/kd_integration/kd-integration.html#kpbm-state-diagram 56 "Keyphrase buffer manager state diagram" 57 */ 58 enum kpb_state { 59 KPB_STATE_DISABLED = 0, 60 KPB_STATE_RESET_FINISHING, 61 KPB_STATE_CREATED, 62 KPB_STATE_PREPARING, 63 KPB_STATE_RUN, 64 KPB_STATE_BUFFERING, 65 KPB_STATE_INIT_DRAINING, 66 KPB_STATE_DRAINING, 67 KPB_STATE_HOST_COPY, 68 KPB_STATE_RESETTING, 69 }; 70 71 enum kpb_event { 72 KPB_EVENT_REGISTER_CLIENT = 0, 73 KPB_EVENT_UPDATE_PARAMS, 74 KPB_EVENT_BEGIN_DRAINING, 75 KPB_EVENT_STOP_DRAINING, 76 KPB_EVENT_UNREGISTER_CLIENT, 77 }; 78 79 struct kpb_event_data { 80 enum kpb_event event_id; 81 struct kpb_client *client_data; 82 }; 83 84 enum kpb_client_state { 85 KPB_CLIENT_UNREGISTERED = 0, 86 KPB_CLIENT_BUFFERING, 87 KPB_CLIENT_DRAINNING, 88 KPB_CLIENT_DRAINNING_OD, /**< draining on demand */ 89 }; 90 91 struct kpb_client { 92 uint8_t id; /**< id associated with output sink */ 93 uint32_t drain_req; /**< normalized value of buffered bytes */ 94 enum kpb_client_state state; /**< current state of a client */ 95 void *r_ptr; /**< current read position */ 96 struct comp_buffer *sink; /**< client's sink */ 97 }; 98 99 enum buffer_state { 100 KPB_BUFFER_FREE = 0, 101 KPB_BUFFER_FULL, 102 KPB_BUFFER_OFF, 103 }; 104 105 enum kpb_id { 106 KPB_LP = 0, 107 KPB_HP, 108 }; 109 110 struct history_buffer { 111 enum buffer_state state; /**< state of the buffer */ 112 void *start_addr; /**< buffer start address */ 113 void *end_addr; /**< buffer end address */ 114 void *w_ptr; /**< buffer write pointer */ 115 void *r_ptr; /**< buffer read pointer */ 116 struct history_buffer *next; /**< next history buffer */ 117 struct history_buffer *prev; /**< next history buffer */ 118 }; 119 120 /* Draining task data */ 121 struct draining_data { 122 struct comp_buffer *sink; 123 struct history_buffer *hb; 124 size_t drain_req; 125 uint8_t is_draining_active; 126 size_t sample_width; 127 size_t buffered_while_draining; 128 size_t drain_interval; 129 size_t pb_limit; /**< Period bytes limit */ 130 struct comp_dev *dev; 131 bool sync_mode_on; 132 enum comp_copy_type copy_type; 133 }; 134 135 struct history_data { 136 size_t buffer_size; /**< size of internal history buffer */ 137 size_t buffered; /**< amount of buffered data */ 138 size_t free; /** spce we can use to write new data */ 139 struct history_buffer *c_hb; /**< current buffer used for writing */ 140 }; 141 142 #ifdef UNIT_TEST 143 void sys_comp_kpb_init(void); 144 #endif 145 146 #endif /* __SOF_AUDIO_KPB_H__ */ 147