diff options
-rw-r--r-- | sound/soc/meson/axg-fifo.c | 27 | ||||
-rw-r--r-- | sound/soc/meson/axg-fifo.h | 6 | ||||
-rw-r--r-- | sound/soc/meson/axg-frddr.c | 24 | ||||
-rw-r--r-- | sound/soc/meson/axg-toddr.c | 21 |
4 files changed, 50 insertions, 28 deletions
diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c index 772eda857019..4365086c9a31 100644 --- a/sound/soc/meson/axg-fifo.c +++ b/sound/soc/meson/axg-fifo.c @@ -113,8 +113,10 @@ int axg_fifo_pcm_hw_params(struct snd_soc_component *component, { struct snd_pcm_runtime *runtime = ss->runtime; struct axg_fifo *fifo = axg_fifo_data(ss); + unsigned int burst_num, period, threshold; dma_addr_t end_ptr; - unsigned int burst_num; + + period = params_period_bytes(params); /* Setup dma memory pointers */ end_ptr = runtime->dma_addr + runtime->dma_bytes - AXG_FIFO_BURST; @@ -122,9 +124,25 @@ int axg_fifo_pcm_hw_params(struct snd_soc_component *component, regmap_write(fifo->map, FIFO_FINISH_ADDR, end_ptr); /* Setup interrupt periodicity */ - burst_num = params_period_bytes(params) / AXG_FIFO_BURST; + burst_num = period / AXG_FIFO_BURST; regmap_write(fifo->map, FIFO_INT_ADDR, burst_num); + /* + * Start the fifo request on the smallest of the following: + * - Half the fifo size + * - Half the period size + */ + threshold = min(period / 2, + (unsigned int)AXG_FIFO_MIN_DEPTH / 2); + + /* + * With the threshold in bytes, register value is: + * V = (threshold / burst) - 1 + */ + threshold /= AXG_FIFO_BURST; + regmap_field_write(fifo->field_threshold, + threshold ? threshold - 1 : 0); + /* Enable block count irq */ regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), @@ -347,6 +365,11 @@ int axg_fifo_probe(struct platform_device *pdev) return fifo->irq; } + fifo->field_threshold = + devm_regmap_field_alloc(dev, fifo->map, data->field_threshold); + if (IS_ERR(fifo->field_threshold)) + return PTR_ERR(fifo->field_threshold); + return devm_snd_soc_register_component(dev, data->component_drv, data->dai_drv, 1); } diff --git a/sound/soc/meson/axg-fifo.h b/sound/soc/meson/axg-fifo.h index cf928d43b558..c442195ba191 100644 --- a/sound/soc/meson/axg-fifo.h +++ b/sound/soc/meson/axg-fifo.h @@ -9,7 +9,9 @@ struct clk; struct platform_device; +struct reg_field; struct regmap; +struct regmap_field; struct reset_control; struct snd_soc_component_driver; @@ -50,8 +52,6 @@ struct snd_soc_pcm_runtime; #define CTRL1_STATUS2_SEL_MASK GENMASK(11, 8) #define CTRL1_STATUS2_SEL(x) ((x) << 8) #define STATUS2_SEL_DDR_READ 0 -#define CTRL1_THRESHOLD_MASK GENMASK(23, 16) -#define CTRL1_THRESHOLD(x) ((x) << 16) #define CTRL1_FRDDR_DEPTH_MASK GENMASK(31, 24) #define CTRL1_FRDDR_DEPTH(x) ((x) << 24) #define FIFO_START_ADDR 0x08 @@ -67,12 +67,14 @@ struct axg_fifo { struct regmap *map; struct clk *pclk; struct reset_control *arb; + struct regmap_field *field_threshold; int irq; }; struct axg_fifo_match_data { const struct snd_soc_component_driver *component_drv; struct snd_soc_dai_driver *dai_drv; + struct reg_field field_threshold; }; int axg_fifo_pcm_open(struct snd_soc_component *component, diff --git a/sound/soc/meson/axg-frddr.c b/sound/soc/meson/axg-frddr.c index 0a7d41257a38..df104303351f 100644 --- a/sound/soc/meson/axg-frddr.c +++ b/sound/soc/meson/axg-frddr.c @@ -50,7 +50,7 @@ static int axg_frddr_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); - unsigned int fifo_depth, fifo_threshold; + unsigned int fifo_depth; int ret; /* Enable pclk to access registers and clock the fifo ip */ @@ -68,11 +68,8 @@ static int axg_frddr_dai_startup(struct snd_pcm_substream *substream, * Depth and threshold are zero based. */ fifo_depth = AXG_FIFO_MIN_CNT - 1; - fifo_threshold = (AXG_FIFO_MIN_CNT / 2) - 1; - regmap_update_bits(fifo->map, FIFO_CTRL1, - CTRL1_FRDDR_DEPTH_MASK | CTRL1_THRESHOLD_MASK, - CTRL1_FRDDR_DEPTH(fifo_depth) | - CTRL1_THRESHOLD(fifo_threshold)); + regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_FRDDR_DEPTH_MASK, + CTRL1_FRDDR_DEPTH(fifo_depth)); return 0; } @@ -158,8 +155,9 @@ static const struct snd_soc_component_driver axg_frddr_component_drv = { }; static const struct axg_fifo_match_data axg_frddr_match_data = { - .component_drv = &axg_frddr_component_drv, - .dai_drv = &axg_frddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &axg_frddr_component_drv, + .dai_drv = &axg_frddr_dai_drv }; static const struct snd_soc_dai_ops g12a_frddr_ops = { @@ -281,8 +279,9 @@ static const struct snd_soc_component_driver g12a_frddr_component_drv = { }; static const struct axg_fifo_match_data g12a_frddr_match_data = { - .component_drv = &g12a_frddr_component_drv, - .dai_drv = &g12a_frddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &g12a_frddr_component_drv, + .dai_drv = &g12a_frddr_dai_drv }; /* On SM1, the output selection in on CTRL2 */ @@ -350,8 +349,9 @@ static const struct snd_soc_component_driver sm1_frddr_component_drv = { }; static const struct axg_fifo_match_data sm1_frddr_match_data = { - .component_drv = &sm1_frddr_component_drv, - .dai_drv = &g12a_frddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &sm1_frddr_component_drv, + .dai_drv = &g12a_frddr_dai_drv }; static const struct of_device_id axg_frddr_of_match[] = { diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c index f6023397c8fe..e711abcf8c12 100644 --- a/sound/soc/meson/axg-toddr.c +++ b/sound/soc/meson/axg-toddr.c @@ -89,7 +89,6 @@ static int axg_toddr_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); - unsigned int fifo_threshold; int ret; /* Enable pclk to access registers and clock the fifo ip */ @@ -107,11 +106,6 @@ static int axg_toddr_dai_startup(struct snd_pcm_substream *substream, /* Apply single buffer mode to the interface */ regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_TODDR_PP_MODE, 0); - /* TODDR does not have a configurable fifo depth */ - fifo_threshold = AXG_FIFO_MIN_CNT - 1; - regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_THRESHOLD_MASK, - CTRL1_THRESHOLD(fifo_threshold)); - return 0; } @@ -190,8 +184,9 @@ static const struct snd_soc_component_driver axg_toddr_component_drv = { }; static const struct axg_fifo_match_data axg_toddr_match_data = { - .component_drv = &axg_toddr_component_drv, - .dai_drv = &axg_toddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &axg_toddr_component_drv, + .dai_drv = &axg_toddr_dai_drv }; static const struct snd_soc_dai_ops g12a_toddr_ops = { @@ -228,8 +223,9 @@ static const struct snd_soc_component_driver g12a_toddr_component_drv = { }; static const struct axg_fifo_match_data g12a_toddr_match_data = { - .component_drv = &g12a_toddr_component_drv, - .dai_drv = &g12a_toddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 16, 23), + .component_drv = &g12a_toddr_component_drv, + .dai_drv = &g12a_toddr_dai_drv }; static const char * const sm1_toddr_sel_texts[] = { @@ -297,8 +293,9 @@ static const struct snd_soc_component_driver sm1_toddr_component_drv = { }; static const struct axg_fifo_match_data sm1_toddr_match_data = { - .component_drv = &sm1_toddr_component_drv, - .dai_drv = &g12a_toddr_dai_drv + .field_threshold = REG_FIELD(FIFO_CTRL1, 12, 23), + .component_drv = &sm1_toddr_component_drv, + .dai_drv = &g12a_toddr_dai_drv }; static const struct of_device_id axg_toddr_of_match[] = { |