xref: /linux/drivers/soundwire/mipi_disco.c (revision 79d2e1919a2728ef49d938eb20ebd5903c14dfb0)
1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
3 
4 /*
5  * MIPI Discovery And Configuration (DisCo) Specification for SoundWire
6  * specifies properties to be implemented for SoundWire Masters and Slaves.
7  * The DisCo spec doesn't mandate these properties. However, SDW bus cannot
8  * work without knowing these values.
9  *
10  * The helper functions read the Master and Slave properties. Implementers
11  * of Master or Slave drivers can use any of the below three mechanisms:
12  *    a) Use these APIs here as .read_prop() callback for Master and Slave
13  *    b) Implement own methods and set those as .read_prop(), but invoke
14  *    APIs in this file for generic read and override the values with
15  *    platform specific data
16  *    c) Implement ones own methods which do not use anything provided
17  *    here
18  */
19 
20 #include <linux/device.h>
21 #include <linux/property.h>
22 #include <linux/mod_devicetable.h>
23 #include <linux/soundwire/sdw.h>
24 #include "bus.h"
25 
26 static bool mipi_fwnode_property_read_bool(const struct fwnode_handle *fwnode,
27 					   const char *propname)
28 {
29 	int ret;
30 	u8 val;
31 
32 	if (!fwnode_property_present(fwnode, propname))
33 		return false;
34 	ret = fwnode_property_read_u8_array(fwnode, propname, &val, 1);
35 	if (ret < 0)
36 		return false;
37 	return !!val;
38 }
39 
40 static bool mipi_device_property_read_bool(const struct device *dev,
41 					   const char *propname)
42 {
43 	return mipi_fwnode_property_read_bool(dev_fwnode(dev), propname);
44 }
45 
46 /**
47  * sdw_master_read_prop() - Read Master properties
48  * @bus: SDW bus instance
49  */
50 int sdw_master_read_prop(struct sdw_bus *bus)
51 {
52 	struct sdw_master_prop *prop = &bus->prop;
53 	struct fwnode_handle *link;
54 	const char *scales_prop;
55 	char name[32];
56 	int nval;
57 	int ret;
58 	int i;
59 
60 	device_property_read_u32(bus->dev,
61 				 "mipi-sdw-sw-interface-revision",
62 				 &prop->revision);
63 
64 	/* Find master handle */
65 	snprintf(name, sizeof(name),
66 		 "mipi-sdw-link-%d-subproperties", bus->link_id);
67 
68 	link = device_get_named_child_node(bus->dev, name);
69 	if (!link) {
70 		dev_err(bus->dev, "Master node %s not found\n", name);
71 		return -EIO;
72 	}
73 
74 	if (mipi_fwnode_property_read_bool(link,
75 				      "mipi-sdw-clock-stop-mode0-supported"))
76 		prop->clk_stop_modes |= BIT(SDW_CLK_STOP_MODE0);
77 
78 	if (mipi_fwnode_property_read_bool(link,
79 				      "mipi-sdw-clock-stop-mode1-supported"))
80 		prop->clk_stop_modes |= BIT(SDW_CLK_STOP_MODE1);
81 
82 	fwnode_property_read_u32(link,
83 				 "mipi-sdw-max-clock-frequency",
84 				 &prop->max_clk_freq);
85 
86 	nval = fwnode_property_count_u32(link, "mipi-sdw-clock-frequencies-supported");
87 	if (nval > 0) {
88 		prop->num_clk_freq = nval;
89 		prop->clk_freq = devm_kcalloc(bus->dev, prop->num_clk_freq,
90 					      sizeof(*prop->clk_freq),
91 					      GFP_KERNEL);
92 		if (!prop->clk_freq) {
93 			fwnode_handle_put(link);
94 			return -ENOMEM;
95 		}
96 
97 		ret = fwnode_property_read_u32_array(link,
98 				"mipi-sdw-clock-frequencies-supported",
99 				prop->clk_freq, prop->num_clk_freq);
100 		if (ret < 0)
101 			return ret;
102 	}
103 
104 	/*
105 	 * Check the frequencies supported. If FW doesn't provide max
106 	 * freq, then populate here by checking values.
107 	 */
108 	if (!prop->max_clk_freq && prop->clk_freq) {
109 		prop->max_clk_freq = prop->clk_freq[0];
110 		for (i = 1; i < prop->num_clk_freq; i++) {
111 			if (prop->clk_freq[i] > prop->max_clk_freq)
112 				prop->max_clk_freq = prop->clk_freq[i];
113 		}
114 	}
115 
116 	scales_prop = "mipi-sdw-supported-clock-scales";
117 	nval = fwnode_property_count_u32(link, scales_prop);
118 	if (nval == 0) {
119 		scales_prop = "mipi-sdw-supported-clock-gears";
120 		nval = fwnode_property_count_u32(link, scales_prop);
121 	}
122 	if (nval > 0) {
123 		prop->num_clk_gears = nval;
124 		prop->clk_gears = devm_kcalloc(bus->dev, prop->num_clk_gears,
125 					       sizeof(*prop->clk_gears),
126 					       GFP_KERNEL);
127 		if (!prop->clk_gears) {
128 			fwnode_handle_put(link);
129 			return -ENOMEM;
130 		}
131 
132 		ret = fwnode_property_read_u32_array(link,
133 					       scales_prop,
134 					       prop->clk_gears,
135 					       prop->num_clk_gears);
136 		if (ret < 0)
137 			return ret;
138 	}
139 
140 	fwnode_property_read_u32(link, "mipi-sdw-default-frame-rate",
141 				 &prop->default_frame_rate);
142 
143 	fwnode_property_read_u32(link, "mipi-sdw-default-frame-row-size",
144 				 &prop->default_row);
145 
146 	fwnode_property_read_u32(link, "mipi-sdw-default-frame-col-size",
147 				 &prop->default_col);
148 
149 	prop->dynamic_frame =  mipi_fwnode_property_read_bool(link,
150 			"mipi-sdw-dynamic-frame-shape");
151 
152 	fwnode_property_read_u32(link, "mipi-sdw-command-error-threshold",
153 				 &prop->err_threshold);
154 
155 	fwnode_handle_put(link);
156 
157 	return 0;
158 }
159 EXPORT_SYMBOL(sdw_master_read_prop);
160 
161 static int sdw_slave_read_dp0(struct sdw_slave *slave,
162 			      struct fwnode_handle *port,
163 			      struct sdw_dp0_prop *dp0)
164 {
165 	int nval;
166 	int ret;
167 
168 	fwnode_property_read_u32(port, "mipi-sdw-port-max-wordlength",
169 				 &dp0->max_word);
170 
171 	fwnode_property_read_u32(port, "mipi-sdw-port-min-wordlength",
172 				 &dp0->min_word);
173 
174 	nval = fwnode_property_count_u32(port, "mipi-sdw-port-wordlength-configs");
175 	if (nval > 0) {
176 
177 		dp0->num_words = nval;
178 		dp0->words = devm_kcalloc(&slave->dev,
179 					  dp0->num_words, sizeof(*dp0->words),
180 					  GFP_KERNEL);
181 		if (!dp0->words)
182 			return -ENOMEM;
183 
184 		ret = fwnode_property_read_u32_array(port,
185 				"mipi-sdw-port-wordlength-configs",
186 				dp0->words, dp0->num_words);
187 		if (ret < 0)
188 			return ret;
189 	}
190 
191 	dp0->BRA_flow_controlled = mipi_fwnode_property_read_bool(port,
192 				"mipi-sdw-bra-flow-controlled");
193 
194 	dp0->simple_ch_prep_sm = mipi_fwnode_property_read_bool(port,
195 				"mipi-sdw-simplified-channel-prepare-sm");
196 
197 	dp0->imp_def_interrupts = mipi_fwnode_property_read_bool(port,
198 				"mipi-sdw-imp-def-dp0-interrupts-supported");
199 
200 	nval = fwnode_property_count_u32(port, "mipi-sdw-lane-list");
201 	if (nval > 0) {
202 		dp0->num_lanes = nval;
203 		dp0->lane_list = devm_kcalloc(&slave->dev,
204 					      dp0->num_lanes, sizeof(*dp0->lane_list),
205 					      GFP_KERNEL);
206 		if (!dp0->lane_list)
207 			return -ENOMEM;
208 
209 		ret = fwnode_property_read_u32_array(port,
210 					       "mipi-sdw-lane-list",
211 					       dp0->lane_list, dp0->num_lanes);
212 		if (ret < 0)
213 			return ret;
214 	}
215 
216 	return 0;
217 }
218 
219 static int sdw_slave_read_dpn(struct sdw_slave *slave,
220 			      struct sdw_dpn_prop *dpn, int count, int ports,
221 			      char *type)
222 {
223 	struct fwnode_handle *node;
224 	u32 bit, i = 0;
225 	unsigned long addr;
226 	char name[40];
227 	int nval;
228 	int ret;
229 
230 	addr = ports;
231 	/* valid ports are 1 to 14 so apply mask */
232 	addr &= GENMASK(14, 1);
233 
234 	for_each_set_bit(bit, &addr, 32) {
235 		snprintf(name, sizeof(name),
236 			 "mipi-sdw-dp-%d-%s-subproperties", bit, type);
237 
238 		dpn[i].num = bit;
239 
240 		node = device_get_named_child_node(&slave->dev, name);
241 		if (!node) {
242 			dev_err(&slave->dev, "%s dpN not found\n", name);
243 			return -EIO;
244 		}
245 
246 		fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength",
247 					 &dpn[i].max_word);
248 		fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength",
249 					 &dpn[i].min_word);
250 
251 		nval = fwnode_property_count_u32(node, "mipi-sdw-port-wordlength-configs");
252 		if (nval > 0) {
253 			dpn[i].num_words = nval;
254 			dpn[i].words = devm_kcalloc(&slave->dev,
255 						    dpn[i].num_words,
256 						    sizeof(*dpn[i].words),
257 						    GFP_KERNEL);
258 			if (!dpn[i].words) {
259 				fwnode_handle_put(node);
260 				return -ENOMEM;
261 			}
262 
263 			ret = fwnode_property_read_u32_array(node,
264 					"mipi-sdw-port-wordlength-configs",
265 					dpn[i].words, dpn[i].num_words);
266 			if (ret < 0)
267 				return ret;
268 		}
269 
270 		fwnode_property_read_u32(node, "mipi-sdw-data-port-type",
271 					 &dpn[i].type);
272 
273 		fwnode_property_read_u32(node,
274 					 "mipi-sdw-max-grouping-supported",
275 					 &dpn[i].max_grouping);
276 
277 		dpn[i].simple_ch_prep_sm = mipi_fwnode_property_read_bool(node,
278 				"mipi-sdw-simplified-channelprepare-sm");
279 
280 		fwnode_property_read_u32(node,
281 					 "mipi-sdw-port-channelprepare-timeout",
282 					 &dpn[i].ch_prep_timeout);
283 
284 		fwnode_property_read_u32(node,
285 				"mipi-sdw-imp-def-dpn-interrupts-supported",
286 				&dpn[i].imp_def_interrupts);
287 
288 		fwnode_property_read_u32(node, "mipi-sdw-min-channel-number",
289 					 &dpn[i].min_ch);
290 
291 		fwnode_property_read_u32(node, "mipi-sdw-max-channel-number",
292 					 &dpn[i].max_ch);
293 
294 		nval = fwnode_property_count_u32(node, "mipi-sdw-channel-number-list");
295 		if (nval > 0) {
296 			dpn[i].num_channels = nval;
297 			dpn[i].channels = devm_kcalloc(&slave->dev,
298 						       dpn[i].num_channels,
299 						       sizeof(*dpn[i].channels),
300 						 GFP_KERNEL);
301 			if (!dpn[i].channels) {
302 				fwnode_handle_put(node);
303 				return -ENOMEM;
304 			}
305 
306 			ret = fwnode_property_read_u32_array(node,
307 					"mipi-sdw-channel-number-list",
308 					dpn[i].channels, dpn[i].num_channels);
309 			if (ret < 0)
310 				return ret;
311 		}
312 
313 		nval = fwnode_property_count_u32(node, "mipi-sdw-channel-combination-list");
314 		if (nval > 0) {
315 			dpn[i].num_ch_combinations = nval;
316 			dpn[i].ch_combinations = devm_kcalloc(&slave->dev,
317 					dpn[i].num_ch_combinations,
318 					sizeof(*dpn[i].ch_combinations),
319 					GFP_KERNEL);
320 			if (!dpn[i].ch_combinations) {
321 				fwnode_handle_put(node);
322 				return -ENOMEM;
323 			}
324 
325 			ret = fwnode_property_read_u32_array(node,
326 					"mipi-sdw-channel-combination-list",
327 					dpn[i].ch_combinations,
328 					dpn[i].num_ch_combinations);
329 			if (ret < 0)
330 				return ret;
331 		}
332 
333 		fwnode_property_read_u32(node,
334 				"mipi-sdw-modes-supported", &dpn[i].modes);
335 
336 		fwnode_property_read_u32(node, "mipi-sdw-max-async-buffer",
337 					 &dpn[i].max_async_buffer);
338 
339 		dpn[i].block_pack_mode = mipi_fwnode_property_read_bool(node,
340 				"mipi-sdw-block-packing-mode");
341 
342 		fwnode_property_read_u32(node, "mipi-sdw-port-encoding-type",
343 					 &dpn[i].port_encoding);
344 
345 		nval = fwnode_property_count_u32(node, "mipi-sdw-lane-list");
346 		if (nval > 0) {
347 			dpn[i].num_lanes = nval;
348 			dpn[i].lane_list = devm_kcalloc(&slave->dev,
349 							dpn[i].num_lanes, sizeof(*dpn[i].lane_list),
350 							GFP_KERNEL);
351 			if (!dpn[i].lane_list)
352 				return -ENOMEM;
353 
354 			ret = fwnode_property_read_u32_array(node,
355 						       "mipi-sdw-lane-list",
356 						       dpn[i].lane_list, dpn[i].num_lanes);
357 			if (ret < 0)
358 				return ret;
359 		}
360 
361 		fwnode_handle_put(node);
362 
363 		i++;
364 	}
365 
366 	return 0;
367 }
368 
369 /**
370  * sdw_slave_read_prop() - Read Slave properties
371  * @slave: SDW Slave
372  */
373 int sdw_slave_read_prop(struct sdw_slave *slave)
374 {
375 	struct sdw_slave_prop *prop = &slave->prop;
376 	struct device *dev = &slave->dev;
377 	struct fwnode_handle *port;
378 	int nval;
379 	int ret;
380 
381 	device_property_read_u32(dev, "mipi-sdw-sw-interface-revision",
382 				 &prop->mipi_revision);
383 
384 	prop->wake_capable = mipi_device_property_read_bool(dev,
385 				"mipi-sdw-wake-up-unavailable");
386 	prop->wake_capable = !prop->wake_capable;
387 
388 	prop->test_mode_capable = mipi_device_property_read_bool(dev,
389 				"mipi-sdw-test-mode-supported");
390 
391 	prop->clk_stop_mode1 = false;
392 	if (mipi_device_property_read_bool(dev,
393 				"mipi-sdw-clock-stop-mode1-supported"))
394 		prop->clk_stop_mode1 = true;
395 
396 	prop->simple_clk_stop_capable = mipi_device_property_read_bool(dev,
397 			"mipi-sdw-simplified-clockstopprepare-sm-supported");
398 
399 	device_property_read_u32(dev, "mipi-sdw-clockstopprepare-timeout",
400 				 &prop->clk_stop_timeout);
401 
402 	ret = device_property_read_u32(dev, "mipi-sdw-peripheral-channelprepare-timeout",
403 				       &prop->ch_prep_timeout);
404 	if (ret < 0)
405 		device_property_read_u32(dev, "mipi-sdw-slave-channelprepare-timeout",
406 					 &prop->ch_prep_timeout);
407 
408 	device_property_read_u32(dev,
409 			"mipi-sdw-clockstopprepare-hard-reset-behavior",
410 			&prop->reset_behave);
411 
412 	prop->high_PHY_capable = mipi_device_property_read_bool(dev,
413 			"mipi-sdw-highPHY-capable");
414 
415 	prop->paging_support = mipi_device_property_read_bool(dev,
416 			"mipi-sdw-paging-support");
417 
418 	prop->bank_delay_support = mipi_device_property_read_bool(dev,
419 			"mipi-sdw-bank-delay-support");
420 
421 	device_property_read_u32(dev,
422 			"mipi-sdw-port15-read-behavior", &prop->p15_behave);
423 
424 	device_property_read_u32(dev, "mipi-sdw-master-count",
425 				 &prop->master_count);
426 
427 	device_property_read_u32(dev, "mipi-sdw-source-port-list",
428 				 &prop->source_ports);
429 
430 	device_property_read_u32(dev, "mipi-sdw-sink-port-list",
431 				 &prop->sink_ports);
432 
433 	device_property_read_u32(dev, "mipi-sdw-sdca-interrupt-register-list",
434 				 &prop->sdca_interrupt_register_list);
435 
436 	prop->commit_register_supported = mipi_device_property_read_bool(dev,
437 			"mipi-sdw-commit-register-supported");
438 
439 	/*
440 	 * Read dp0 properties - we don't rely on the 'mipi-sdw-dp-0-supported'
441 	 * property since the 'mipi-sdw-dp0-subproperties' property is logically
442 	 * equivalent.
443 	 */
444 	port = device_get_named_child_node(dev, "mipi-sdw-dp-0-subproperties");
445 	if (!port) {
446 		dev_dbg(dev, "DP0 node not found!!\n");
447 	} else {
448 		prop->dp0_prop = devm_kzalloc(&slave->dev,
449 					      sizeof(*prop->dp0_prop),
450 					      GFP_KERNEL);
451 		if (!prop->dp0_prop) {
452 			fwnode_handle_put(port);
453 			return -ENOMEM;
454 		}
455 
456 		sdw_slave_read_dp0(slave, port, prop->dp0_prop);
457 
458 		fwnode_handle_put(port);
459 	}
460 
461 	/*
462 	 * Based on each DPn port, get source and sink dpn properties.
463 	 * Also, some ports can operate as both source or sink.
464 	 */
465 
466 	/* Allocate memory for set bits in port lists */
467 	nval = hweight32(prop->source_ports);
468 	prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
469 					  sizeof(*prop->src_dpn_prop),
470 					  GFP_KERNEL);
471 	if (!prop->src_dpn_prop)
472 		return -ENOMEM;
473 
474 	/* Read dpn properties for source port(s) */
475 	sdw_slave_read_dpn(slave, prop->src_dpn_prop, nval,
476 			   prop->source_ports, "source");
477 
478 	nval = hweight32(prop->sink_ports);
479 	prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,
480 					   sizeof(*prop->sink_dpn_prop),
481 					   GFP_KERNEL);
482 	if (!prop->sink_dpn_prop)
483 		return -ENOMEM;
484 
485 	/* Read dpn properties for sink port(s) */
486 	sdw_slave_read_dpn(slave, prop->sink_dpn_prop, nval,
487 			   prop->sink_ports, "sink");
488 
489 	return 0;
490 }
491 EXPORT_SYMBOL(sdw_slave_read_prop);
492