xref: /openbmc/linux/sound/soc/qcom/qdsp6/q6apm.h (revision bb6979c5)
15477518bSSrinivas Kandagatla /* SPDX-License-Identifier: GPL-2.0 */
25477518bSSrinivas Kandagatla #ifndef __Q6APM_H__
35477518bSSrinivas Kandagatla #define __Q6APM_H__
45477518bSSrinivas Kandagatla #include <linux/types.h>
55477518bSSrinivas Kandagatla #include <linux/slab.h>
65477518bSSrinivas Kandagatla #include <linux/wait.h>
75477518bSSrinivas Kandagatla #include <linux/kernel.h>
85477518bSSrinivas Kandagatla #include <linux/module.h>
95477518bSSrinivas Kandagatla #include <linux/sched.h>
105477518bSSrinivas Kandagatla #include <linux/of.h>
115477518bSSrinivas Kandagatla #include <linux/delay.h>
125477518bSSrinivas Kandagatla #include <sound/soc.h>
135477518bSSrinivas Kandagatla #include <linux/of_platform.h>
145477518bSSrinivas Kandagatla #include <linux/jiffies.h>
155477518bSSrinivas Kandagatla #include <linux/soc/qcom/apr.h>
165477518bSSrinivas Kandagatla #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
175477518bSSrinivas Kandagatla #include "audioreach.h"
185477518bSSrinivas Kandagatla 
195477518bSSrinivas Kandagatla #define APM_PORT_MAX		127
205477518bSSrinivas Kandagatla #define APM_PORT_MAX_AUDIO_CHAN_CNT 8
215477518bSSrinivas Kandagatla #define PCM_CHANNEL_NULL 0
225477518bSSrinivas Kandagatla #define PCM_CHANNEL_FL    1	/* Front left channel. */
235477518bSSrinivas Kandagatla #define PCM_CHANNEL_FR    2	/* Front right channel. */
245477518bSSrinivas Kandagatla #define PCM_CHANNEL_FC    3	/* Front center channel. */
255477518bSSrinivas Kandagatla #define PCM_CHANNEL_LS   4	/* Left surround channel. */
265477518bSSrinivas Kandagatla #define PCM_CHANNEL_RS   5	/* Right surround channel. */
275477518bSSrinivas Kandagatla #define PCM_CHANNEL_LFE  6	/* Low frequency effect channel. */
285477518bSSrinivas Kandagatla #define PCM_CHANNEL_CS   7	/* Center surround channel; Rear center ch */
295477518bSSrinivas Kandagatla #define PCM_CHANNEL_LB   8	/* Left back channel; Rear left channel. */
305477518bSSrinivas Kandagatla #define PCM_CHANNEL_RB   9	/* Right back channel; Rear right channel. */
315477518bSSrinivas Kandagatla #define PCM_CHANNELS   10	/* Top surround channel. */
325477518bSSrinivas Kandagatla 
335477518bSSrinivas Kandagatla #define APM_TIMESTAMP_FLAG	0x80000000
345477518bSSrinivas Kandagatla #define FORMAT_LINEAR_PCM	0x0000
355477518bSSrinivas Kandagatla /* APM client callback events */
365477518bSSrinivas Kandagatla #define APM_CMD_EOS				0x0003
375477518bSSrinivas Kandagatla #define APM_CLIENT_EVENT_CMD_EOS_DONE		0x1003
385477518bSSrinivas Kandagatla #define APM_CMD_CLOSE				0x0004
395477518bSSrinivas Kandagatla #define APM_CLIENT_EVENT_CMD_CLOSE_DONE		0x1004
405477518bSSrinivas Kandagatla #define APM_CLIENT_EVENT_CMD_RUN_DONE		0x1008
415477518bSSrinivas Kandagatla #define APM_CLIENT_EVENT_DATA_WRITE_DONE	0x1009
425477518bSSrinivas Kandagatla #define APM_CLIENT_EVENT_DATA_READ_DONE		0x100a
435477518bSSrinivas Kandagatla #define APM_WRITE_TOKEN_MASK                   GENMASK(15, 0)
445477518bSSrinivas Kandagatla #define APM_WRITE_TOKEN_LEN_MASK               GENMASK(31, 16)
455477518bSSrinivas Kandagatla #define APM_WRITE_TOKEN_LEN_SHIFT              16
465477518bSSrinivas Kandagatla 
475477518bSSrinivas Kandagatla #define APM_MAX_SESSIONS			8
4888b60bf0SSrinivas Kandagatla #define APM_LAST_BUFFER_FLAG			BIT(30)
49*c337bf33SSrinivas Kandagatla #define NO_TIMESTAMP				0xFF00
505477518bSSrinivas Kandagatla 
515477518bSSrinivas Kandagatla struct q6apm {
525477518bSSrinivas Kandagatla 	struct device *dev;
535477518bSSrinivas Kandagatla 	gpr_port_t *port;
545477518bSSrinivas Kandagatla 	gpr_device_t *gdev;
555477518bSSrinivas Kandagatla 	/* For Graph OPEN/START/STOP/CLOSE operations */
565477518bSSrinivas Kandagatla 	wait_queue_head_t wait;
575477518bSSrinivas Kandagatla 	struct gpr_ibasic_rsp_result_t result;
585477518bSSrinivas Kandagatla 
595477518bSSrinivas Kandagatla 	struct mutex cmd_lock;
605477518bSSrinivas Kandagatla 	struct mutex lock;
615477518bSSrinivas Kandagatla 	uint32_t state;
625477518bSSrinivas Kandagatla 
631c87d381SSrinivas Kandagatla 	struct list_head widget_list;
645477518bSSrinivas Kandagatla 	struct idr graph_idr;
655477518bSSrinivas Kandagatla 	struct idr graph_info_idr;
665477518bSSrinivas Kandagatla 	struct idr sub_graphs_idr;
675477518bSSrinivas Kandagatla 	struct idr containers_idr;
685477518bSSrinivas Kandagatla 	struct idr modules_idr;
695477518bSSrinivas Kandagatla };
705477518bSSrinivas Kandagatla 
715477518bSSrinivas Kandagatla struct audio_buffer {
725477518bSSrinivas Kandagatla 	phys_addr_t phys;
735477518bSSrinivas Kandagatla 	uint32_t size;		/* size of buffer */
745477518bSSrinivas Kandagatla };
755477518bSSrinivas Kandagatla 
765477518bSSrinivas Kandagatla struct audioreach_graph_data {
775477518bSSrinivas Kandagatla 	struct audio_buffer *buf;
785477518bSSrinivas Kandagatla 	uint32_t num_periods;
795477518bSSrinivas Kandagatla 	uint32_t dsp_buf;
805477518bSSrinivas Kandagatla 	uint32_t mem_map_handle;
815477518bSSrinivas Kandagatla };
825477518bSSrinivas Kandagatla 
835477518bSSrinivas Kandagatla struct audioreach_graph {
845477518bSSrinivas Kandagatla 	struct audioreach_graph_info *info;
855477518bSSrinivas Kandagatla 	uint32_t id;
865477518bSSrinivas Kandagatla 	int state;
875477518bSSrinivas Kandagatla 	int start_count;
885477518bSSrinivas Kandagatla 	/* Cached Graph data */
895477518bSSrinivas Kandagatla 	void *graph;
905477518bSSrinivas Kandagatla 	struct kref refcount;
915477518bSSrinivas Kandagatla 	struct q6apm *apm;
925477518bSSrinivas Kandagatla };
935477518bSSrinivas Kandagatla 
945477518bSSrinivas Kandagatla typedef void (*q6apm_cb) (uint32_t opcode, uint32_t token,
955477518bSSrinivas Kandagatla 			  void *payload, void *priv);
965477518bSSrinivas Kandagatla struct q6apm_graph {
975477518bSSrinivas Kandagatla 	void *priv;
985477518bSSrinivas Kandagatla 	q6apm_cb cb;
995477518bSSrinivas Kandagatla 	uint32_t id;
1005477518bSSrinivas Kandagatla 	struct device *dev;
1015477518bSSrinivas Kandagatla 	struct q6apm *apm;
1025477518bSSrinivas Kandagatla 	gpr_port_t *port;
1035477518bSSrinivas Kandagatla 	struct audioreach_graph_data rx_data;
1045477518bSSrinivas Kandagatla 	struct audioreach_graph_data tx_data;
1055477518bSSrinivas Kandagatla 	struct gpr_ibasic_rsp_result_t result;
1065477518bSSrinivas Kandagatla 	wait_queue_head_t cmd_wait;
1075477518bSSrinivas Kandagatla 	struct mutex lock;
1085477518bSSrinivas Kandagatla 	struct audioreach_graph *ar_graph;
1095477518bSSrinivas Kandagatla 	struct audioreach_graph_info *info;
1105477518bSSrinivas Kandagatla };
1115477518bSSrinivas Kandagatla 
1125477518bSSrinivas Kandagatla /* Graph Operations */
1135477518bSSrinivas Kandagatla struct q6apm_graph *q6apm_graph_open(struct device *dev, q6apm_cb cb,
1145477518bSSrinivas Kandagatla 				     void *priv, int graph_id);
1155477518bSSrinivas Kandagatla int q6apm_graph_close(struct q6apm_graph *graph);
1165477518bSSrinivas Kandagatla int q6apm_graph_prepare(struct q6apm_graph *graph);
1175477518bSSrinivas Kandagatla int q6apm_graph_start(struct q6apm_graph *graph);
1185477518bSSrinivas Kandagatla int q6apm_graph_stop(struct q6apm_graph *graph);
1195477518bSSrinivas Kandagatla int q6apm_graph_flush(struct q6apm_graph *graph);
1205477518bSSrinivas Kandagatla 
1215477518bSSrinivas Kandagatla /* Media Format */
1225477518bSSrinivas Kandagatla int q6apm_graph_media_format_pcm(struct q6apm_graph *graph,
1235477518bSSrinivas Kandagatla 				 struct audioreach_module_config *cfg);
1245477518bSSrinivas Kandagatla 
1255477518bSSrinivas Kandagatla int q6apm_graph_media_format_shmem(struct q6apm_graph *graph,
1265477518bSSrinivas Kandagatla 				   struct audioreach_module_config *cfg);
1275477518bSSrinivas Kandagatla 
1285477518bSSrinivas Kandagatla /* read/write related */
1295477518bSSrinivas Kandagatla int q6apm_read(struct q6apm_graph *graph);
1305477518bSSrinivas Kandagatla int q6apm_write_async(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts,
1315477518bSSrinivas Kandagatla 		      uint32_t lsw_ts, uint32_t wflags);
1325477518bSSrinivas Kandagatla 
1335477518bSSrinivas Kandagatla /* Memory Map related */
1345477518bSSrinivas Kandagatla int q6apm_map_memory_regions(struct q6apm_graph *graph,
1355477518bSSrinivas Kandagatla 			     unsigned int dir, phys_addr_t phys,
1365477518bSSrinivas Kandagatla 			     size_t period_sz, unsigned int periods);
1375477518bSSrinivas Kandagatla int q6apm_unmap_memory_regions(struct q6apm_graph *graph,
1385477518bSSrinivas Kandagatla 			       unsigned int dir);
1395477518bSSrinivas Kandagatla /* Helpers */
1405477518bSSrinivas Kandagatla int q6apm_send_cmd_sync(struct q6apm *apm, struct gpr_pkt *pkt,
1415477518bSSrinivas Kandagatla 			uint32_t rsp_opcode);
1425477518bSSrinivas Kandagatla 
1435477518bSSrinivas Kandagatla /* Callback for graph specific */
1445477518bSSrinivas Kandagatla struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph,
1455477518bSSrinivas Kandagatla 						    uint32_t mid);
1465477518bSSrinivas Kandagatla int q6apm_graph_get_rx_shmem_module_iid(struct q6apm_graph *graph);
1475477518bSSrinivas Kandagatla 
14847bc8cf6SSrinivasa Rao Mandadapu bool q6apm_is_adsp_ready(void);
14947bc8cf6SSrinivasa Rao Mandadapu 
150c7548f59SSrinivas Kandagatla int q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph, bool en);
151c7548f59SSrinivas Kandagatla int q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
152c7548f59SSrinivas Kandagatla int q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples);
153c7548f59SSrinivas Kandagatla int q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, uint32_t codec_id);
1545477518bSSrinivas Kandagatla #endif /* __APM_GRAPH_ */
155