Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  4 */
  5
  6
  7#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
  8
  9#include <linux/of_platform.h>
 10
 11#include <drm/display/drm_dp_helper.h>
 12#include <drm/drm_edid.h>
 13
 14#include "dp_catalog.h"
 15#include "dp_audio.h"
 16#include "dp_panel.h"
 17#include "dp_display.h"
 18
 19#define HEADER_BYTE_2_BIT	 0
 20#define PARITY_BYTE_2_BIT	 8
 21#define HEADER_BYTE_1_BIT	16
 22#define PARITY_BYTE_1_BIT	24
 23#define HEADER_BYTE_3_BIT	16
 24#define PARITY_BYTE_3_BIT	24
 25
 26struct dp_audio_private {
 27	struct platform_device *audio_pdev;
 28	struct platform_device *pdev;
 29	struct drm_device *drm_dev;
 30	struct dp_catalog *catalog;
 31	struct dp_panel *panel;
 32
 33	bool engine_on;
 34	u32 channels;
 35
 36	struct dp_audio dp_audio;
 37};
 38
 39static u8 dp_audio_get_g0_value(u8 data)
 40{
 41	u8 c[4];
 42	u8 g[4];
 43	u8 ret_data = 0;
 44	u8 i;
 45
 46	for (i = 0; i < 4; i++)
 47		c[i] = (data >> i) & 0x01;
 48
 49	g[0] = c[3];
 50	g[1] = c[0] ^ c[3];
 51	g[2] = c[1];
 52	g[3] = c[2];
 53
 54	for (i = 0; i < 4; i++)
 55		ret_data = ((g[i] & 0x01) << i) | ret_data;
 56
 57	return ret_data;
 58}
 59
 60static u8 dp_audio_get_g1_value(u8 data)
 61{
 62	u8 c[4];
 63	u8 g[4];
 64	u8 ret_data = 0;
 65	u8 i;
 66
 67	for (i = 0; i < 4; i++)
 68		c[i] = (data >> i) & 0x01;
 69
 70	g[0] = c[0] ^ c[3];
 71	g[1] = c[0] ^ c[1] ^ c[3];
 72	g[2] = c[1] ^ c[2];
 73	g[3] = c[2] ^ c[3];
 74
 75	for (i = 0; i < 4; i++)
 76		ret_data = ((g[i] & 0x01) << i) | ret_data;
 77
 78	return ret_data;
 79}
 80
 81static u8 dp_audio_calculate_parity(u32 data)
 82{
 83	u8 x0 = 0;
 84	u8 x1 = 0;
 85	u8 ci = 0;
 86	u8 iData = 0;
 87	u8 i = 0;
 88	u8 parity_byte;
 89	u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2;
 90
 91	for (i = 0; i < num_byte; i++) {
 92		iData = (data >> i*4) & 0xF;
 93
 94		ci = iData ^ x1;
 95		x1 = x0 ^ dp_audio_get_g1_value(ci);
 96		x0 = dp_audio_get_g0_value(ci);
 97	}
 98
 99	parity_byte = x1 | (x0 << 4);
100
101	return parity_byte;
102}
103
104static u32 dp_audio_get_header(struct dp_catalog *catalog,
105		enum dp_catalog_audio_sdp_type sdp,
106		enum dp_catalog_audio_header_type header)
107{
108	catalog->sdp_type = sdp;
109	catalog->sdp_header = header;
110	dp_catalog_audio_get_header(catalog);
111
112	return catalog->audio_data;
113}
114
115static void dp_audio_set_header(struct dp_catalog *catalog,
116		u32 data,
117		enum dp_catalog_audio_sdp_type sdp,
118		enum dp_catalog_audio_header_type header)
119{
120	catalog->sdp_type = sdp;
121	catalog->sdp_header = header;
122	catalog->audio_data = data;
123	dp_catalog_audio_set_header(catalog);
124}
125
126static void dp_audio_stream_sdp(struct dp_audio_private *audio)
127{
128	struct dp_catalog *catalog = audio->catalog;
129	u32 value, new_value;
130	u8 parity_byte;
131
132	/* Config header and parity byte 1 */
133	value = dp_audio_get_header(catalog,
134			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
135
136	new_value = 0x02;
137	parity_byte = dp_audio_calculate_parity(new_value);
138	value |= ((new_value << HEADER_BYTE_1_BIT)
139			| (parity_byte << PARITY_BYTE_1_BIT));
140	drm_dbg_dp(audio->drm_dev,
141			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
142			value, parity_byte);
143	dp_audio_set_header(catalog, value,
144		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
145
146	/* Config header and parity byte 2 */
147	value = dp_audio_get_header(catalog,
148			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
149	new_value = value;
150	parity_byte = dp_audio_calculate_parity(new_value);
151	value |= ((new_value << HEADER_BYTE_2_BIT)
152			| (parity_byte << PARITY_BYTE_2_BIT));
153	drm_dbg_dp(audio->drm_dev,
154			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
155			value, parity_byte);
156
157	dp_audio_set_header(catalog, value,
158		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
159
160	/* Config header and parity byte 3 */
161	value = dp_audio_get_header(catalog,
162			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
163
164	new_value = audio->channels - 1;
165	parity_byte = dp_audio_calculate_parity(new_value);
166	value |= ((new_value << HEADER_BYTE_3_BIT)
167			| (parity_byte << PARITY_BYTE_3_BIT));
168	drm_dbg_dp(audio->drm_dev,
169			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
170		value, parity_byte);
171
172	dp_audio_set_header(catalog, value,
173		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
174}
175
176static void dp_audio_timestamp_sdp(struct dp_audio_private *audio)
177{
178	struct dp_catalog *catalog = audio->catalog;
179	u32 value, new_value;
180	u8 parity_byte;
181
182	/* Config header and parity byte 1 */
183	value = dp_audio_get_header(catalog,
184			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
185
186	new_value = 0x1;
187	parity_byte = dp_audio_calculate_parity(new_value);
188	value |= ((new_value << HEADER_BYTE_1_BIT)
189			| (parity_byte << PARITY_BYTE_1_BIT));
190	drm_dbg_dp(audio->drm_dev,
191			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
192			value, parity_byte);
193	dp_audio_set_header(catalog, value,
194		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
195
196	/* Config header and parity byte 2 */
197	value = dp_audio_get_header(catalog,
198			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
199
200	new_value = 0x17;
201	parity_byte = dp_audio_calculate_parity(new_value);
202	value |= ((new_value << HEADER_BYTE_2_BIT)
203			| (parity_byte << PARITY_BYTE_2_BIT));
204	drm_dbg_dp(audio->drm_dev,
205			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
206			value, parity_byte);
207	dp_audio_set_header(catalog, value,
208		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
209
210	/* Config header and parity byte 3 */
211	value = dp_audio_get_header(catalog,
212			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
213
214	new_value = (0x0 | (0x11 << 2));
215	parity_byte = dp_audio_calculate_parity(new_value);
216	value |= ((new_value << HEADER_BYTE_3_BIT)
217			| (parity_byte << PARITY_BYTE_3_BIT));
218	drm_dbg_dp(audio->drm_dev,
219			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
220			value, parity_byte);
221	dp_audio_set_header(catalog, value,
222		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
223}
224
225static void dp_audio_infoframe_sdp(struct dp_audio_private *audio)
226{
227	struct dp_catalog *catalog = audio->catalog;
228	u32 value, new_value;
229	u8 parity_byte;
230
231	/* Config header and parity byte 1 */
232	value = dp_audio_get_header(catalog,
233			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
234
235	new_value = 0x84;
236	parity_byte = dp_audio_calculate_parity(new_value);
237	value |= ((new_value << HEADER_BYTE_1_BIT)
238			| (parity_byte << PARITY_BYTE_1_BIT));
239	drm_dbg_dp(audio->drm_dev,
240			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
241			value, parity_byte);
242	dp_audio_set_header(catalog, value,
243		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
244
245	/* Config header and parity byte 2 */
246	value = dp_audio_get_header(catalog,
247			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
248
249	new_value = 0x1b;
250	parity_byte = dp_audio_calculate_parity(new_value);
251	value |= ((new_value << HEADER_BYTE_2_BIT)
252			| (parity_byte << PARITY_BYTE_2_BIT));
253	drm_dbg_dp(audio->drm_dev,
254			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
255			value, parity_byte);
256	dp_audio_set_header(catalog, value,
257		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
258
259	/* Config header and parity byte 3 */
260	value = dp_audio_get_header(catalog,
261			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
262
263	new_value = (0x0 | (0x11 << 2));
264	parity_byte = dp_audio_calculate_parity(new_value);
265	value |= ((new_value << HEADER_BYTE_3_BIT)
266			| (parity_byte << PARITY_BYTE_3_BIT));
267	drm_dbg_dp(audio->drm_dev,
268			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
269			new_value, parity_byte);
270	dp_audio_set_header(catalog, value,
271		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
272}
273
274static void dp_audio_copy_management_sdp(struct dp_audio_private *audio)
275{
276	struct dp_catalog *catalog = audio->catalog;
277	u32 value, new_value;
278	u8 parity_byte;
279
280	/* Config header and parity byte 1 */
281	value = dp_audio_get_header(catalog,
282			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
283
284	new_value = 0x05;
285	parity_byte = dp_audio_calculate_parity(new_value);
286	value |= ((new_value << HEADER_BYTE_1_BIT)
287			| (parity_byte << PARITY_BYTE_1_BIT));
288	drm_dbg_dp(audio->drm_dev,
289			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
290			value, parity_byte);
291	dp_audio_set_header(catalog, value,
292		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
293
294	/* Config header and parity byte 2 */
295	value = dp_audio_get_header(catalog,
296			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
297
298	new_value = 0x0F;
299	parity_byte = dp_audio_calculate_parity(new_value);
300	value |= ((new_value << HEADER_BYTE_2_BIT)
301			| (parity_byte << PARITY_BYTE_2_BIT));
302	drm_dbg_dp(audio->drm_dev,
303			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
304			value, parity_byte);
305	dp_audio_set_header(catalog, value,
306		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
307
308	/* Config header and parity byte 3 */
309	value = dp_audio_get_header(catalog,
310			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
311
312	new_value = 0x0;
313	parity_byte = dp_audio_calculate_parity(new_value);
314	value |= ((new_value << HEADER_BYTE_3_BIT)
315			| (parity_byte << PARITY_BYTE_3_BIT));
316	drm_dbg_dp(audio->drm_dev,
317			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
318			value, parity_byte);
319	dp_audio_set_header(catalog, value,
320		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
321}
322
323static void dp_audio_isrc_sdp(struct dp_audio_private *audio)
324{
325	struct dp_catalog *catalog = audio->catalog;
326	u32 value, new_value;
327	u8 parity_byte;
328
329	/* Config header and parity byte 1 */
330	value = dp_audio_get_header(catalog,
331			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
332
333	new_value = 0x06;
334	parity_byte = dp_audio_calculate_parity(new_value);
335	value |= ((new_value << HEADER_BYTE_1_BIT)
336			| (parity_byte << PARITY_BYTE_1_BIT));
337	drm_dbg_dp(audio->drm_dev,
338			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
339			value, parity_byte);
340	dp_audio_set_header(catalog, value,
341		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
342
343	/* Config header and parity byte 2 */
344	value = dp_audio_get_header(catalog,
345			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
346
347	new_value = 0x0F;
348	parity_byte = dp_audio_calculate_parity(new_value);
349	value |= ((new_value << HEADER_BYTE_2_BIT)
350			| (parity_byte << PARITY_BYTE_2_BIT));
351	drm_dbg_dp(audio->drm_dev,
352			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
353			value, parity_byte);
354	dp_audio_set_header(catalog, value,
355		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
356}
357
358static void dp_audio_setup_sdp(struct dp_audio_private *audio)
359{
360	dp_catalog_audio_config_sdp(audio->catalog);
361
362	dp_audio_stream_sdp(audio);
363	dp_audio_timestamp_sdp(audio);
364	dp_audio_infoframe_sdp(audio);
365	dp_audio_copy_management_sdp(audio);
366	dp_audio_isrc_sdp(audio);
367}
368
369static void dp_audio_setup_acr(struct dp_audio_private *audio)
370{
371	u32 select = 0;
372	struct dp_catalog *catalog = audio->catalog;
373
374	switch (audio->dp_audio.bw_code) {
375	case DP_LINK_BW_1_62:
376		select = 0;
377		break;
378	case DP_LINK_BW_2_7:
379		select = 1;
380		break;
381	case DP_LINK_BW_5_4:
382		select = 2;
383		break;
384	case DP_LINK_BW_8_1:
385		select = 3;
386		break;
387	default:
388		drm_dbg_dp(audio->drm_dev, "Unknown link rate\n");
389		select = 0;
390		break;
391	}
392
393	catalog->audio_data = select;
394	dp_catalog_audio_config_acr(catalog);
395}
396
397static void dp_audio_safe_to_exit_level(struct dp_audio_private *audio)
398{
399	struct dp_catalog *catalog = audio->catalog;
400	u32 safe_to_exit_level = 0;
401
402	switch (audio->dp_audio.lane_count) {
403	case 1:
404		safe_to_exit_level = 14;
405		break;
406	case 2:
407		safe_to_exit_level = 8;
408		break;
409	case 4:
410		safe_to_exit_level = 5;
411		break;
412	default:
413		drm_dbg_dp(audio->drm_dev,
414				"setting the default safe_to_exit_level = %u\n",
415				safe_to_exit_level);
416		safe_to_exit_level = 14;
417		break;
418	}
419
420	catalog->audio_data = safe_to_exit_level;
421	dp_catalog_audio_sfe_level(catalog);
422}
423
424static void dp_audio_enable(struct dp_audio_private *audio, bool enable)
425{
426	struct dp_catalog *catalog = audio->catalog;
427
428	catalog->audio_data = enable;
429	dp_catalog_audio_enable(catalog);
430
431	audio->engine_on = enable;
432}
433
434static struct dp_audio_private *dp_audio_get_data(struct platform_device *pdev)
435{
436	struct dp_audio *dp_audio;
437	struct msm_dp *dp_display;
438
439	if (!pdev) {
440		DRM_ERROR("invalid input\n");
441		return ERR_PTR(-ENODEV);
442	}
443
444	dp_display = platform_get_drvdata(pdev);
445	if (!dp_display) {
446		DRM_ERROR("invalid input\n");
447		return ERR_PTR(-ENODEV);
448	}
449
450	dp_audio = dp_display->dp_audio;
451
452	if (!dp_audio) {
453		DRM_ERROR("invalid dp_audio data\n");
454		return ERR_PTR(-EINVAL);
455	}
456
457	return container_of(dp_audio, struct dp_audio_private, dp_audio);
458}
459
460static int dp_audio_hook_plugged_cb(struct device *dev, void *data,
461		hdmi_codec_plugged_cb fn,
462		struct device *codec_dev)
463{
464
465	struct platform_device *pdev;
466	struct msm_dp *dp_display;
467
468	pdev = to_platform_device(dev);
469	if (!pdev) {
470		pr_err("invalid input\n");
471		return -ENODEV;
472	}
473
474	dp_display = platform_get_drvdata(pdev);
475	if (!dp_display) {
476		pr_err("invalid input\n");
477		return -ENODEV;
478	}
479
480	return dp_display_set_plugged_cb(dp_display, fn, codec_dev);
481}
482
483static int dp_audio_get_eld(struct device *dev,
484	void *data, uint8_t *buf, size_t len)
485{
486	struct platform_device *pdev;
487	struct msm_dp *dp_display;
488
489	pdev = to_platform_device(dev);
490
491	if (!pdev) {
492		DRM_ERROR("invalid input\n");
493		return -ENODEV;
494	}
495
496	dp_display = platform_get_drvdata(pdev);
497	if (!dp_display) {
498		DRM_ERROR("invalid input\n");
499		return -ENODEV;
500	}
501
502	memcpy(buf, dp_display->connector->eld,
503		min(sizeof(dp_display->connector->eld), len));
504
505	return 0;
506}
507
508int dp_audio_hw_params(struct device *dev,
509	void *data,
510	struct hdmi_codec_daifmt *daifmt,
511	struct hdmi_codec_params *params)
512{
513	int rc = 0;
514	struct dp_audio_private *audio;
515	struct platform_device *pdev;
516	struct msm_dp *dp_display;
517
518	pdev = to_platform_device(dev);
519	dp_display = platform_get_drvdata(pdev);
520
521	/*
522	 * there could be cases where sound card can be opened even
523	 * before OR even when DP is not connected . This can cause
524	 * unclocked access as the audio subsystem relies on the DP
525	 * driver to maintain the correct state of clocks. To protect
526	 * such cases check for connection status and bail out if not
527	 * connected.
528	 */
529	if (!dp_display->power_on) {
530		rc = -EINVAL;
531		goto end;
532	}
533
534	audio = dp_audio_get_data(pdev);
535	if (IS_ERR(audio)) {
536		rc = PTR_ERR(audio);
537		goto end;
538	}
539
540	audio->channels = params->channels;
541
542	dp_audio_setup_sdp(audio);
543	dp_audio_setup_acr(audio);
544	dp_audio_safe_to_exit_level(audio);
545	dp_audio_enable(audio, true);
546	dp_display_signal_audio_start(dp_display);
547	dp_display->audio_enabled = true;
548
549end:
550	return rc;
551}
552
553static void dp_audio_shutdown(struct device *dev, void *data)
554{
555	struct dp_audio_private *audio;
556	struct platform_device *pdev;
557	struct msm_dp *dp_display;
558
559	pdev = to_platform_device(dev);
560	dp_display = platform_get_drvdata(pdev);
561	audio = dp_audio_get_data(pdev);
562	if (IS_ERR(audio)) {
563		DRM_ERROR("failed to get audio data\n");
564		return;
565	}
566
567	/*
568	 * if audio was not enabled there is no need
569	 * to execute the shutdown and we can bail out early.
570	 * This also makes sure that we dont cause an unclocked
571	 * access when audio subsystem calls this without DP being
572	 * connected. is_connected cannot be used here as its set
573	 * to false earlier than this call
574	 */
575	if (!dp_display->audio_enabled)
576		return;
577
578	dp_audio_enable(audio, false);
579	/* signal the dp display to safely shutdown clocks */
580	dp_display_signal_audio_complete(dp_display);
581}
582
583static const struct hdmi_codec_ops dp_audio_codec_ops = {
584	.hw_params = dp_audio_hw_params,
585	.audio_shutdown = dp_audio_shutdown,
586	.get_eld = dp_audio_get_eld,
587	.hook_plugged_cb = dp_audio_hook_plugged_cb,
588};
589
590static struct hdmi_codec_pdata codec_data = {
591	.ops = &dp_audio_codec_ops,
592	.max_i2s_channels = 8,
593	.i2s = 1,
594};
595
596int dp_register_audio_driver(struct device *dev,
597		struct dp_audio *dp_audio)
598{
599	struct dp_audio_private *audio_priv;
600
601	audio_priv = container_of(dp_audio,
602			struct dp_audio_private, dp_audio);
603
604	audio_priv->audio_pdev = platform_device_register_data(dev,
605						HDMI_CODEC_DRV_NAME,
606						PLATFORM_DEVID_AUTO,
607						&codec_data,
608						sizeof(codec_data));
609	return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
610}
611
612struct dp_audio *dp_audio_get(struct platform_device *pdev,
613			struct dp_panel *panel,
614			struct dp_catalog *catalog)
615{
616	int rc = 0;
617	struct dp_audio_private *audio;
618	struct dp_audio *dp_audio;
619
620	if (!pdev || !panel || !catalog) {
621		DRM_ERROR("invalid input\n");
622		rc = -EINVAL;
623		goto error;
624	}
625
626	audio = devm_kzalloc(&pdev->dev, sizeof(*audio), GFP_KERNEL);
627	if (!audio) {
628		rc = -ENOMEM;
629		goto error;
630	}
631
632	audio->pdev = pdev;
633	audio->panel = panel;
634	audio->catalog = catalog;
635
636	dp_audio = &audio->dp_audio;
637
638	dp_catalog_audio_init(catalog);
639
640	return dp_audio;
641error:
642	return ERR_PTR(rc);
643}
644
645void dp_audio_put(struct dp_audio *dp_audio)
646{
647	struct dp_audio_private *audio;
648
649	if (!dp_audio)
650		return;
651
652	audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
653
654	devm_kfree(&audio->pdev->dev, audio);
655}