From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/sound/soc/rockchip/rockchip_sai.c | 95 +++++++++++++++++++++++++++++++++++------------ 1 files changed, 70 insertions(+), 25 deletions(-) diff --git a/kernel/sound/soc/rockchip/rockchip_sai.c b/kernel/sound/soc/rockchip/rockchip_sai.c index 6609c1f..c3e0006 100644 --- a/kernel/sound/soc/rockchip/rockchip_sai.c +++ b/kernel/sound/soc/rockchip/rockchip_sai.c @@ -19,10 +19,12 @@ #include <sound/tlv.h> #include "rockchip_sai.h" +#include "rockchip_dlp_pcm.h" +#include "rockchip_utils.h" #define DRV_NAME "rockchip-sai" -#define CLK_SHIFT_RATE_HZ_MAX 1 /* 1 Hz */ +#define CLK_SHIFT_RATE_HZ_MAX 5 #define FW_RATIO_MAX 8 #define FW_RATIO_MIN 1 #define MAXBURST_PER_FIFO 8 @@ -422,23 +424,27 @@ { struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai); struct snd_dmaengine_dai_dma_data *dma_data; - unsigned int mclk_rate, bclk_rate, div_bclk; + unsigned int mclk_rate, mclk_req_rate, bclk_rate, div_bclk; unsigned int ch_per_lane, lanes, slot_width; - unsigned int val, fscr, reg; + unsigned int val, fscr, reg, fifo; dma_data = snd_soc_dai_get_dma_data(dai, substream); dma_data->maxburst = MAXBURST_PER_FIFO * params_channels(params) / 2; lanes = rockchip_sai_lanes_auto(params, dai); + regmap_read(sai->regmap, SAI_DMACR, &val); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { reg = SAI_TXCR; if (sai->tx_lanes) lanes = sai->tx_lanes; + fifo = SAI_DMACR_TDL_V(val) * lanes; } else { reg = SAI_RXCR; if (sai->rx_lanes) lanes = sai->rx_lanes; + fifo = SAI_DMACR_TDL_V(val) * lanes; } switch (params_format(params)) { @@ -497,18 +503,29 @@ if (sai->is_clk_auto) clk_set_rate(sai->mclk, bclk_rate); mclk_rate = clk_get_rate(sai->mclk); - if (mclk_rate < bclk_rate - CLK_SHIFT_RATE_HZ_MAX || - mclk_rate > bclk_rate + CLK_SHIFT_RATE_HZ_MAX) { + div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate); + mclk_req_rate = bclk_rate * div_bclk; + + if (mclk_rate < mclk_req_rate - CLK_SHIFT_RATE_HZ_MAX || + mclk_rate > mclk_req_rate + CLK_SHIFT_RATE_HZ_MAX) { dev_err(sai->dev, "Mismatch mclk: %u, expected %u (+/- %dHz)\n", - mclk_rate, bclk_rate, CLK_SHIFT_RATE_HZ_MAX); + mclk_rate, mclk_req_rate, CLK_SHIFT_RATE_HZ_MAX); return -EINVAL; } - - div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate); regmap_update_bits(sai->regmap, SAI_CKR, SAI_CKR_MDIV_MASK, SAI_CKR_MDIV(div_bclk)); } + + rockchip_utils_get_performance(substream, params, dai, fifo); + + return 0; +} + +static int rockchip_sai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + rockchip_utils_put_performance(substream, dai); return 0; } @@ -639,6 +656,7 @@ .startup = rockchip_sai_startup, .shutdown = rockchip_sai_shutdown, .hw_params = rockchip_sai_hw_params, + .hw_free = rockchip_sai_hw_free, .set_sysclk = rockchip_sai_set_sysclk, .set_fmt = rockchip_sai_set_fmt, .prepare = rockchip_sai_prepare, @@ -879,39 +897,39 @@ "From PATH0", "From PATH1", "From PATH2", "From PATH3" }; /* TXCR */ -static SOC_ENUM_SINGLE_DECL(tsft_enum, SAI_TXCR, 22, edge_shift_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused tsft_enum, SAI_TXCR, 22, edge_shift_text); static const struct soc_enum tx_lanes_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_lanes_text), tx_lanes_text); -static SOC_ENUM_SINGLE_DECL(tsjm_enum, SAI_TXCR, 19, sjm_text); -static SOC_ENUM_SINGLE_DECL(tfbm_enum, SAI_TXCR, 18, fbm_text); -static SOC_ENUM_SINGLE_DECL(tvdj_enum, SAI_TXCR, 10, vdj_text); -static SOC_ENUM_SINGLE_DECL(tsbw_enum, SAI_TXCR, 5, sbw_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused tsjm_enum, SAI_TXCR, 19, sjm_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused tfbm_enum, SAI_TXCR, 18, fbm_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused tvdj_enum, SAI_TXCR, 10, vdj_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused tsbw_enum, SAI_TXCR, 5, sbw_text); /* FSCR */ -static SOC_ENUM_SINGLE_DECL(edge_enum, SAI_FSCR, 24, edge_text); -static const struct soc_enum fpw_enum = +static SOC_ENUM_SINGLE_DECL(__maybe_unused edge_enum, SAI_FSCR, 24, edge_text); +static const struct soc_enum __maybe_unused fpw_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fpw_text), fpw_text); -static const struct soc_enum fw_ratio_enum = +static const struct soc_enum __maybe_unused fw_ratio_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fw_ratio_text), fw_ratio_text); /* RXCR */ -static SOC_ENUM_SINGLE_DECL(rsft_enum, SAI_RXCR, 22, edge_shift_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused rsft_enum, SAI_RXCR, 22, edge_shift_text); static const struct soc_enum rx_lanes_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_lanes_text), rx_lanes_text); -static SOC_ENUM_SINGLE_DECL(rsjm_enum, SAI_RXCR, 19, sjm_text); -static SOC_ENUM_SINGLE_DECL(rfbm_enum, SAI_RXCR, 18, fbm_text); -static SOC_ENUM_SINGLE_DECL(rvdj_enum, SAI_RXCR, 10, vdj_text); -static SOC_ENUM_SINGLE_DECL(rsbw_enum, SAI_RXCR, 5, sbw_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused rsjm_enum, SAI_RXCR, 19, sjm_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused rfbm_enum, SAI_RXCR, 18, fbm_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused rvdj_enum, SAI_RXCR, 10, vdj_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused rsbw_enum, SAI_RXCR, 5, sbw_text); /* MONO_CR */ static SOC_ENUM_SINGLE_DECL(rmono_switch, SAI_MONO_CR, 1, mono_text); static SOC_ENUM_SINGLE_DECL(tmono_switch, SAI_MONO_CR, 0, mono_text); /* CKR */ -static const struct soc_enum mss_switch = +static const struct soc_enum __maybe_unused mss_switch = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mss_text), mss_text); -static SOC_ENUM_SINGLE_DECL(sp_switch, SAI_CKR, 1, ckp_text); -static SOC_ENUM_SINGLE_DECL(fp_switch, SAI_CKR, 0, ckp_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused sp_switch, SAI_CKR, 1, ckp_text); +static SOC_ENUM_SINGLE_DECL(__maybe_unused fp_switch, SAI_CKR, 0, ckp_text); /* PATH_SEL */ static SOC_ENUM_SINGLE_DECL(lp3_enum, SAI_PATH_SEL, 28, lpx_text); @@ -1344,6 +1362,29 @@ return ret; } +static int rockchip_sai_get_fifo_count(struct device *dev, + struct snd_pcm_substream *substream) +{ + struct rk_sai_dev *sai = dev_get_drvdata(dev); + int val = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + regmap_read(sai->regmap, SAI_TXFIFOLR, &val); + else + regmap_read(sai->regmap, SAI_RXFIFOLR, &val); + + val = ((val & SAI_FIFOLR_XFL3_MASK) >> SAI_FIFOLR_XFL3_SHIFT) + + ((val & SAI_FIFOLR_XFL2_MASK) >> SAI_FIFOLR_XFL2_SHIFT) + + ((val & SAI_FIFOLR_XFL1_MASK) >> SAI_FIFOLR_XFL1_SHIFT) + + ((val & SAI_FIFOLR_XFL0_MASK) >> SAI_FIFOLR_XFL0_SHIFT); + + return val; +} + +static const struct snd_dlp_config dconfig = { + .get_fifo_count = rockchip_sai_get_fifo_count, +}; + static int rockchip_sai_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -1438,7 +1479,11 @@ return 0; } - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + if (device_property_read_bool(&pdev->dev, "rockchip,digital-loopback")) + ret = devm_snd_dmaengine_dlp_register(&pdev->dev, &dconfig); + else + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + if (ret) goto err_runtime_suspend; -- Gitblit v1.6.2