Re: [RFC PATCH v6 10/11] media: imx-asrc: Add memory to memory driver

From: Hans Verkuil
Date: Wed Oct 18 2023 - 08:58:02 EST


On 18/10/2023 14:53, Shengjiu Wang wrote:
> On Mon, Oct 16, 2023 at 10:01 PM Hans Verkuil <hverkuil@xxxxxxxxx> wrote:
>>
>> On 13/10/2023 10:31, Shengjiu Wang wrote:
>>> Implement the ASRC memory to memory function using
>>> the v4l2 framework, user can use this function with
>>> v4l2 ioctl interface.
>>>
>>> User send the output and capture buffer to driver and
>>> driver store the converted data to the capture buffer.
>>>
>>> This feature can be shared by ASRC and EASRC drivers
>>>
>>> Signed-off-by: Shengjiu Wang <shengjiu.wang@xxxxxxx>
>>> ---
>>> drivers/media/platform/nxp/Kconfig | 12 +
>>> drivers/media/platform/nxp/Makefile | 1 +
>>> drivers/media/platform/nxp/imx-asrc.c | 1248 +++++++++++++++++++++++++
>>> 3 files changed, 1261 insertions(+)
>>> create mode 100644 drivers/media/platform/nxp/imx-asrc.c
>>>
>>> diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig
>>> index 40e3436669e2..8234644ee341 100644
>>> --- a/drivers/media/platform/nxp/Kconfig
>>> +++ b/drivers/media/platform/nxp/Kconfig
>>> @@ -67,3 +67,15 @@ config VIDEO_MX2_EMMAPRP
>>>
>>> source "drivers/media/platform/nxp/dw100/Kconfig"
>>> source "drivers/media/platform/nxp/imx-jpeg/Kconfig"
>>> +
>>> +config VIDEO_IMX_ASRC
>>> + tristate "NXP i.MX ASRC M2M support"
>>> + depends on V4L_MEM2MEM_DRIVERS
>>> + depends on MEDIA_SUPPORT
>>> + select VIDEOBUF2_DMA_CONTIG
>>> + select V4L2_MEM2MEM_DEV
>>> + help
>>> + Say Y if you want to add ASRC M2M support for NXP CPUs.
>>> + It is a complement for ASRC M2P and ASRC P2M features.
>>> + This option is only useful for out-of-tree drivers since
>>> + in-tree drivers select it automatically.
>>> diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/nxp/Makefile
>>> index 4d90eb713652..1325675e34f5 100644
>>> --- a/drivers/media/platform/nxp/Makefile
>>> +++ b/drivers/media/platform/nxp/Makefile
>>> @@ -9,3 +9,4 @@ obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
>>> obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
>>> obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
>>> obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
>>> +obj-$(CONFIG_VIDEO_IMX_ASRC) += imx-asrc.o
>>> diff --git a/drivers/media/platform/nxp/imx-asrc.c b/drivers/media/platform/nxp/imx-asrc.c
>>> new file mode 100644
>>> index 000000000000..373ca2b5ec90
>>> --- /dev/null
>>> +++ b/drivers/media/platform/nxp/imx-asrc.c
>>> @@ -0,0 +1,1248 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +//
>>> +// Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
>>> +// Copyright (C) 2019-2023 NXP
>>> +//
>>> +// Freescale ASRC Memory to Memory (M2M) driver
>>> +
>>> +#include <linux/dma/imx-dma.h>
>>> +#include <linux/pm_runtime.h>
>>> +#include <media/v4l2-ctrls.h>
>>> +#include <media/v4l2-device.h>
>>> +#include <media/v4l2-event.h>
>>> +#include <media/v4l2-fh.h>
>>> +#include <media/v4l2-ioctl.h>
>>> +#include <media/v4l2-mem2mem.h>
>>> +#include <media/videobuf2-dma-contig.h>
>>> +#include <sound/dmaengine_pcm.h>
>>> +#include <sound/fsl_asrc_common.h>
>>> +
>>> +#define V4L_CAP OUT
>>> +#define V4L_OUT IN
>>> +
>>> +#define ASRC_xPUT_DMA_CALLBACK(dir) \
>>> + (((dir) == V4L_OUT) ? asrc_input_dma_callback \
>>> + : asrc_output_dma_callback)
>>> +
>>> +#define DIR_STR(dir) (dir) == V4L_OUT ? "out" : "cap"
>>> +
>>> +#define ASRC_M2M_BUFFER_SIZE (512 * 1024)
>>> +#define ASRC_M2M_PERIOD_SIZE (48 * 1024)
>>> +#define ASRC_M2M_SG_NUM (20)
>>
>> Where do all these values come from? How do they relate?
>> Some comments would be welcome.
>>
>> Esp. ASRC_M2M_SG_NUM is a bit odd.
>>
>>> +
>>> +struct asrc_fmt {
>>> + u32 fourcc;
>>> + snd_pcm_format_t format;
>>
>> Do you need this field? If not, then you can drop the whole
>> struct and just use u32 fourcc in the formats[] array.
>>
>>> +};
>>> +
>>> +struct asrc_pair_m2m {
>>> + struct fsl_asrc_pair *pair;
>>> + struct asrc_m2m *m2m;
>>> + struct v4l2_fh fh;
>>> + struct v4l2_ctrl_handler ctrl_handler;
>>> + int channels[2];
>>> + struct v4l2_ctrl_fixed_point src_rate;
>>> + struct v4l2_ctrl_fixed_point dst_rate;
>>> +
>>> +};
>>> +
>>> +struct asrc_m2m {
>>> + struct fsl_asrc_m2m_pdata pdata;
>>> + struct v4l2_device v4l2_dev;
>>> + struct v4l2_m2m_dev *m2m_dev;
>>> + struct video_device *dec_vdev;
>>> + struct mutex mlock; /* v4l2 ioctls serialization */
>>> + struct platform_device *pdev;
>>> +};
>>> +
>>> +static struct asrc_fmt formats[] = {
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_S8,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_S16_LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_U16_LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_S24_LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_S24_3LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_U24_LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_U24_3LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_S32_LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_U32_LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_S20_3LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_U20_3LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_FLOAT_LE,
>>> + },
>>> + {
>>> + .fourcc = V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE,
>>> + },
>>> +};
>>> +
>>> +#define NUM_FORMATS ARRAY_SIZE(formats)
>>> +
>>> +static snd_pcm_format_t convert_fourcc(u32 fourcc) {
>>> +
>>> + return (__force snd_pcm_format_t)v4l2_fourcc_to_audfmt(fourcc);
>>
>> Is this cast something that should be done in the v4l2_fourcc_to_audfmt
>> define instead?
>
> need to avoid include asound.h in videodev2.h, so add this cast in driver.

It's a #define, so just including videodev2.h won't require asound.h.

Regards,

Hans