1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
7 #define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
9 #include <linux/platform_device.h>
11 #include <drm/display/drm_dp_helper.h>
12 #include <drm/drm_edid.h>
14 #include "dp_catalog.h"
17 #include "dp_display.h"
20 struct msm_dp_audio_private {
21 struct platform_device *audio_pdev;
22 struct platform_device *pdev;
23 struct drm_device *drm_dev;
24 struct msm_dp_catalog *catalog;
28 struct msm_dp_audio msm_dp_audio;
31 static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
32 enum msm_dp_catalog_audio_sdp_type sdp,
33 enum msm_dp_catalog_audio_header_type header)
35 return msm_dp_catalog_audio_get_header(catalog, sdp, header);
38 static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
40 enum msm_dp_catalog_audio_sdp_type sdp,
41 enum msm_dp_catalog_audio_header_type header)
43 msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
46 static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
48 struct msm_dp_catalog *catalog = audio->catalog;
52 /* Config header and parity byte 1 */
53 value = msm_dp_audio_get_header(catalog,
54 DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
57 parity_byte = msm_dp_utils_calculate_parity(new_value);
58 value |= ((new_value << HEADER_BYTE_1_BIT)
59 | (parity_byte << PARITY_BYTE_1_BIT));
60 drm_dbg_dp(audio->drm_dev,
61 "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
63 msm_dp_audio_set_header(catalog, value,
64 DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
66 /* Config header and parity byte 2 */
67 value = msm_dp_audio_get_header(catalog,
68 DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
70 parity_byte = msm_dp_utils_calculate_parity(new_value);
71 value |= ((new_value << HEADER_BYTE_2_BIT)
72 | (parity_byte << PARITY_BYTE_2_BIT));
73 drm_dbg_dp(audio->drm_dev,
74 "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
77 msm_dp_audio_set_header(catalog, value,
78 DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
80 /* Config header and parity byte 3 */
81 value = msm_dp_audio_get_header(catalog,
82 DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
84 new_value = audio->channels - 1;
85 parity_byte = msm_dp_utils_calculate_parity(new_value);
86 value |= ((new_value << HEADER_BYTE_3_BIT)
87 | (parity_byte << PARITY_BYTE_3_BIT));
88 drm_dbg_dp(audio->drm_dev,
89 "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
92 msm_dp_audio_set_header(catalog, value,
93 DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
96 static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
98 struct msm_dp_catalog *catalog = audio->catalog;
102 /* Config header and parity byte 1 */
103 value = msm_dp_audio_get_header(catalog,
104 DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
107 parity_byte = msm_dp_utils_calculate_parity(new_value);
108 value |= ((new_value << HEADER_BYTE_1_BIT)
109 | (parity_byte << PARITY_BYTE_1_BIT));
110 drm_dbg_dp(audio->drm_dev,
111 "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
113 msm_dp_audio_set_header(catalog, value,
114 DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
116 /* Config header and parity byte 2 */
117 value = msm_dp_audio_get_header(catalog,
118 DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
121 parity_byte = msm_dp_utils_calculate_parity(new_value);
122 value |= ((new_value << HEADER_BYTE_2_BIT)
123 | (parity_byte << PARITY_BYTE_2_BIT));
124 drm_dbg_dp(audio->drm_dev,
125 "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
127 msm_dp_audio_set_header(catalog, value,
128 DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
130 /* Config header and parity byte 3 */
131 value = msm_dp_audio_get_header(catalog,
132 DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
134 new_value = (0x0 | (0x11 << 2));
135 parity_byte = msm_dp_utils_calculate_parity(new_value);
136 value |= ((new_value << HEADER_BYTE_3_BIT)
137 | (parity_byte << PARITY_BYTE_3_BIT));
138 drm_dbg_dp(audio->drm_dev,
139 "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
141 msm_dp_audio_set_header(catalog, value,
142 DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
145 static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
147 struct msm_dp_catalog *catalog = audio->catalog;
148 u32 value, new_value;
151 /* Config header and parity byte 1 */
152 value = msm_dp_audio_get_header(catalog,
153 DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
156 parity_byte = msm_dp_utils_calculate_parity(new_value);
157 value |= ((new_value << HEADER_BYTE_1_BIT)
158 | (parity_byte << PARITY_BYTE_1_BIT));
159 drm_dbg_dp(audio->drm_dev,
160 "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
162 msm_dp_audio_set_header(catalog, value,
163 DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
165 /* Config header and parity byte 2 */
166 value = msm_dp_audio_get_header(catalog,
167 DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
170 parity_byte = msm_dp_utils_calculate_parity(new_value);
171 value |= ((new_value << HEADER_BYTE_2_BIT)
172 | (parity_byte << PARITY_BYTE_2_BIT));
173 drm_dbg_dp(audio->drm_dev,
174 "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
176 msm_dp_audio_set_header(catalog, value,
177 DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
179 /* Config header and parity byte 3 */
180 value = msm_dp_audio_get_header(catalog,
181 DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
183 new_value = (0x0 | (0x11 << 2));
184 parity_byte = msm_dp_utils_calculate_parity(new_value);
185 value |= ((new_value << HEADER_BYTE_3_BIT)
186 | (parity_byte << PARITY_BYTE_3_BIT));
187 drm_dbg_dp(audio->drm_dev,
188 "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
189 new_value, parity_byte);
190 msm_dp_audio_set_header(catalog, value,
191 DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
194 static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
196 struct msm_dp_catalog *catalog = audio->catalog;
197 u32 value, new_value;
200 /* Config header and parity byte 1 */
201 value = msm_dp_audio_get_header(catalog,
202 DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
205 parity_byte = msm_dp_utils_calculate_parity(new_value);
206 value |= ((new_value << HEADER_BYTE_1_BIT)
207 | (parity_byte << PARITY_BYTE_1_BIT));
208 drm_dbg_dp(audio->drm_dev,
209 "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
211 msm_dp_audio_set_header(catalog, value,
212 DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
214 /* Config header and parity byte 2 */
215 value = msm_dp_audio_get_header(catalog,
216 DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
219 parity_byte = msm_dp_utils_calculate_parity(new_value);
220 value |= ((new_value << HEADER_BYTE_2_BIT)
221 | (parity_byte << PARITY_BYTE_2_BIT));
222 drm_dbg_dp(audio->drm_dev,
223 "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
225 msm_dp_audio_set_header(catalog, value,
226 DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
228 /* Config header and parity byte 3 */
229 value = msm_dp_audio_get_header(catalog,
230 DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
233 parity_byte = msm_dp_utils_calculate_parity(new_value);
234 value |= ((new_value << HEADER_BYTE_3_BIT)
235 | (parity_byte << PARITY_BYTE_3_BIT));
236 drm_dbg_dp(audio->drm_dev,
237 "Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
239 msm_dp_audio_set_header(catalog, value,
240 DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
243 static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
245 struct msm_dp_catalog *catalog = audio->catalog;
246 u32 value, new_value;
249 /* Config header and parity byte 1 */
250 value = msm_dp_audio_get_header(catalog,
251 DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
254 parity_byte = msm_dp_utils_calculate_parity(new_value);
255 value |= ((new_value << HEADER_BYTE_1_BIT)
256 | (parity_byte << PARITY_BYTE_1_BIT));
257 drm_dbg_dp(audio->drm_dev,
258 "Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
260 msm_dp_audio_set_header(catalog, value,
261 DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
263 /* Config header and parity byte 2 */
264 value = msm_dp_audio_get_header(catalog,
265 DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
268 parity_byte = msm_dp_utils_calculate_parity(new_value);
269 value |= ((new_value << HEADER_BYTE_2_BIT)
270 | (parity_byte << PARITY_BYTE_2_BIT));
271 drm_dbg_dp(audio->drm_dev,
272 "Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
274 msm_dp_audio_set_header(catalog, value,
275 DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
278 static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
280 msm_dp_catalog_audio_config_sdp(audio->catalog);
282 msm_dp_audio_stream_sdp(audio);
283 msm_dp_audio_timestamp_sdp(audio);
284 msm_dp_audio_infoframe_sdp(audio);
285 msm_dp_audio_copy_management_sdp(audio);
286 msm_dp_audio_isrc_sdp(audio);
289 static void msm_dp_audio_setup_acr(struct msm_dp_audio_private *audio)
292 struct msm_dp_catalog *catalog = audio->catalog;
294 switch (audio->msm_dp_audio.bw_code) {
295 case DP_LINK_BW_1_62:
308 drm_dbg_dp(audio->drm_dev, "Unknown link rate\n");
313 msm_dp_catalog_audio_config_acr(catalog, select);
316 static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
318 struct msm_dp_catalog *catalog = audio->catalog;
319 u32 safe_to_exit_level = 0;
321 switch (audio->msm_dp_audio.lane_count) {
323 safe_to_exit_level = 14;
326 safe_to_exit_level = 8;
329 safe_to_exit_level = 5;
332 drm_dbg_dp(audio->drm_dev,
333 "setting the default safe_to_exit_level = %u\n",
335 safe_to_exit_level = 14;
339 msm_dp_catalog_audio_sfe_level(catalog, safe_to_exit_level);
342 static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable)
344 struct msm_dp_catalog *catalog = audio->catalog;
346 msm_dp_catalog_audio_enable(catalog, enable);
349 static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev)
351 struct msm_dp_audio *msm_dp_audio;
352 struct msm_dp *msm_dp_display;
355 DRM_ERROR("invalid input\n");
356 return ERR_PTR(-ENODEV);
359 msm_dp_display = platform_get_drvdata(pdev);
360 if (!msm_dp_display) {
361 DRM_ERROR("invalid input\n");
362 return ERR_PTR(-ENODEV);
365 msm_dp_audio = msm_dp_display->msm_dp_audio;
368 DRM_ERROR("invalid msm_dp_audio data\n");
369 return ERR_PTR(-EINVAL);
372 return container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
375 static int msm_dp_audio_hook_plugged_cb(struct device *dev, void *data,
376 hdmi_codec_plugged_cb fn,
377 struct device *codec_dev)
380 struct platform_device *pdev;
381 struct msm_dp *msm_dp_display;
383 pdev = to_platform_device(dev);
385 pr_err("invalid input\n");
389 msm_dp_display = platform_get_drvdata(pdev);
390 if (!msm_dp_display) {
391 pr_err("invalid input\n");
395 return msm_dp_display_set_plugged_cb(msm_dp_display, fn, codec_dev);
398 static int msm_dp_audio_get_eld(struct device *dev,
399 void *data, uint8_t *buf, size_t len)
401 struct platform_device *pdev;
402 struct msm_dp *msm_dp_display;
404 pdev = to_platform_device(dev);
407 DRM_ERROR("invalid input\n");
411 msm_dp_display = platform_get_drvdata(pdev);
412 if (!msm_dp_display) {
413 DRM_ERROR("invalid input\n");
417 memcpy(buf, msm_dp_display->connector->eld,
418 min(sizeof(msm_dp_display->connector->eld), len));
423 int msm_dp_audio_hw_params(struct device *dev,
425 struct hdmi_codec_daifmt *daifmt,
426 struct hdmi_codec_params *params)
429 struct msm_dp_audio_private *audio;
430 struct platform_device *pdev;
431 struct msm_dp *msm_dp_display;
433 pdev = to_platform_device(dev);
434 msm_dp_display = platform_get_drvdata(pdev);
437 * there could be cases where sound card can be opened even
438 * before OR even when DP is not connected . This can cause
439 * unclocked access as the audio subsystem relies on the DP
440 * driver to maintain the correct state of clocks. To protect
441 * such cases check for connection status and bail out if not
444 if (!msm_dp_display->power_on) {
449 audio = msm_dp_audio_get_data(pdev);
455 audio->channels = params->channels;
457 msm_dp_audio_setup_sdp(audio);
458 msm_dp_audio_setup_acr(audio);
459 msm_dp_audio_safe_to_exit_level(audio);
460 msm_dp_audio_enable(audio, true);
461 msm_dp_display_signal_audio_start(msm_dp_display);
462 msm_dp_display->audio_enabled = true;
468 static void msm_dp_audio_shutdown(struct device *dev, void *data)
470 struct msm_dp_audio_private *audio;
471 struct platform_device *pdev;
472 struct msm_dp *msm_dp_display;
474 pdev = to_platform_device(dev);
475 msm_dp_display = platform_get_drvdata(pdev);
476 audio = msm_dp_audio_get_data(pdev);
478 DRM_ERROR("failed to get audio data\n");
483 * if audio was not enabled there is no need
484 * to execute the shutdown and we can bail out early.
485 * This also makes sure that we dont cause an unclocked
486 * access when audio subsystem calls this without DP being
487 * connected. is_connected cannot be used here as its set
488 * to false earlier than this call
490 if (!msm_dp_display->audio_enabled)
493 msm_dp_audio_enable(audio, false);
494 /* signal the dp display to safely shutdown clocks */
495 msm_dp_display_signal_audio_complete(msm_dp_display);
498 static const struct hdmi_codec_ops msm_dp_audio_codec_ops = {
499 .hw_params = msm_dp_audio_hw_params,
500 .audio_shutdown = msm_dp_audio_shutdown,
501 .get_eld = msm_dp_audio_get_eld,
502 .hook_plugged_cb = msm_dp_audio_hook_plugged_cb,
505 static struct hdmi_codec_pdata codec_data = {
506 .ops = &msm_dp_audio_codec_ops,
507 .max_i2s_channels = 8,
511 void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio)
513 struct msm_dp_audio_private *audio_priv;
515 audio_priv = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
517 if (audio_priv->audio_pdev) {
518 platform_device_unregister(audio_priv->audio_pdev);
519 audio_priv->audio_pdev = NULL;
523 int msm_dp_register_audio_driver(struct device *dev,
524 struct msm_dp_audio *msm_dp_audio)
526 struct msm_dp_audio_private *audio_priv;
528 audio_priv = container_of(msm_dp_audio,
529 struct msm_dp_audio_private, msm_dp_audio);
531 audio_priv->audio_pdev = platform_device_register_data(dev,
536 return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
539 struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
540 struct msm_dp_panel *panel,
541 struct msm_dp_catalog *catalog)
544 struct msm_dp_audio_private *audio;
545 struct msm_dp_audio *msm_dp_audio;
547 if (!pdev || !panel || !catalog) {
548 DRM_ERROR("invalid input\n");
553 audio = devm_kzalloc(&pdev->dev, sizeof(*audio), GFP_KERNEL);
560 audio->catalog = catalog;
562 msm_dp_audio = &audio->msm_dp_audio;
564 msm_dp_catalog_audio_init(catalog);
571 void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio)
573 struct msm_dp_audio_private *audio;
578 audio = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
580 devm_kfree(&audio->pdev->dev, audio);