hdmi_audio.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2013 Red Hat
  4. * Author: Rob Clark <robdclark@gmail.com>
  5. */
  6. #include <drm/display/drm_hdmi_helper.h>
  7. #include <drm/display/drm_hdmi_state_helper.h>
  8. #include <linux/hdmi.h>
  9. #include <sound/hdmi-codec.h>
  10. #include "hdmi.h"
  11. int msm_hdmi_audio_update(struct hdmi *hdmi)
  12. {
  13. struct hdmi_audio *audio = &hdmi->audio;
  14. bool enabled = audio->enabled;
  15. uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl;
  16. uint32_t audio_config;
  17. if (!hdmi->connector->display_info.is_hdmi)
  18. return -EINVAL;
  19. DBG("audio: enabled=%d, channels=%d, rate=%d",
  20. audio->enabled, audio->channels, audio->rate);
  21. DBG("video: power_on=%d, pixclock=%lu", hdmi->power_on, hdmi->pixclock);
  22. if (enabled && !(hdmi->power_on && hdmi->pixclock)) {
  23. DBG("disabling audio: no video");
  24. enabled = false;
  25. }
  26. /* Read first before writing */
  27. acr_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_ACR_PKT_CTRL);
  28. vbi_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_VBI_PKT_CTRL);
  29. aud_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_AUDIO_PKT_CTRL1);
  30. audio_config = hdmi_read(hdmi, REG_HDMI_AUDIO_CFG);
  31. /* Clear N/CTS selection bits */
  32. acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_SELECT__MASK;
  33. if (enabled) {
  34. uint32_t n, cts, multiplier;
  35. enum hdmi_acr_cts select;
  36. drm_hdmi_acr_get_n_cts(hdmi->pixclock, audio->rate, &n, &cts);
  37. if (audio->rate == 192000 || audio->rate == 176400) {
  38. multiplier = 4;
  39. n >>= 2; /* divide N by 4 and use multiplier */
  40. } else if (audio->rate == 96000 || audio->rate == 88200) {
  41. multiplier = 2;
  42. n >>= 1; /* divide N by 2 and use multiplier */
  43. } else {
  44. multiplier = 1;
  45. }
  46. DBG("n=%u, cts=%u, multiplier=%u", n, cts, multiplier);
  47. acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SOURCE;
  48. acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_AUDIO_PRIORITY;
  49. acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_N_MULTIPLIER(multiplier);
  50. if (audio->rate == 48000 || audio->rate == 96000 ||
  51. audio->rate == 192000)
  52. select = ACR_48;
  53. else if (audio->rate == 44100 || audio->rate == 88200 ||
  54. audio->rate == 176400)
  55. select = ACR_44;
  56. else /* default to 32k */
  57. select = ACR_32;
  58. acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SELECT(select);
  59. hdmi_write(hdmi, REG_HDMI_ACR_0(select - 1),
  60. HDMI_ACR_0_CTS(cts));
  61. hdmi_write(hdmi, REG_HDMI_ACR_1(select - 1),
  62. HDMI_ACR_1_N(n));
  63. hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL2,
  64. COND(audio->channels != 2, HDMI_AUDIO_PKT_CTRL2_LAYOUT) |
  65. HDMI_AUDIO_PKT_CTRL2_OVERRIDE);
  66. acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_CONT;
  67. acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SEND;
  68. hdmi_write(hdmi, REG_HDMI_GC, 0);
  69. vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_ENABLE;
  70. vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
  71. aud_pkt_ctrl |= HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
  72. audio_config &= ~HDMI_AUDIO_CFG_FIFO_WATERMARK__MASK;
  73. audio_config |= HDMI_AUDIO_CFG_FIFO_WATERMARK(4);
  74. audio_config |= HDMI_AUDIO_CFG_ENGINE_ENABLE;
  75. } else {
  76. acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_CONT;
  77. acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_SEND;
  78. vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_ENABLE;
  79. vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
  80. aud_pkt_ctrl &= ~HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
  81. audio_config &= ~HDMI_AUDIO_CFG_ENGINE_ENABLE;
  82. }
  83. hdmi_write(hdmi, REG_HDMI_ACR_PKT_CTRL, acr_pkt_ctrl);
  84. hdmi_write(hdmi, REG_HDMI_VBI_PKT_CTRL, vbi_pkt_ctrl);
  85. hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL1, aud_pkt_ctrl);
  86. hdmi_write(hdmi, REG_HDMI_AUD_INT,
  87. COND(enabled, HDMI_AUD_INT_AUD_FIFO_URUN_INT) |
  88. COND(enabled, HDMI_AUD_INT_AUD_SAM_DROP_INT));
  89. hdmi_write(hdmi, REG_HDMI_AUDIO_CFG, audio_config);
  90. DBG("audio %sabled", enabled ? "en" : "dis");
  91. return 0;
  92. }
  93. int msm_hdmi_bridge_audio_prepare(struct drm_bridge *bridge,
  94. struct drm_connector *connector,
  95. struct hdmi_codec_daifmt *daifmt,
  96. struct hdmi_codec_params *params)
  97. {
  98. struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
  99. struct hdmi *hdmi = hdmi_bridge->hdmi;
  100. int ret;
  101. drm_dbg_driver(bridge->dev, "%u Hz, %d bit, %d channels\n",
  102. params->sample_rate,
  103. params->sample_width,
  104. params->cea.channels);
  105. switch (params->sample_rate) {
  106. case 32000:
  107. case 44100:
  108. case 48000:
  109. case 88200:
  110. case 96000:
  111. case 176400:
  112. case 192000:
  113. break;
  114. default:
  115. drm_err(bridge->dev, "rate[%d] not supported!\n",
  116. params->sample_rate);
  117. return -EINVAL;
  118. }
  119. ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
  120. &params->cea);
  121. if (ret)
  122. return ret;
  123. hdmi->audio.rate = params->sample_rate;
  124. hdmi->audio.channels = params->cea.channels;
  125. hdmi->audio.enabled = true;
  126. return msm_hdmi_audio_update(hdmi);
  127. }
  128. void msm_hdmi_bridge_audio_shutdown(struct drm_bridge *bridge,
  129. struct drm_connector *connector)
  130. {
  131. struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
  132. struct hdmi *hdmi = hdmi_bridge->hdmi;
  133. drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
  134. hdmi->audio.rate = 0;
  135. hdmi->audio.channels = 2;
  136. hdmi->audio.enabled = false;
  137. msm_hdmi_audio_update(hdmi);
  138. }