Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp20072330rwd; Wed, 28 Jun 2023 19:35:03 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7NkWdWQDNZSK4ql1pDQL0QUS2DXzzA6lW6l+RL9xBTUX7/S7jsu1Rlw8nm+RGr8VVy9o14 X-Received: by 2002:a05:6358:c6a3:b0:134:ce45:b782 with SMTP id fe35-20020a056358c6a300b00134ce45b782mr6505319rwb.21.1688006103018; Wed, 28 Jun 2023 19:35:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688006102; cv=none; d=google.com; s=arc-20160816; b=I1ggOjpt0ozqZzM2j2xDNPdSsmjCu5Mn3myRIA8/y4F9FFtun12587fZZd9QFUade3 7Orv9sa09riaH3KU1Fmr6QRkvhbWxwQPBGrmBy/KJHhUtcOMZtjI0GFStrarsgikKd51 YkOiFcKuB6Ych4wDldHN82ptBKJPb91SM7kKMSli62JioSiSOC//CppjxlMzkslV820N QsHWNC4il1JAS54cebZ87IEFblFJauGjF71nsNGXLbg3xGAR2F81jvxtq5xvX+xxWcwh rWJC7LHHpiCOjJxhp5fyF/b8+iCQ7gcxGs99pn8drMRg4gPFzemcdbKw3I2Kevbk97Xw 8fIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :to:from; bh=XdT7pCqEBGy/8IkbFHoTFFZGLvKXJq94RDdU7/NXCec=; fh=wqCnLC59fNJLqJJs3/NMi5/oD30IP5JQsz1JrCsHxko=; b=CL3AyJYey6N5D1Av+iUVF/sczvqPFMf0B5lRS6CR9sQ1ThlhXTclhkxCEshlqbnEtt 2IL1iyTxOLjQkU9ZShkfwb7+GPNNFKdDK2yDFG1WK5d/cJhNmg19P0N55tmaZQi66ZwL W1zJWToHkZoSpvFi/VfjDPjsVa8lMtl5rOVEtxgZMJTiFgzZCIoM8c5083uRKHUc2pIZ HFhfsuXTvFtj87I62vYhgs+XudECoksBCAQnM9HooDgkW+HQVcGAiCuwFLs1+nhuFQao 5rCINGBWgYf06hfuywzmauEYyADRCkSh2uNcxYAGc6iP389n/ry0p63x7AnuARRG3L9d FqMQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 5-20020a630f45000000b0050fa9bc63cbsi9464572pgp.432.2023.06.28.19.34.47; Wed, 28 Jun 2023 19:35:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nxp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231967AbjF2CTM (ORCPT + 99 others); Wed, 28 Jun 2023 22:19:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230456AbjF2CS7 (ORCPT ); Wed, 28 Jun 2023 22:18:59 -0400 Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CCB182122; Wed, 28 Jun 2023 19:18:57 -0700 (PDT) Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 33884200D39; Thu, 29 Jun 2023 04:10:35 +0200 (CEST) Received: from aprdc01srsp001v.ap-rdc01.nxp.com (aprdc01srsp001v.ap-rdc01.nxp.com [165.114.16.16]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id C6925200D36; Thu, 29 Jun 2023 04:10:34 +0200 (CEST) Received: from localhost.localdomain (shlinux2.ap.freescale.net [10.192.224.44]) by aprdc01srsp001v.ap-rdc01.nxp.com (Postfix) with ESMTP id 0E481181D0E5; Thu, 29 Jun 2023 10:10:32 +0800 (+08) From: Shengjiu Wang To: tfiga@chromium.org, m.szyprowski@samsung.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, shengjiu.wang@gmail.com, Xiubo.Lee@gmail.com, festevam@gmail.com, nicoleotsuka@gmail.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH 2/6] ASoC: fsl_asrc: define functions for memory to memory usage Date: Thu, 29 Jun 2023 09:37:49 +0800 Message-Id: <1688002673-28493-3-git-send-email-shengjiu.wang@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1688002673-28493-1-git-send-email-shengjiu.wang@nxp.com> References: <1688002673-28493-1-git-send-email-shengjiu.wang@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ASRC can be used on memory to memory case, define several functions for m2m usage. m2m_start_part_one: first part of the start steps m2m_start_part_two: second part of the start steps m2m_stop_part_one: first part of stop steps m2m_stop_part_two: second part of stop steps m2m_check_format: check format is supported or not m2m_calc_out_len: calculate output length according to input length m2m_get_maxburst: burst size for dma m2m_pair_suspend: suspend function of pair m2m_pair_resume: resume function of pair get_output_fifo_size: get remaining data size in FIFO Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl_asrc.c | 138 ++++++++++++++++++++++++++++++++ sound/soc/fsl/fsl_asrc.h | 2 + sound/soc/fsl/fsl_asrc_common.h | 54 +++++++++++++ 3 files changed, 194 insertions(+) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index adb8a59de2bd..30190ccb74e7 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -1063,6 +1063,135 @@ static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index) return REG_ASRDx(dir, index); } +/* Get sample numbers in FIFO */ +static unsigned int fsl_asrc_get_output_fifo_size(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc *asrc = pair->asrc; + enum asrc_pair_index index = pair->index; + u32 val; + + regmap_read(asrc->regmap, REG_ASRFST(index), &val); + + val &= ASRFSTi_OUTPUT_FIFO_MASK; + + return val >> ASRFSTi_OUTPUT_FIFO_SHIFT; +} + +static int fsl_asrc_m2m_start_part_one(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc_pair_priv *pair_priv = pair->private; + struct fsl_asrc *asrc = pair->asrc; + struct device *dev = &asrc->pdev->dev; + struct asrc_config config; + int ret; + + /* fill config */ + config.pair = pair->index; + config.channel_num = pair->channels; + config.input_sample_rate = pair->rate[IN]; + config.output_sample_rate = pair->rate[OUT]; + config.input_format = pair->sample_format[IN]; + config.output_format = pair->sample_format[OUT]; + config.inclk = INCLK_NONE; + config.outclk = OUTCLK_ASRCK1_CLK; + + pair_priv->config = &config; + ret = fsl_asrc_config_pair(pair, true); + if (ret) { + dev_err(dev, "failed to config pair: %d\n", ret); + return ret; + } + + fsl_asrc_start_pair(pair); + + return 0; +} + +static int fsl_asrc_m2m_start_part_two(struct fsl_asrc_pair *pair) +{ + /* + * Clear DMA request during the stall state of ASRC: + * During STALL state, the remaining in input fifo would never be + * smaller than the input threshold while the output fifo would not + * be bigger than output one. Thus the DMA request would be cleared. + */ + fsl_asrc_set_watermarks(pair, ASRC_FIFO_THRESHOLD_MIN, + ASRC_FIFO_THRESHOLD_MAX); + + /* Update the real input threshold to raise DMA request */ + fsl_asrc_set_watermarks(pair, ASRC_M2M_INPUTFIFO_WML, + ASRC_M2M_OUTPUTFIFO_WML); + + return 0; +} + +static int fsl_asrc_m2m_stop_part_one(struct fsl_asrc_pair *pair) +{ + fsl_asrc_stop_pair(pair); + + return 0; +} + +static int fsl_asrc_m2m_check_format(u8 dir, u32 rate, u32 channels, u32 format) +{ + u64 support_format = FSL_ASRC_FORMATS; + + if (channels < 1 || channels > 10) + return -EINVAL; + + if (rate < 5512 || rate > 192000) + return -EINVAL; + + if (dir == IN) + support_format |= SNDRV_PCM_FMTBIT_S8; + + if (!(1 << format & support_format)) + return -EINVAL; + + return 0; +} + +/* calculate capture data length according to output data length and sample rate */ +static int fsl_asrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int input_buffer_length) +{ + unsigned int in_width, out_width; + unsigned int channels = pair->channels; + unsigned int in_samples, out_samples; + unsigned int out_length; + + in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8; + out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8; + + in_samples = input_buffer_length / in_width / channels; + out_samples = pair->rate[OUT] * in_samples / pair->rate[IN]; + out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * channels; + + return out_length; +} + +static int fsl_asrc_m2m_get_maxburst(u8 dir, struct fsl_asrc_pair *pair) +{ + struct fsl_asrc *asrc = pair->asrc; + struct fsl_asrc_priv *asrc_priv = asrc->private; + int wml = (dir == IN) ? ASRC_M2M_INPUTFIFO_WML : ASRC_M2M_OUTPUTFIFO_WML; + + if (!asrc_priv->soc->use_edma) + return wml * pair->channels; + else + return 1; +} + +static int fsl_asrc_m2m_pair_resume(struct fsl_asrc_pair *pair) +{ + struct fsl_asrc *asrc = pair->asrc; + int i; + + for (i = 0; i < pair->channels * 4; i++) + regmap_write(asrc->regmap, REG_ASRDI(pair->index), 0); + + return 0; +} + static int fsl_asrc_runtime_resume(struct device *dev); static int fsl_asrc_runtime_suspend(struct device *dev); @@ -1147,6 +1276,15 @@ static int fsl_asrc_probe(struct platform_device *pdev) asrc->get_fifo_addr = fsl_asrc_get_fifo_addr; asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv); + asrc->m2m_start_part_one = fsl_asrc_m2m_start_part_one; + asrc->m2m_start_part_two = fsl_asrc_m2m_start_part_two; + asrc->m2m_stop_part_one = fsl_asrc_m2m_stop_part_one; + asrc->get_output_fifo_size = fsl_asrc_get_output_fifo_size; + asrc->m2m_check_format = fsl_asrc_m2m_check_format; + asrc->m2m_calc_out_len = fsl_asrc_m2m_calc_out_len; + asrc->m2m_get_maxburst = fsl_asrc_m2m_get_maxburst; + asrc->m2m_pair_resume = fsl_asrc_m2m_pair_resume; + if (of_device_is_compatible(np, "fsl,imx35-asrc")) { asrc_priv->clk_map[IN] = input_clk_map_imx35; asrc_priv->clk_map[OUT] = output_clk_map_imx35; diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 86d2422ad606..1c492eb237f5 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -12,6 +12,8 @@ #include "fsl_asrc_common.h" +#define ASRC_M2M_INPUTFIFO_WML 0x4 +#define ASRC_M2M_OUTPUTFIFO_WML 0x2 #define ASRC_DMA_BUFFER_NUM 2 #define ASRC_INPUTFIFO_THRESHOLD 32 #define ASRC_OUTPUTFIFO_THRESHOLD 32 diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h index 7e1c13ca37f1..9294f378f0cc 100644 --- a/sound/soc/fsl/fsl_asrc_common.h +++ b/sound/soc/fsl/fsl_asrc_common.h @@ -4,6 +4,10 @@ * */ +#include +#include +#include + #ifndef _FSL_ASRC_COMMON_H #define _FSL_ASRC_COMMON_H @@ -34,6 +38,13 @@ enum asrc_pair_index { * @pos: hardware pointer position * @req_dma_chan: flag to release dev_to_dev chan * @private: pair private area + * @complete: dma task complete + * @fh: v4l2 file handler + * @ctrl_handler: v4l2 control handler + * @sample_format: format of m2m + * @rate: rate of m2m + * @buf_len: buffer length of m2m + * @req_pair: flag for request pair */ struct fsl_asrc_pair { struct fsl_asrc *asrc; @@ -49,6 +60,15 @@ struct fsl_asrc_pair { bool req_dma_chan; void *private; + + /* used for m2m */ + struct completion complete[2]; + struct v4l2_fh fh; + struct v4l2_ctrl_handler ctrl_handler; + snd_pcm_format_t sample_format[2]; + unsigned int rate[2]; + unsigned int buf_len[2]; + bool req_pair; }; /** @@ -63,6 +83,10 @@ struct fsl_asrc_pair { * @ipg_clk: clock source to drive peripheral * @spba_clk: SPBA clock (optional, depending on SoC design) * @lock: spin lock for resource protection + * @v4l2_dev: v4l2 device structure + * @m2m_dev: pointer to v4l2_m2m_dev + * @dec_vdev: pointer to video_device + * @mlock: v4l2 ioctls serialization * @pair: pair pointers * @channel_avail: non-occupied channel numbers * @asrc_rate: default sample rate for ASoC Back-Ends @@ -72,6 +96,17 @@ struct fsl_asrc_pair { * @request_pair: function pointer * @release_pair: function pointer * @get_fifo_addr: function pointer + * @m2m_start_part_one: function pointer + * @m2m_start_part_two: function pointer + * @m2m_stop_part_one: function pointer + * @m2m_stop_part_two: function pointer + * @m2m_check_format: function pointer + * @m2m_calc_out_len: function pointer + * @m2m_get_maxburst: function pointer + * @m2m_pair_suspend: function pointer + * @m2m_pair_resume: function pointer + * @m2m_set_ratio_mod: function pointer + * @get_output_fifo_size: function pointer * @pair_priv_size: size of pair private struct. * @private: private data structure */ @@ -86,6 +121,11 @@ struct fsl_asrc { struct clk *spba_clk; spinlock_t lock; /* spin lock for resource protection */ + struct v4l2_device v4l2_dev; + struct v4l2_m2m_dev *m2m_dev; + struct video_device *dec_vdev; + struct mutex mlock; /* v4l2 ioctls serialization */ + struct fsl_asrc_pair *pair[PAIR_CTX_NUM]; unsigned int channel_avail; @@ -97,6 +137,20 @@ struct fsl_asrc { int (*request_pair)(int channels, struct fsl_asrc_pair *pair); void (*release_pair)(struct fsl_asrc_pair *pair); int (*get_fifo_addr)(u8 dir, enum asrc_pair_index index); + + int (*m2m_start_part_one)(struct fsl_asrc_pair *pair); + int (*m2m_start_part_two)(struct fsl_asrc_pair *pair); + int (*m2m_stop_part_one)(struct fsl_asrc_pair *pair); + int (*m2m_stop_part_two)(struct fsl_asrc_pair *pair); + + int (*m2m_check_format)(u8 dir, u32 rate, u32 channels, u32 format); + int (*m2m_calc_out_len)(struct fsl_asrc_pair *pair, int input_buffer_length); + int (*m2m_get_maxburst)(u8 dir, struct fsl_asrc_pair *pair); + int (*m2m_pair_suspend)(struct fsl_asrc_pair *pair); + int (*m2m_pair_resume)(struct fsl_asrc_pair *pair); + int (*m2m_set_ratio_mod)(struct fsl_asrc_pair *pair, int val); + + unsigned int (*get_output_fifo_size)(struct fsl_asrc_pair *pair); size_t pair_priv_size; void *private; -- 2.34.1