Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
0002 //
0003 // Copyright (c) 2018 BayLibre, SAS.
0004 // Author: Jerome Brunet <jbrunet@baylibre.com>
0005 
0006 #include <linux/clk.h>
0007 #include <linux/of_irq.h>
0008 #include <linux/of_platform.h>
0009 #include <linux/module.h>
0010 #include <linux/regmap.h>
0011 #include <linux/reset.h>
0012 #include <sound/pcm_params.h>
0013 #include <sound/soc.h>
0014 #include <sound/soc-dai.h>
0015 
0016 #include "axg-fifo.h"
0017 
0018 /*
0019  * This file implements the platform operations common to the playback and
0020  * capture frontend DAI. The logic behind this two types of fifo is very
0021  * similar but some difference exist.
0022  * These differences are handled in the respective DAI drivers
0023  */
0024 
0025 static struct snd_pcm_hardware axg_fifo_hw = {
0026     .info = (SNDRV_PCM_INFO_INTERLEAVED |
0027          SNDRV_PCM_INFO_MMAP |
0028          SNDRV_PCM_INFO_MMAP_VALID |
0029          SNDRV_PCM_INFO_BLOCK_TRANSFER |
0030          SNDRV_PCM_INFO_PAUSE |
0031          SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
0032     .formats = AXG_FIFO_FORMATS,
0033     .rate_min = 5512,
0034     .rate_max = 192000,
0035     .channels_min = 1,
0036     .channels_max = AXG_FIFO_CH_MAX,
0037     .period_bytes_min = AXG_FIFO_BURST,
0038     .period_bytes_max = UINT_MAX,
0039     .periods_min = 2,
0040     .periods_max = UINT_MAX,
0041 
0042     /* No real justification for this */
0043     .buffer_bytes_max = 1 * 1024 * 1024,
0044 };
0045 
0046 static struct snd_soc_dai *axg_fifo_dai(struct snd_pcm_substream *ss)
0047 {
0048     struct snd_soc_pcm_runtime *rtd = ss->private_data;
0049 
0050     return asoc_rtd_to_cpu(rtd, 0);
0051 }
0052 
0053 static struct axg_fifo *axg_fifo_data(struct snd_pcm_substream *ss)
0054 {
0055     struct snd_soc_dai *dai = axg_fifo_dai(ss);
0056 
0057     return snd_soc_dai_get_drvdata(dai);
0058 }
0059 
0060 static struct device *axg_fifo_dev(struct snd_pcm_substream *ss)
0061 {
0062     struct snd_soc_dai *dai = axg_fifo_dai(ss);
0063 
0064     return dai->dev;
0065 }
0066 
0067 static void __dma_enable(struct axg_fifo *fifo,  bool enable)
0068 {
0069     regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_DMA_EN,
0070                enable ? CTRL0_DMA_EN : 0);
0071 }
0072 
0073 int axg_fifo_pcm_trigger(struct snd_soc_component *component,
0074              struct snd_pcm_substream *ss, int cmd)
0075 {
0076     struct axg_fifo *fifo = axg_fifo_data(ss);
0077 
0078     switch (cmd) {
0079     case SNDRV_PCM_TRIGGER_START:
0080     case SNDRV_PCM_TRIGGER_RESUME:
0081     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0082         __dma_enable(fifo, true);
0083         break;
0084     case SNDRV_PCM_TRIGGER_SUSPEND:
0085     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0086     case SNDRV_PCM_TRIGGER_STOP:
0087         __dma_enable(fifo, false);
0088         break;
0089     default:
0090         return -EINVAL;
0091     }
0092 
0093     return 0;
0094 }
0095 EXPORT_SYMBOL_GPL(axg_fifo_pcm_trigger);
0096 
0097 snd_pcm_uframes_t axg_fifo_pcm_pointer(struct snd_soc_component *component,
0098                        struct snd_pcm_substream *ss)
0099 {
0100     struct axg_fifo *fifo = axg_fifo_data(ss);
0101     struct snd_pcm_runtime *runtime = ss->runtime;
0102     unsigned int addr;
0103 
0104     regmap_read(fifo->map, FIFO_STATUS2, &addr);
0105 
0106     return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr);
0107 }
0108 EXPORT_SYMBOL_GPL(axg_fifo_pcm_pointer);
0109 
0110 int axg_fifo_pcm_hw_params(struct snd_soc_component *component,
0111                struct snd_pcm_substream *ss,
0112                struct snd_pcm_hw_params *params)
0113 {
0114     struct snd_pcm_runtime *runtime = ss->runtime;
0115     struct axg_fifo *fifo = axg_fifo_data(ss);
0116     unsigned int burst_num, period, threshold, irq_en;
0117     dma_addr_t end_ptr;
0118 
0119     period = params_period_bytes(params);
0120 
0121     /* Setup dma memory pointers */
0122     end_ptr = runtime->dma_addr + runtime->dma_bytes - AXG_FIFO_BURST;
0123     regmap_write(fifo->map, FIFO_START_ADDR, runtime->dma_addr);
0124     regmap_write(fifo->map, FIFO_FINISH_ADDR, end_ptr);
0125 
0126     /* Setup interrupt periodicity */
0127     burst_num = period / AXG_FIFO_BURST;
0128     regmap_write(fifo->map, FIFO_INT_ADDR, burst_num);
0129 
0130     /*
0131      * Start the fifo request on the smallest of the following:
0132      * - Half the fifo size
0133      * - Half the period size
0134      */
0135     threshold = min(period / 2, fifo->depth / 2);
0136 
0137     /*
0138      * With the threshold in bytes, register value is:
0139      * V = (threshold / burst) - 1
0140      */
0141     threshold /= AXG_FIFO_BURST;
0142     regmap_field_write(fifo->field_threshold,
0143                threshold ? threshold - 1 : 0);
0144 
0145     /* Enable irq if necessary  */
0146     irq_en = runtime->no_period_wakeup ? 0 : FIFO_INT_COUNT_REPEAT;
0147     regmap_update_bits(fifo->map, FIFO_CTRL0,
0148                CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT),
0149                CTRL0_INT_EN(irq_en));
0150 
0151     return 0;
0152 }
0153 EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_params);
0154 
0155 int g12a_fifo_pcm_hw_params(struct snd_soc_component *component,
0156                 struct snd_pcm_substream *ss,
0157                 struct snd_pcm_hw_params *params)
0158 {
0159     struct axg_fifo *fifo = axg_fifo_data(ss);
0160     struct snd_pcm_runtime *runtime = ss->runtime;
0161     int ret;
0162 
0163     ret = axg_fifo_pcm_hw_params(component, ss, params);
0164     if (ret)
0165         return ret;
0166 
0167     /* Set the initial memory address of the DMA */
0168     regmap_write(fifo->map, FIFO_INIT_ADDR, runtime->dma_addr);
0169 
0170     return 0;
0171 }
0172 EXPORT_SYMBOL_GPL(g12a_fifo_pcm_hw_params);
0173 
0174 int axg_fifo_pcm_hw_free(struct snd_soc_component *component,
0175              struct snd_pcm_substream *ss)
0176 {
0177     struct axg_fifo *fifo = axg_fifo_data(ss);
0178 
0179     /* Disable the block count irq */
0180     regmap_update_bits(fifo->map, FIFO_CTRL0,
0181                CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), 0);
0182 
0183     return 0;
0184 }
0185 EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_free);
0186 
0187 static void axg_fifo_ack_irq(struct axg_fifo *fifo, u8 mask)
0188 {
0189     regmap_update_bits(fifo->map, FIFO_CTRL1,
0190                CTRL1_INT_CLR(FIFO_INT_MASK),
0191                CTRL1_INT_CLR(mask));
0192 
0193     /* Clear must also be cleared */
0194     regmap_update_bits(fifo->map, FIFO_CTRL1,
0195                CTRL1_INT_CLR(FIFO_INT_MASK),
0196                0);
0197 }
0198 
0199 static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id)
0200 {
0201     struct snd_pcm_substream *ss = dev_id;
0202     struct axg_fifo *fifo = axg_fifo_data(ss);
0203     unsigned int status;
0204 
0205     regmap_read(fifo->map, FIFO_STATUS1, &status);
0206 
0207     status = STATUS1_INT_STS(status) & FIFO_INT_MASK;
0208     if (status & FIFO_INT_COUNT_REPEAT)
0209         snd_pcm_period_elapsed(ss);
0210     else
0211         dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n",
0212             status);
0213 
0214     /* Ack irqs */
0215     axg_fifo_ack_irq(fifo, status);
0216 
0217     return IRQ_RETVAL(status);
0218 }
0219 
0220 int axg_fifo_pcm_open(struct snd_soc_component *component,
0221               struct snd_pcm_substream *ss)
0222 {
0223     struct axg_fifo *fifo = axg_fifo_data(ss);
0224     struct device *dev = axg_fifo_dev(ss);
0225     int ret;
0226 
0227     snd_soc_set_runtime_hwparams(ss, &axg_fifo_hw);
0228 
0229     /*
0230      * Make sure the buffer and period size are multiple of the FIFO
0231      * burst
0232      */
0233     ret = snd_pcm_hw_constraint_step(ss->runtime, 0,
0234                      SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
0235                      AXG_FIFO_BURST);
0236     if (ret)
0237         return ret;
0238 
0239     ret = snd_pcm_hw_constraint_step(ss->runtime, 0,
0240                      SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
0241                      AXG_FIFO_BURST);
0242     if (ret)
0243         return ret;
0244 
0245     ret = request_irq(fifo->irq, axg_fifo_pcm_irq_block, 0,
0246               dev_name(dev), ss);
0247     if (ret)
0248         return ret;
0249 
0250     /* Enable pclk to access registers and clock the fifo ip */
0251     ret = clk_prepare_enable(fifo->pclk);
0252     if (ret)
0253         goto free_irq;
0254 
0255     /* Setup status2 so it reports the memory pointer */
0256     regmap_update_bits(fifo->map, FIFO_CTRL1,
0257                CTRL1_STATUS2_SEL_MASK,
0258                CTRL1_STATUS2_SEL(STATUS2_SEL_DDR_READ));
0259 
0260     /* Make sure the dma is initially disabled */
0261     __dma_enable(fifo, false);
0262 
0263     /* Disable irqs until params are ready */
0264     regmap_update_bits(fifo->map, FIFO_CTRL0,
0265                CTRL0_INT_EN(FIFO_INT_MASK), 0);
0266 
0267     /* Clear any pending interrupt */
0268     axg_fifo_ack_irq(fifo, FIFO_INT_MASK);
0269 
0270     /* Take memory arbitror out of reset */
0271     ret = reset_control_deassert(fifo->arb);
0272     if (ret)
0273         goto free_clk;
0274 
0275     return 0;
0276 
0277 free_clk:
0278     clk_disable_unprepare(fifo->pclk);
0279 free_irq:
0280     free_irq(fifo->irq, ss);
0281     return ret;
0282 }
0283 EXPORT_SYMBOL_GPL(axg_fifo_pcm_open);
0284 
0285 int axg_fifo_pcm_close(struct snd_soc_component *component,
0286                struct snd_pcm_substream *ss)
0287 {
0288     struct axg_fifo *fifo = axg_fifo_data(ss);
0289     int ret;
0290 
0291     /* Put the memory arbitror back in reset */
0292     ret = reset_control_assert(fifo->arb);
0293 
0294     /* Disable fifo ip and register access */
0295     clk_disable_unprepare(fifo->pclk);
0296 
0297     /* remove IRQ */
0298     free_irq(fifo->irq, ss);
0299 
0300     return ret;
0301 }
0302 EXPORT_SYMBOL_GPL(axg_fifo_pcm_close);
0303 
0304 int axg_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, unsigned int type)
0305 {
0306     struct snd_card *card = rtd->card->snd_card;
0307     size_t size = axg_fifo_hw.buffer_bytes_max;
0308 
0309     snd_pcm_set_managed_buffer(rtd->pcm->streams[type].substream,
0310                    SNDRV_DMA_TYPE_DEV, card->dev,
0311                    size, size);
0312     return 0;
0313 }
0314 EXPORT_SYMBOL_GPL(axg_fifo_pcm_new);
0315 
0316 static const struct regmap_config axg_fifo_regmap_cfg = {
0317     .reg_bits   = 32,
0318     .val_bits   = 32,
0319     .reg_stride = 4,
0320     .max_register   = FIFO_CTRL2,
0321 };
0322 
0323 int axg_fifo_probe(struct platform_device *pdev)
0324 {
0325     struct device *dev = &pdev->dev;
0326     const struct axg_fifo_match_data *data;
0327     struct axg_fifo *fifo;
0328     void __iomem *regs;
0329     int ret;
0330 
0331     data = of_device_get_match_data(dev);
0332     if (!data) {
0333         dev_err(dev, "failed to match device\n");
0334         return -ENODEV;
0335     }
0336 
0337     fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL);
0338     if (!fifo)
0339         return -ENOMEM;
0340     platform_set_drvdata(pdev, fifo);
0341 
0342     regs = devm_platform_ioremap_resource(pdev, 0);
0343     if (IS_ERR(regs))
0344         return PTR_ERR(regs);
0345 
0346     fifo->map = devm_regmap_init_mmio(dev, regs, &axg_fifo_regmap_cfg);
0347     if (IS_ERR(fifo->map)) {
0348         dev_err(dev, "failed to init regmap: %ld\n",
0349             PTR_ERR(fifo->map));
0350         return PTR_ERR(fifo->map);
0351     }
0352 
0353     fifo->pclk = devm_clk_get(dev, NULL);
0354     if (IS_ERR(fifo->pclk))
0355         return dev_err_probe(dev, PTR_ERR(fifo->pclk), "failed to get pclk\n");
0356 
0357     fifo->arb = devm_reset_control_get_exclusive(dev, NULL);
0358     if (IS_ERR(fifo->arb))
0359         return dev_err_probe(dev, PTR_ERR(fifo->arb), "failed to get arb reset\n");
0360 
0361     fifo->irq = of_irq_get(dev->of_node, 0);
0362     if (fifo->irq <= 0) {
0363         dev_err(dev, "failed to get irq: %d\n", fifo->irq);
0364         return fifo->irq;
0365     }
0366 
0367     fifo->field_threshold =
0368         devm_regmap_field_alloc(dev, fifo->map, data->field_threshold);
0369     if (IS_ERR(fifo->field_threshold))
0370         return PTR_ERR(fifo->field_threshold);
0371 
0372     ret = of_property_read_u32(dev->of_node, "amlogic,fifo-depth",
0373                    &fifo->depth);
0374     if (ret) {
0375         /* Error out for anything but a missing property */
0376         if (ret != -EINVAL)
0377             return ret;
0378         /*
0379          * If the property is missing, it might be because of an old
0380          * DT. In such case, assume the smallest known fifo depth
0381          */
0382         fifo->depth = 256;
0383         dev_warn(dev, "fifo depth not found, assume %u bytes\n",
0384              fifo->depth);
0385     }
0386 
0387     return devm_snd_soc_register_component(dev, data->component_drv,
0388                            data->dai_drv, 1);
0389 }
0390 EXPORT_SYMBOL_GPL(axg_fifo_probe);
0391 
0392 MODULE_DESCRIPTION("Amlogic AXG/G12A fifo driver");
0393 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
0394 MODULE_LICENSE("GPL v2");