alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: dri-devel@lists.freedesktop.org
Cc: Jernej Skrabec <jernej.skrabec@siol.net>,
	alsa-devel@alsa-project.org, Jonas Karlman <jonas@kwiboo.se>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Russell King <linux@armlinux.org.uk>,
	Andrzej Hajda <a.hajda@samsung.com>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Subject: [alsa-devel] [PATCH for-5.6 1/2] drm/bridge: dw-hdmi: Follow the standard ALSA memalloc way
Date: Tue, 10 Dec 2019 16:45:35 +0100	[thread overview]
Message-ID: <20191210154536.29819-2-tiwai@suse.de> (raw)
In-Reply-To: <20191210154536.29819-1-tiwai@suse.de>

The driver manages actually two different buffers: the internal buffer
that is pre-allocated at the probe time and the vmalloc buffer for PCM
streams allocated at each stream open time.  The problem of the
current code is that the PCM core rather expects other way round,
i.e. the the vmalloc buffer is declared as preallocator (although not
actually pre-allocating pages at the probe time).  Then the whole rest
buffer allocation and release can be managed inside PCM core and we
can drop the allocation/free call in the driver.

For achieving that, this patch changes the buffer management in the
following way:
- The intermediate buffer is allocated manually instead of
  snd_pcm_lib_preallocate*() helper, kept in the own record, released
  in the card private_free call
- The size of internal buffer is specified by the new module option,
  buffer_size
- The normal stream buffer is set up via the new
  snd_pcm_set_managed_buffer*() helper
- The hw_params and hw_free callbacks are removed as they become
  superfluous with the new API

Also the hw_constraint call is corrected to point to the right unit
(bytes) instead of the frame size.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 .../gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c    | 48 ++++++++++++----------
 1 file changed, 26 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index 2b7539701b42..ab8d16b3b78d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -7,6 +7,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 #include <drm/bridge/dw_hdmi.h>
 #include <drm/drm_edid.h>
@@ -22,6 +23,10 @@
 
 #define DRIVER_NAME "dw-hdmi-ahb-audio"
 
+static unsigned int hw_buffer_size = 128 * 1024;
+module_param_named(buffer_size, hw_buffer_size, uint, 0444);
+MODULE_PARM_DESC(buffer_size, "Hardware buffer size to preallocate");
+
 /* Provide some bits rather than bit offsets */
 enum {
 	HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
@@ -119,6 +124,7 @@ struct snd_dw_hdmi {
 	spinlock_t lock;
 	struct dw_hdmi_audio_data data;
 	struct snd_pcm_substream *substream;
+	struct snd_dma_buffer hw_buffer;
 	void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
 	void *buf_src;
 	void *buf_dst;
@@ -339,8 +345,8 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream)
 
 	/* Limit the buffer size to the size of the preallocated buffer */
 	ret = snd_pcm_hw_constraint_minmax(runtime,
-					   SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
-					   0, substream->dma_buffer.bytes);
+					   SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+					   0, dw->hw_buffer.bytes);
 	if (ret < 0)
 		return ret;
 
@@ -382,19 +388,6 @@ static int dw_hdmi_close(struct snd_pcm_substream *substream)
 	return 0;
 }
 
-static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
-{
-	return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	/* Allocate the PCM runtime buffer, which is exposed to userspace. */
-	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-						params_buffer_bytes(params));
-}
-
 static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -449,8 +442,8 @@ static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
 	dw->iec_offset = 0;
 	dw->channels = runtime->channels;
 	dw->buf_src  = runtime->dma_area;
-	dw->buf_dst  = substream->dma_buffer.area;
-	dw->buf_addr = substream->dma_buffer.addr;
+	dw->buf_dst  = dw->hw_buffer.area;
+	dw->buf_addr = dw->hw_buffer.addr;
 	dw->buf_period = snd_pcm_lib_period_bytes(substream);
 	dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
 
@@ -506,14 +499,19 @@ static const struct snd_pcm_ops snd_dw_hdmi_ops = {
 	.open = dw_hdmi_open,
 	.close = dw_hdmi_close,
 	.ioctl = snd_pcm_lib_ioctl,
-	.hw_params = dw_hdmi_hw_params,
-	.hw_free = dw_hdmi_hw_free,
 	.prepare = dw_hdmi_prepare,
 	.trigger = dw_hdmi_trigger,
 	.pointer = dw_hdmi_pointer,
-	.page = snd_pcm_lib_get_vmalloc_page,
 };
 
+static void snd_dw_hdmi_free(struct snd_card *card)
+{
+	struct snd_dw_hdmi *dw = card->private_data;
+
+	if (dw->hw_buffer.bytes)
+		snd_dma_free_pages(&dw->hw_buffer);
+}
+
 static int snd_dw_hdmi_probe(struct platform_device *pdev)
 {
 	const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
@@ -548,6 +546,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
 	dw->card = card;
 	dw->data = *data;
 	dw->revision = revision;
+	card->private_free = snd_dw_hdmi_free;
 
 	spin_lock_init(&dw->lock);
 
@@ -559,13 +558,18 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
 	pcm->private_data = dw;
 	strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
+	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, dev, 0, 0);
 
 	/*
 	 * To support 8-channel 96kHz audio reliably, we need 512k
 	 * to satisfy alsa with our restricted period (ERR004323).
 	 */
-	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-			dev, 128 * 1024, 1024 * 1024);
+	if (hw_buffer_size > 1024 * 1024)
+		hw_buffer_size = 1024 * 1024;
+	ret  = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, dev,
+					    hw_buffer_size, &dw->hw_buffer);
+	if (ret < 0)
+		goto err;
 
 	ret = snd_card_register(card);
 	if (ret < 0)
-- 
2.16.4

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

  reply	other threads:[~2019-12-10 15:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-10 15:45 [alsa-devel] [PATCH for-5.6 0/2] drm/bridge: dw-hdmi: PCM API updates Takashi Iwai
2019-12-10 15:45 ` Takashi Iwai [this message]
2019-12-10 15:45 ` [alsa-devel] [PATCH for-5.6 2/2] drm/bridge: dw-hdmi: Drop superfluous ioctl PCM ops Takashi Iwai
2020-01-09  9:10 ` [alsa-devel] [PATCH for-5.6 0/2] drm/bridge: dw-hdmi: PCM API updates Takashi Iwai
2020-01-09 10:18   ` Neil Armstrong
2020-01-09 10:25   ` Russell King - ARM Linux admin

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=20191210154536.29819-2-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=a.hajda@samsung.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jernej.skrabec@siol.net \
    --cc=jonas@kwiboo.se \
    --cc=linux@armlinux.org.uk \
    --cc=narmstrong@baylibre.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;
as well as URLs for NNTP newsgroup(s).