// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics 2016
 * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
 */

#include <linux/bitfield.h>
#include <linux/mfd/stm32-timers.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/reset.h>

#define STM32_TIMERS_MAX_REGISTERS	0x3fc

/* DIER register DMA enable bits */
static const u32 stm32_timers_dier_dmaen[STM32_TIMERS_MAX_DMAS] = {
	TIM_DIER_CC1DE,
	TIM_DIER_CC2DE,
	TIM_DIER_CC3DE,
	TIM_DIER_CC4DE,
	TIM_DIER_UIE,
	TIM_DIER_TDE,
	TIM_DIER_COMDE
};

static void stm32_timers_dma_done(void *p)
{
	struct stm32_timers_dma *dma = p;
	struct dma_tx_state state;
	enum dma_status status;

	status = dmaengine_tx_status(dma->chan, dma->chan->cookie, &state);
	if (status == DMA_COMPLETE)
		complete(&dma->completion);
}

/**
 * stm32_timers_dma_burst_read - Read from timers registers using DMA.
 *
 * Read from STM32 timers registers using DMA on a single event.
 * @dev: reference to stm32_timers MFD device
 * @buf: DMA'able destination buffer
 * @id: stm32_timers_dmas event identifier (ch[1..4], up, trig or com)
 * @reg: registers start offset for DMA to read from (like CCRx for capture)
 * @num_reg: number of registers to read upon each DMA request, starting @reg.
 * @bursts: number of bursts to read (e.g. like two for pwm period capture)
 * @tmo_ms: timeout (milliseconds)
 */
int stm32_timers_dma_burst_read(struct device *dev, u32 *buf,
				enum stm32_timers_dmas id, u32 reg,
				unsigned int num_reg, unsigned int bursts,
				unsigned long tmo_ms)
{
	struct stm32_timers *ddata = dev_get_drvdata(dev);
	unsigned long timeout = msecs_to_jiffies(tmo_ms);
	struct regmap *regmap = ddata->regmap;
	struct stm32_timers_dma *dma = &ddata->dma;
	size_t len = num_reg * bursts * sizeof(u32);
	struct dma_async_tx_descriptor *desc;
	struct dma_slave_config config;
	dma_cookie_t cookie;
	dma_addr_t dma_buf;
	u32 dbl, dba;
	long err;
	int ret;

	/* Sanity check */
	if (id < STM32_TIMERS_DMA_CH1 || id >= STM32_TIMERS_MAX_DMAS)
		return -EINVAL;

	if (!num_reg || !bursts || reg > STM32_TIMERS_MAX_REGISTERS ||
	    (reg + num_reg * sizeof(u32)) > STM32_TIMERS_MAX_REGISTERS)
		return -EINVAL;

	if (!dma->chans[id])
		return -ENODEV;
	mutex_lock(&dma->lock);

	/* Select DMA channel in use */
	dma->chan = dma->chans[id];
	dma_buf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
	if (dma_mapping_error(dev, dma_buf)) {
		ret = -ENOMEM;
		goto unlock;
	}

	/* Prepare DMA read from timer registers, using DMA burst mode */
	memset(&config, 0, sizeof(config));
	config.src_addr = (dma_addr_t)dma->phys_base + TIM_DMAR;
	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	ret = dmaengine_slave_config(dma->chan, &config);
	if (ret)
		goto unmap;

	desc = dmaengine_prep_slave_single(dma->chan, dma_buf, len,
					   DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
	if (!desc) {
		ret = -EBUSY;
		goto unmap;
	}

	desc->callback = stm32_timers_dma_done;
	desc->callback_param = dma;
	cookie = dmaengine_submit(desc);
	ret = dma_submit_error(cookie);
	if (ret)
		goto dma_term;

	reinit_completion(&dma->completion);
	dma_async_issue_pending(dma->chan);

	/* Setup and enable timer DMA burst mode */
	dbl = FIELD_PREP(TIM_DCR_DBL, bursts - 1);
	dba = FIELD_PREP(TIM_DCR_DBA, reg >> 2);
	ret = regmap_write(regmap, TIM_DCR, dbl | dba);
	if (ret)
		goto dma_term;

	/* Clear pending flags before enabling DMA request */
	ret = regmap_write(regmap, TIM_SR, 0);
	if (ret)
		goto dcr_clr;

	ret = regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id],
				 stm32_timers_dier_dmaen[id]);
	if (ret)
		goto dcr_clr;

	err = wait_for_completion_interruptible_timeout(&dma->completion,
							timeout);
	if (err == 0)
		ret = -ETIMEDOUT;
	else if (err < 0)
		ret = err;

	regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id], 0);
	regmap_write(regmap, TIM_SR, 0);
dcr_clr:
	regmap_write(regmap, TIM_DCR, 0);
dma_term:
	dmaengine_terminate_all(dma->chan);
unmap:
	dma_unmap_single(dev, dma_buf, len, DMA_FROM_DEVICE);
unlock:
	dma->chan = NULL;
	mutex_unlock(&dma->lock);

	return ret;
}
EXPORT_SYMBOL_GPL(stm32_timers_dma_burst_read);

static const struct regmap_config stm32_timers_regmap_cfg = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = sizeof(u32),
	.max_register = STM32_TIMERS_MAX_REGISTERS,
};

static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
{
	u32 arr;

	/* Backup ARR to restore it after getting the maximum value */
	regmap_read(ddata->regmap, TIM_ARR, &arr);

	/*
	 * Only the available bits will be written so when readback
	 * we get the maximum value of auto reload register
	 */
	regmap_write(ddata->regmap, TIM_ARR, ~0L);
	regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr);
	regmap_write(ddata->regmap, TIM_ARR, arr);
}

static int stm32_timers_probe_hwcfgr(struct device *dev, struct stm32_timers *ddata)
{
	u32 val;

	ddata->ipidr = (uintptr_t)device_get_match_data(dev);
	if (!ddata->ipidr) {
		/* Fallback to legacy method for probing counter width */
		stm32_timers_get_arr_size(ddata);
		return 0;
	}

	regmap_read(ddata->regmap, TIM_IPIDR, &val);
	if (val != ddata->ipidr) {
		dev_err(dev, "Unsupported device detected: %u\n", val);
		return -EINVAL;
	}

	regmap_read(ddata->regmap, TIM_HWCFGR2, &val);

	/* Counter width in bits, max reload value is BIT(width) - 1 */
	ddata->max_arr = BIT(FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val)) - 1;

	return 0;
}

static int stm32_timers_dma_probe(struct device *dev,
				   struct stm32_timers *ddata)
{
	int i;
	int ret = 0;
	char name[4];

	init_completion(&ddata->dma.completion);
	mutex_init(&ddata->dma.lock);

	/* Optional DMA support: get valid DMA channel(s) or NULL */
	for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) {
		snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1);
		ddata->dma.chans[i] = dma_request_chan(dev, name);
	}
	ddata->dma.chans[STM32_TIMERS_DMA_UP] = dma_request_chan(dev, "up");
	ddata->dma.chans[STM32_TIMERS_DMA_TRIG] = dma_request_chan(dev, "trig");
	ddata->dma.chans[STM32_TIMERS_DMA_COM] = dma_request_chan(dev, "com");

	for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++) {
		if (IS_ERR(ddata->dma.chans[i])) {
			/* Save the first error code to return */
			if (PTR_ERR(ddata->dma.chans[i]) != -ENODEV && !ret)
				ret = PTR_ERR(ddata->dma.chans[i]);

			ddata->dma.chans[i] = NULL;
		}
	}

	return ret;
}

static void stm32_timers_dma_remove(struct device *dev,
				    struct stm32_timers *ddata)
{
	int i;

	for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++)
		if (ddata->dma.chans[i])
			dma_release_channel(ddata->dma.chans[i]);
}

static const char * const stm32_timers_irq_name[STM32_TIMERS_MAX_IRQS] = {
	"brk", "up", "trg-com", "cc"
};

static int stm32_timers_irq_probe(struct platform_device *pdev,
				  struct stm32_timers *ddata)
{
	int i, ret;

	/*
	 * STM32 Timer may have either:
	 * - a unique global interrupt line
	 * - four dedicated interrupt lines that may be handled separately.
	 * Optionally get them here, to be used by child devices.
	 */
	ret = platform_get_irq_byname_optional(pdev, "global");
	if (ret < 0 && ret != -ENXIO) {
		return ret;
	} else if (ret != -ENXIO) {
		ddata->irq[STM32_TIMERS_IRQ_GLOBAL_BRK] = ret;
		ddata->nr_irqs = 1;
		return 0;
	}

	for (i = 0; i < STM32_TIMERS_MAX_IRQS; i++) {
		ret = platform_get_irq_byname_optional(pdev, stm32_timers_irq_name[i]);
		if (ret < 0 && ret != -ENXIO) {
			return ret;
		} else if (ret != -ENXIO) {
			ddata->irq[i] = ret;
			ddata->nr_irqs++;
		}
	}

	if (ddata->nr_irqs && ddata->nr_irqs != STM32_TIMERS_MAX_IRQS) {
		dev_err(&pdev->dev, "Invalid number of IRQs %d\n", ddata->nr_irqs);
		return -EINVAL;
	}

	return 0;
}

static int stm32_timers_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct stm32_timers *ddata;
	struct resource *res;
	void __iomem *mmio;
	int ret;

	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
	if (!ddata)
		return -ENOMEM;

	mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(mmio))
		return PTR_ERR(mmio);

	/* Timer physical addr for DMA */
	ddata->dma.phys_base = res->start;

	ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio,
						  &stm32_timers_regmap_cfg);
	if (IS_ERR(ddata->regmap))
		return PTR_ERR(ddata->regmap);

	ddata->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(ddata->clk))
		return PTR_ERR(ddata->clk);

	ret = stm32_timers_probe_hwcfgr(dev, ddata);
	if (ret)
		return ret;

	ret = stm32_timers_irq_probe(pdev, ddata);
	if (ret)
		return ret;

	ret = stm32_timers_dma_probe(dev, ddata);
	if (ret) {
		stm32_timers_dma_remove(dev, ddata);
		return ret;
	}

	platform_set_drvdata(pdev, ddata);

	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
	if (ret)
		stm32_timers_dma_remove(dev, ddata);

	return ret;
}

static void stm32_timers_remove(struct platform_device *pdev)
{
	struct stm32_timers *ddata = platform_get_drvdata(pdev);

	/*
	 * Don't use devm_ here: enfore of_platform_depopulate() happens before
	 * DMA are released, to avoid race on DMA.
	 */
	of_platform_depopulate(&pdev->dev);
	stm32_timers_dma_remove(&pdev->dev, ddata);
}

static const struct of_device_id stm32_timers_of_match[] = {
	{ .compatible = "st,stm32-timers", },
	{ .compatible = "st,stm32mp25-timers", .data = (void *)STM32MP25_TIM_IPIDR },
	{ /* end node */ },
};
MODULE_DEVICE_TABLE(of, stm32_timers_of_match);

static struct platform_driver stm32_timers_driver = {
	.probe = stm32_timers_probe,
	.remove = stm32_timers_remove,
	.driver	= {
		.name = "stm32-timers",
		.of_match_table = stm32_timers_of_match,
	},
};
module_platform_driver(stm32_timers_driver);

MODULE_DESCRIPTION("STMicroelectronics STM32 Timers");
MODULE_LICENSE("GPL v2");
