Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Vincent ABRIOU <vincent.abriou@st.com>
To: Arnaud POULIQUEN <arnaud.pouliquen@st.com>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>
Cc: Daniel Vetter <daniel.vetter@intel.com>,
	"alsa-devel@alsa-project.org" <alsa-devel@alsa-project.org>,
	"kernel@stlinux.com" <kernel@stlinux.com>
Subject: Re: [PATCH] drm: sti: allow audio playback on HDMI even if disabled.
Date: Wed, 4 Jan 2017 15:01:55 +0000	[thread overview]
Message-ID: <fd67a70d-167a-eae8-1f80-936ea724bc2c@st.com> (raw)
In-Reply-To: <1475248620-28996-1-git-send-email-arnaud.pouliquen@st.com>

Acked-by: Vincent Abriou <vincent.abriou@st.com>

On 09/30/2016 05:17 PM, Arnaud Pouliquen wrote:
> This fix allows to play audio while HDMI is disconnected.
> When HDMI is disable, audio configuration is stored and samples
> are dropped (by HDMI IP).
> When HDMI is enabled, audio HDMI configuration is applied and samples
> are outputted on HDMI wire.
>
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
> ---
>  drivers/gpu/drm/sti/sti_hdmi.c | 205 ++++++++++++++++++++---------------------
>  1 file changed, 101 insertions(+), 104 deletions(-)
>
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 376b076..9c0025e 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -788,6 +788,95 @@ static void sti_hdmi_disable(struct drm_bridge *bridge)
>  	hdmi->enabled = false;
>  }
>
> +/**
> + * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
> + * clocks. None-coherent clocks means that audio and TMDS clocks have not the
> + * same source (drifts between clocks). In this case assumption is that CTS is
> + * automatically calculated by hardware.
> + *
> + * @audio_fs: audio frame clock frequency in Hz
> + *
> + * Values computed are based on table described in HDMI specification 1.4b
> + *
> + * Returns n value.
> + */
> +static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs)
> +{
> +	unsigned int n;
> +
> +	switch (audio_fs) {
> +	case 32000:
> +		n = 4096;
> +		break;
> +	case 44100:
> +		n = 6272;
> +		break;
> +	case 48000:
> +		n = 6144;
> +		break;
> +	case 88200:
> +		n = 6272 * 2;
> +		break;
> +	case 96000:
> +		n = 6144 * 2;
> +		break;
> +	case 176400:
> +		n = 6272 * 4;
> +		break;
> +	case 192000:
> +		n = 6144 * 4;
> +		break;
> +	default:
> +		/* Not pre-defined, recommended value: 128 * fs / 1000 */
> +		n = (audio_fs * 128) / 1000;
> +	}
> +
> +	return n;
> +}
> +
> +static int hdmi_audio_configure(struct sti_hdmi *hdmi)
> +{
> +	int audio_cfg, n;
> +	struct hdmi_audio_params *params = &hdmi->audio;
> +	struct hdmi_audio_infoframe *info = &params->cea;
> +
> +	DRM_DEBUG_DRIVER("\n");
> +
> +	if (!hdmi->enabled)
> +		return 0;
> +
> +	/* update N parameter */
> +	n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate);
> +
> +	DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n",
> +			 params->sample_rate, hdmi->mode.clock * 1000, n);
> +	hdmi_write(hdmi, n, HDMI_AUDN);
> +
> +	/* update HDMI registers according to configuration */
> +	audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID |
> +		    HDMI_AUD_CFG_ONE_BIT_INVALID;
> +
> +	switch (info->channels) {
> +	case 8:
> +		audio_cfg |= HDMI_AUD_CFG_CH78_VALID;
> +	case 6:
> +		audio_cfg |= HDMI_AUD_CFG_CH56_VALID;
> +	case 4:
> +		audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH;
> +	case 2:
> +		audio_cfg |= HDMI_AUD_CFG_CH12_VALID;
> +		break;
> +	default:
> +		DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n",
> +			  info->channels);
> +		return -EINVAL;
> +	}
> +
> +	hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
> +
> +	return hdmi_audio_infoframe_config(hdmi);
> +}
> +
>  static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
>  {
>  	struct sti_hdmi *hdmi = bridge->driver_private;
> @@ -826,9 +915,12 @@ static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
>  	if (hdmi_avi_infoframe_config(hdmi))
>  		DRM_ERROR("Unable to configure AVI infoframe\n");
>
> -	/* Program AUDIO infoframe */
> -	if (hdmi_audio_infoframe_config(hdmi))
> -		DRM_ERROR("Unable to configure AUDIO infoframe\n");
> +	if (hdmi->audio.enabled) {
> +		if (hdmi_audio_configure(hdmi))
> +			DRM_ERROR("Unable to configure audio\n");
> +	} else {
> +		hdmi_audio_infoframe_config(hdmi);
> +	}
>
>  	/* Program VS infoframe */
>  	if (hdmi_vendor_infoframe_config(hdmi))
> @@ -1078,97 +1170,6 @@ static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev)
>  	return NULL;
>  }
>
> -/**
> - * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
> - * clocks. None-coherent clocks means that audio and TMDS clocks have not the
> - * same source (drifts between clocks). In this case assumption is that CTS is
> - * automatically calculated by hardware.
> - *
> - * @audio_fs: audio frame clock frequency in Hz
> - *
> - * Values computed are based on table described in HDMI specification 1.4b
> - *
> - * Returns n value.
> - */
> -static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs)
> -{
> -	unsigned int n;
> -
> -	switch (audio_fs) {
> -	case 32000:
> -		n = 4096;
> -		break;
> -	case 44100:
> -		n = 6272;
> -		break;
> -	case 48000:
> -		n = 6144;
> -		break;
> -	case 88200:
> -		n = 6272 * 2;
> -		break;
> -	case 96000:
> -		n = 6144 * 2;
> -		break;
> -	case 176400:
> -		n = 6272 * 4;
> -		break;
> -	case 192000:
> -		n = 6144 * 4;
> -		break;
> -	default:
> -		/* Not pre-defined, recommended value: 128 * fs / 1000 */
> -		n = (audio_fs * 128) / 1000;
> -	}
> -
> -	return n;
> -}
> -
> -static int hdmi_audio_configure(struct sti_hdmi *hdmi,
> -				struct hdmi_audio_params *params)
> -{
> -	int audio_cfg, n;
> -	struct hdmi_audio_infoframe *info = &params->cea;
> -
> -	DRM_DEBUG_DRIVER("\n");
> -
> -	if (!hdmi->enabled)
> -		return 0;
> -
> -	/* update N parameter */
> -	n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate);
> -
> -	DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n",
> -			 params->sample_rate, hdmi->mode.clock * 1000, n);
> -	hdmi_write(hdmi, n, HDMI_AUDN);
> -
> -	/* update HDMI registers according to configuration */
> -	audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID |
> -		    HDMI_AUD_CFG_ONE_BIT_INVALID;
> -
> -	switch (info->channels) {
> -	case 8:
> -		audio_cfg |= HDMI_AUD_CFG_CH78_VALID;
> -	case 6:
> -		audio_cfg |= HDMI_AUD_CFG_CH56_VALID;
> -	case 4:
> -		audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH;
> -	case 2:
> -		audio_cfg |= HDMI_AUD_CFG_CH12_VALID;
> -		break;
> -	default:
> -		DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n",
> -			  info->channels);
> -		return -EINVAL;
> -	}
> -
> -	hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
> -
> -	hdmi->audio = *params;
> -
> -	return hdmi_audio_infoframe_config(hdmi);
> -}
> -
>  static void hdmi_audio_shutdown(struct device *dev, void *data)
>  {
>  	struct sti_hdmi *hdmi = dev_get_drvdata(dev);
> @@ -1192,17 +1193,9 @@ static int hdmi_audio_hw_params(struct device *dev,
>  {
>  	struct sti_hdmi *hdmi = dev_get_drvdata(dev);
>  	int ret;
> -	struct hdmi_audio_params audio = {
> -		.sample_width = params->sample_width,
> -		.sample_rate = params->sample_rate,
> -		.cea = params->cea,
> -	};
>
>  	DRM_DEBUG_DRIVER("\n");
>
> -	if (!hdmi->enabled)
> -		return 0;
> -
>  	if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv ||
>  	    daifmt->frame_clk_inv || daifmt->bit_clk_master ||
>  	    daifmt->frame_clk_master) {
> @@ -1213,9 +1206,13 @@ static int hdmi_audio_hw_params(struct device *dev,
>  		return -EINVAL;
>  	}
>
> -	audio.enabled = true;
> +	hdmi->audio.sample_width = params->sample_width;
> +	hdmi->audio.sample_rate = params->sample_rate;
> +	hdmi->audio.cea = params->cea;
> +
> +	hdmi->audio.enabled = true;
>
> -	ret = hdmi_audio_configure(hdmi, &audio);
> +	ret = hdmi_audio_configure(hdmi);
>  	if (ret < 0)
>  		return ret;
>
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

      reply	other threads:[~2017-01-04 15:01 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-30 15:17 [PATCH] drm: sti: allow audio playback on HDMI even if disabled Arnaud Pouliquen
2017-01-04 15:01 ` Vincent ABRIOU [this message]

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=fd67a70d-167a-eae8-1f80-936ea724bc2c@st.com \
    --to=vincent.abriou@st.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=arnaud.pouliquen@st.com \
    --cc=daniel.vetter@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kernel@stlinux.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