Unverified Commit 632ee3aa authored by Dave Stevenson's avatar Dave Stevenson Committed by Maxime Ripard
Browse files

drm/vc4: hdmi: Add audio-related callbacks



The audio configuration has changed for the BCM2711, with notably a
different parent clock and a different channel configuration.

Make that modular to be able to support the BCM2711.

Signed-off-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Tested-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Tested-by: default avatarHoegeun Kwon <hoegeun.kwon@samsung.com>
Tested-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Link: https://patchwork.freedesktop.org/patch/msgid/85a8ca721c2d800be758c55870cea98536749680.1599120059.git-series.maxime@cerno.tech
parent b9b8bac6
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -611,10 +611,22 @@ static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
	.enable = vc4_hdmi_encoder_enable,
};

static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
{
	int i;
	u32 channel_map = 0;

	for (i = 0; i < 8; i++) {
		if (channel_mask & BIT(i))
			channel_map |= i << (3 * i);
	}
	return channel_map;
}

/* HDMI audio codec callbacks */
static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
{
	u32 hsm_clock = clk_get_rate(vc4_hdmi->hsm_clock);
	u32 hsm_clock = clk_get_rate(vc4_hdmi->audio_clock);
	unsigned long n, m;

	rational_best_approximation(hsm_clock, vc4_hdmi->audio.samplerate,
@@ -733,7 +745,7 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
	struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
	struct device *dev = &vc4_hdmi->pdev->dev;
	u32 audio_packet_config, channel_mask;
	u32 channel_map, i;
	u32 channel_map;

	if (substream != vc4_hdmi->audio.substream)
		return -EINVAL;
@@ -785,12 +797,7 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
		   VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
		   VC4_SET_FIELD(channel_mask, VC4_HDMI_MAI_CHANNEL_MASK));

	channel_map = 0;
	for (i = 0; i < 8; i++) {
		if (channel_mask & BIT(i))
			channel_map |= i << (3 * i);
	}

	channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask);
	HDMI_WRITE(HDMI_MAI_CHANNEL_MAP, channel_map);
	HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
	vc4_hdmi_set_n_cts(vc4_hdmi);
@@ -1342,6 +1349,7 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
		DRM_ERROR("Failed to get HDMI state machine clock\n");
		return PTR_ERR(vc4_hdmi->hsm_clock);
	}
	vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock;

	return 0;
}
@@ -1507,6 +1515,7 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
	.phy_disable		= vc4_hdmi_phy_disable,
	.phy_rng_enable		= vc4_hdmi_phy_rng_enable,
	.phy_rng_disable	= vc4_hdmi_phy_rng_disable,
	.channel_map		= vc4_hdmi_channel_map,
};

static const struct of_device_id vc4_hdmi_dt_match[] = {
+4 −0
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@ struct vc4_hdmi_variant {

	/* Callback to disable the RNG in the PHY */
	void (*phy_rng_disable)(struct vc4_hdmi *vc4_hdmi);

	/* Callback to get channel map */
	u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask);
};

/* HDMI audio information */
@@ -112,6 +115,7 @@ struct vc4_hdmi {

	struct clk *pixel_clock;
	struct clk *hsm_clock;
	struct clk *audio_clock;

	struct debugfs_regset32 hdmi_regset;
	struct debugfs_regset32 hd_regset;