xref: /linux/drivers/soundwire/cadence_master.h (revision db9c4387391e09209d44d41c2791512ac45b9e3c)
1 /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
2 /* Copyright(c) 2015-17 Intel Corporation. */
3 #include <sound/soc.h>
4 #include "bus.h"
5 
6 #ifndef __SDW_CADENCE_H
7 #define __SDW_CADENCE_H
8 
9 #define SDW_CADENCE_GSYNC_KHZ		4 /* 4 kHz */
10 #define SDW_CADENCE_GSYNC_HZ		(SDW_CADENCE_GSYNC_KHZ * 1000)
11 
12 /*
13  * The Cadence IP supports up to 32 entries in the FIFO, though implementations
14  * can configure the IP to have a smaller FIFO.
15  */
16 #define CDNS_MCP_IP_MAX_CMD_LEN		32
17 
18 #define SDW_CADENCE_MCP_IP_OFFSET	0x4000
19 
20 /**
21  * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
22  *
23  * @num: pdi number
24  * @intel_alh_id: link identifier
25  * @l_ch_num: low channel for PDI
26  * @h_ch_num: high channel for PDI
27  * @ch_count: total channel count for PDI
28  * @dir: data direction
29  * @type: stream type, (only PCM supported)
30  */
31 struct sdw_cdns_pdi {
32 	int num;
33 	int intel_alh_id;
34 	int l_ch_num;
35 	int h_ch_num;
36 	int ch_count;
37 	enum sdw_data_direction dir;
38 	enum sdw_stream_type type;
39 };
40 
41 /**
42  * struct sdw_cdns_streams: Cadence stream data structure
43  *
44  * @num_bd: number of bidirectional streams
45  * @num_in: number of input streams
46  * @num_out: number of output streams
47  * @num_ch_bd: number of bidirectional stream channels
48  * @num_ch_bd: number of input stream channels
49  * @num_ch_bd: number of output stream channels
50  * @num_pdi: total number of PDIs
51  * @bd: bidirectional streams
52  * @in: input streams
53  * @out: output streams
54  */
55 struct sdw_cdns_streams {
56 	unsigned int num_bd;
57 	unsigned int num_in;
58 	unsigned int num_out;
59 	unsigned int num_ch_bd;
60 	unsigned int num_ch_in;
61 	unsigned int num_ch_out;
62 	unsigned int num_pdi;
63 	struct sdw_cdns_pdi *bd;
64 	struct sdw_cdns_pdi *in;
65 	struct sdw_cdns_pdi *out;
66 };
67 
68 /**
69  * struct sdw_cdns_stream_config: stream configuration
70  *
71  * @pcm_bd: number of bidirectional PCM streams supported
72  * @pcm_in: number of input PCM streams supported
73  * @pcm_out: number of output PCM streams supported
74  */
75 struct sdw_cdns_stream_config {
76 	unsigned int pcm_bd;
77 	unsigned int pcm_in;
78 	unsigned int pcm_out;
79 };
80 
81 /**
82  * struct sdw_cdns_dai_runtime: Cadence DAI runtime data
83  *
84  * @name: SoundWire stream name
85  * @stream: stream runtime
86  * @pdi: PDI used for this dai
87  * @bus: Bus handle
88  * @stream_type: Stream type
89  * @link_id: Master link id
90  * @suspended: status set when suspended, to be used in .prepare
91  * @paused: status set in .trigger, to be used in suspend
92  * @direction: stream direction
93  */
94 struct sdw_cdns_dai_runtime {
95 	char *name;
96 	struct sdw_stream_runtime *stream;
97 	struct sdw_cdns_pdi *pdi;
98 	struct sdw_bus *bus;
99 	enum sdw_stream_type stream_type;
100 	int link_id;
101 	bool suspended;
102 	bool paused;
103 	int direction;
104 };
105 
106 /**
107  * struct sdw_cdns - Cadence driver context
108  * @dev: Linux device
109  * @bus: Bus handle
110  * @instance: instance number
111  * @ip_offset: version-dependent offset to access IP_MCP registers and fields
112  * @response_buf: SoundWire response buffer
113  * @tx_complete: Tx completion
114  * @ports: Data ports
115  * @num_ports: Total number of data ports
116  * @pcm: PCM streams
117  * @registers: Cadence registers
118  * @link_up: Link status
119  * @msg_count: Messages sent on bus
120  * @dai_runtime_array: runtime context for each allocated DAI.
121  * @status_update_lock: protect concurrency between interrupt-based and delayed work
122  * status update
123  */
124 struct sdw_cdns {
125 	struct device *dev;
126 	struct sdw_bus bus;
127 	unsigned int instance;
128 
129 	u32 ip_offset;
130 
131 	/*
132 	 * The datasheet says the RX FIFO AVAIL can be 2 entries more
133 	 * than the FIFO capacity, so allow for this.
134 	 */
135 	u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN + 2];
136 
137 	struct completion tx_complete;
138 
139 	struct sdw_cdns_port *ports;
140 	int num_ports;
141 
142 	struct sdw_cdns_streams pcm;
143 
144 	int pdi_loopback_source;
145 	int pdi_loopback_target;
146 
147 	void __iomem *registers;
148 
149 	bool link_up;
150 	unsigned int msg_count;
151 	bool interrupt_enabled;
152 
153 	struct work_struct work;
154 	struct delayed_work attach_dwork;
155 
156 	struct list_head list;
157 
158 	struct sdw_cdns_dai_runtime **dai_runtime_array;
159 
160 	struct mutex status_update_lock; /* add mutual exclusion to sdw_handle_slave_status() */
161 };
162 
163 #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
164 
165 /* Exported symbols */
166 
167 int sdw_cdns_probe(struct sdw_cdns *cdns);
168 
169 irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
170 irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
171 
172 int sdw_cdns_soft_reset(struct sdw_cdns *cdns);
173 int sdw_cdns_init(struct sdw_cdns *cdns);
174 int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
175 		      struct sdw_cdns_stream_config config);
176 int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
177 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state);
178 
179 bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns);
180 int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake);
181 int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset);
182 
183 #ifdef CONFIG_DEBUG_FS
184 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
185 #endif
186 
187 struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
188 					struct sdw_cdns_streams *stream,
189 					u32 ch, u32 dir, int dai_id);
190 void sdw_cdns_config_stream(struct sdw_cdns *cdns,
191 			    u32 ch, u32 dir, struct sdw_cdns_pdi *pdi);
192 
193 enum sdw_command_response
194 cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg);
195 
196 enum sdw_command_response
197 cdns_xfer_msg_defer(struct sdw_bus *bus);
198 
199 u32 cdns_read_ping_status(struct sdw_bus *bus);
200 
201 int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params);
202 
203 int cdns_set_sdw_stream(struct snd_soc_dai *dai,
204 			void *stream, int direction);
205 
206 void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string,
207 				       bool initial_delay, int reset_iterations);
208 
209 void sdw_cdns_config_update(struct sdw_cdns *cdns);
210 int sdw_cdns_config_update_set_wait(struct sdw_cdns *cdns);
211 
212 /* SoundWire BPT/BRA helpers to format data */
213 int sdw_cdns_bpt_find_bandwidth(int command, /* 0: write, 1: read */
214 				int row, int col, int frame_rate,
215 				unsigned int *tx_dma_bandwidth,
216 				unsigned int *rx_dma_bandwidth);
217 
218 int sdw_cdns_bpt_find_buffer_sizes(int command, /* 0: write, 1: read */
219 				   int row, int col, unsigned int data_bytes,
220 				   unsigned int requested_bytes_per_frame,
221 				   unsigned int *data_per_frame, unsigned int *pdi0_buffer_size,
222 				   unsigned int *pdi1_buffer_size, unsigned int *num_frames);
223 
224 int sdw_cdns_prepare_write_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, int num_sec,
225 				      int data_per_frame, u8 *dma_buffer,
226 				      int dma_buffer_size, int *dma_buffer_total_bytes);
227 
228 int sdw_cdns_prepare_read_dma_buffer(u8 dev_num, struct sdw_bpt_section *sec, int num_sec,
229 				     int data_per_frame, u8 *dma_buffer, int dma_buffer_size,
230 				     int *dma_buffer_total_bytes, unsigned int fake_size);
231 
232 int sdw_cdns_check_write_response(struct device *dev, u8 *dma_buffer,
233 				  int dma_buffer_size, int num_frames);
234 
235 int sdw_cdns_check_read_response(struct device *dev, u8 *dma_buffer, int dma_buffer_size,
236 				 struct sdw_bpt_section *sec, int num_sec, int num_frames,
237 				 int data_per_frame);
238 #endif /* __SDW_CADENCE_H */
239