From: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: jani.nikula@intel.com
Subject: [Intel-gfx] [PATCH 3/3] drm/i915/display: Configure and initialize HDMI audio capabilities
Date: Mon, 21 Aug 2023 21:30:04 +0530 [thread overview]
Message-ID: <20230821160004.2821445-4-mitulkumar.ajitkumar.golani@intel.com> (raw)
In-Reply-To: <20230821160004.2821445-1-mitulkumar.ajitkumar.golani@intel.com>
Initialize the source audio capabilities in the crtc_state property,
setting them to their maximum supported values for max_channel and
max_rate. This initialization enables the calculation of audio source
capabilities concerning the available mode bandwidth. These
capabilities encompass parameters such as supported rate and
channel configurations.
Additionally, introduces a wrapper function for computing
Short Audio Descriptors (SADs). The wrapper function incorporates
logic for determining supported rates and channels according to the
capabilities of the audio source. It returns a set of SADs that are
compatible with the audio source's capabilities.
--v1:
- Refactor max_channel and max_rate to this commit as it is being
initialised here
- Remove call for intel_audio_compute_eld to avoid any regression while
merge. instead call it in different commit when it is defined.
- Use int instead of unsigned int for max_channel and max_frequecy
- Update commit message and header
--v2:
- Use signed instead of unsigned variables.
- Avoid using magic numbers and give them proper name.
--v3:
- Move defines to intel_audio.c.
- use consistent naming convention for rate and channel.
- declare num_of_channel and aud_rate separately.
- Declare index value outside of for loop.
- Move Bandwidth calculation to intel_Audio.c as it is common for both
DP and HDMI. Also use static.
--v10:
- Merged patch 2 and 3 to deduplicate function calls.
- Instead using Calibrate and calculated functions separately,
removed code duplication and merged functions.[Nikula, Jani]
- Remove magic value for SAD Channel mask. [Nikula, Jani]
- Corrected rate values based on HDMI Spec [Nikula, Jani]
- Update drm function to extract SAD from ELD [Nikula, Jani]
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
---
drivers/gpu/drm/i915/display/intel_audio.c | 127 ++++++++++++++++++
.../drm/i915/display/intel_display_types.h | 6 +
2 files changed, 133 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index e20ffc8e9654..2584096d80a4 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -64,6 +64,10 @@
* struct &i915_audio_component_audio_ops @audio_ops is called from i915 driver.
*/
+#define AUDIO_SAMPLE_CONTAINER_SIZE 32
+#define MAX_CHANNEL_COUNT 8
+#define ELD_SAD_CHANNELS_MASK 0x7
+
struct intel_audio_funcs {
void (*audio_codec_enable)(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
@@ -770,6 +774,127 @@ void intel_audio_sdp_split_update(struct intel_encoder *encoder,
crtc_state->sdp_split_enable ? AUD_ENABLE_SDP_SPLIT : 0);
}
+static int sad_to_channels(const u8 *sad)
+{
+ return 1 + (sad[0] & 0x7);
+}
+
+static int calc_audio_bw(int channel_count, int rate)
+{
+ int bandwidth = channel_count * rate * AUDIO_SAMPLE_CONTAINER_SIZE;
+ return bandwidth;
+}
+
+static void calc_and_calibrate_audio_config_params(struct intel_crtc_state *pipe_config,
+ int channel, bool calibration_required)
+{
+ struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+ int channel_count;
+ int index, rate[] = { 192000, 176400, 96000, 88200, 48000, 44100, 32000 };
+ int audio_req_bandwidth, available_blank_bandwidth, vblank, hblank;
+
+ hblank = adjusted_mode->htotal - adjusted_mode->hdisplay;
+ vblank = adjusted_mode->vtotal - adjusted_mode->vdisplay;
+ available_blank_bandwidth = hblank * vblank *
+ drm_mode_vrefresh(adjusted_mode) * pipe_config->pipe_bpp;
+
+ /*
+ * Expected calibration of channels and respective rates,
+ * based on MAX_CHANNEL_COUNT. First calculate channel and
+ * rate based on Maximum that source can compute, letter
+ * with respect to sink's maximum channel capacity, calibrate
+ * supportive rates.
+ */
+ if (calibration_required) {
+ channel_count = channel;
+ for (index = 0; index < ARRAY_SIZE(rate); index++) {
+ audio_req_bandwidth = calc_audio_bw(channel_count,
+ rate[index]);
+ if (audio_req_bandwidth < available_blank_bandwidth) {
+ pipe_config->audio.max_rate = rate[index];
+ pipe_config->audio.max_channel_count = channel_count;
+ return;
+ }
+ }
+ } else {
+ for (channel_count = channel; channel_count > 0; channel_count--) {
+ for (index = 0; index < ARRAY_SIZE(rate); index++) {
+ audio_req_bandwidth = calc_audio_bw(channel_count, rate[index]);
+ if (audio_req_bandwidth < available_blank_bandwidth) {
+ pipe_config->audio.max_rate = rate[index];
+ pipe_config->audio.max_channel_count = channel_count;
+ return;
+ }
+ }
+ }
+ }
+
+ pipe_config->audio.max_rate = 0;
+ pipe_config->audio.max_channel_count = 0;
+}
+
+static int get_supported_freq_mask(struct intel_crtc_state *crtc_state)
+{
+ int rate[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
+ int mask = 0, index;
+
+ for (index = 0; index < ARRAY_SIZE(rate); index++) {
+ if (rate[index] > crtc_state->audio.max_rate)
+ break;
+
+ mask |= 1 << index;
+
+ if (crtc_state->audio.max_rate != rate[index])
+ continue;
+ }
+
+ return mask;
+}
+
+static void intel_audio_compute_eld(struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ u8 *eld, *sad;
+ int index, mask = 0;
+
+ eld = crtc_state->eld;
+ if (!eld)
+ return;
+
+ sad = drm_extract_sad_from_eld(eld);
+ if (!sad)
+ return;
+
+ calc_and_calibrate_audio_config_params(crtc_state, MAX_CHANNEL_COUNT,
+ false);
+
+ mask = get_supported_freq_mask(crtc_state);
+ for (index = 0; index < drm_eld_sad_count(eld); index++, sad += 3) {
+ /*
+ * Respect source restricitions. Limit capabilities to a subset that is
+ * supported both by the source and the sink.
+ */
+ if (sad_to_channels(sad) >= crtc_state->audio.max_channel_count) {
+ sad[0] &= ~ELD_SAD_CHANNELS_MASK;
+ sad[0] |= crtc_state->audio.max_channel_count - 1;
+ drm_dbg_kms(&i915->drm, "Channel count is limited to %d\n",
+ crtc_state->audio.max_channel_count - 1);
+ } else {
+ /*
+ * calibrate rate when, sink supported channel
+ * count is slight less than max supported
+ * channel count.
+ */
+ calc_and_calibrate_audio_config_params(crtc_state,
+ sad_to_channels(sad),
+ true);
+ mask = get_supported_freq_mask(crtc_state);
+ }
+
+ sad[1] &= mask;
+ }
+}
+
bool intel_audio_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -791,6 +916,8 @@ bool intel_audio_compute_config(struct intel_encoder *encoder,
crtc_state->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
+ intel_audio_compute_eld(crtc_state);
+
return true;
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index ebd147180a6e..8815837a95a6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1131,6 +1131,12 @@ struct intel_crtc_state {
struct {
bool has_audio;
+
+ /* Audio rate in Hz */
+ int max_rate;
+
+ /* Number of audio channels */
+ int max_channel_count;
} audio;
/*
--
2.25.1
next prev parent reply other threads:[~2023-08-21 16:04 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-21 16:00 [Intel-gfx] [PATCH 0/3] Get optimal audio frequency and channels Mitul Golani
2023-08-21 16:00 ` [Intel-gfx] [PATCH 1/3] drm/i915: Add has_audio to separate audio parameter in crtc_state Mitul Golani
2023-08-21 16:00 ` [Intel-gfx] [PATCH 2/3] drm: Add Wrapper Functions for ELD SAD Extraction Mitul Golani
2023-09-05 6:26 ` Kandpal, Suraj
2023-09-07 9:35 ` Jani Nikula
2023-08-21 16:00 ` Mitul Golani [this message]
2023-09-05 9:17 ` [Intel-gfx] [PATCH 3/3] drm/i915/display: Configure and initialize HDMI audio capabilities Kandpal, Suraj
2023-09-06 16:17 ` Golani, Mitulkumar Ajitkumar
2023-09-08 8:17 ` Kandpal, Suraj
2023-08-21 21:58 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Get optimal audio frequency and channels (rev10) Patchwork
2023-08-21 21:58 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2023-08-21 22:13 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2023-08-22 1:05 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230821160004.2821445-4-mitulkumar.ajitkumar.golani@intel.com \
--to=mitulkumar.ajitkumar.golani@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox