// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018 BayLibre, SAS
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 * Copyright (C) 2014 Endless Mobile
 */

#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/soc/amlogic/meson-canvas.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/io.h>

#define NUM_CANVAS 256

/* DMC Registers */
#define DMC_CAV_LUT_DATAL	0x00
	#define CANVAS_WIDTH_LBIT	29
	#define CANVAS_WIDTH_LWID	3
#define DMC_CAV_LUT_DATAH	0x04
	#define CANVAS_WIDTH_HBIT	0
	#define CANVAS_HEIGHT_BIT	9
	#define CANVAS_WRAP_BIT		22
	#define CANVAS_BLKMODE_BIT	24
	#define CANVAS_ENDIAN_BIT	26
#define DMC_CAV_LUT_ADDR	0x08
	#define CANVAS_LUT_WR_EN	BIT(9)
	#define CANVAS_LUT_RD_EN	BIT(8)

struct meson_canvas {
	struct device *dev;
	void __iomem *reg_base;
	spinlock_t lock; /* canvas device lock */
	u8 used[NUM_CANVAS];
	bool supports_endianness;
};

static void canvas_write(struct meson_canvas *canvas, u32 reg, u32 val)
{
	writel_relaxed(val, canvas->reg_base + reg);
}

static u32 canvas_read(struct meson_canvas *canvas, u32 reg)
{
	return readl_relaxed(canvas->reg_base + reg);
}

struct meson_canvas *meson_canvas_get(struct device *dev)
{
	struct device_node *canvas_node;
	struct platform_device *canvas_pdev;
	struct meson_canvas *canvas;

	canvas_node = of_parse_phandle(dev->of_node, "amlogic,canvas", 0);
	if (!canvas_node)
		return ERR_PTR(-ENODEV);

	canvas_pdev = of_find_device_by_node(canvas_node);
	if (!canvas_pdev) {
		of_node_put(canvas_node);
		return ERR_PTR(-EPROBE_DEFER);
	}

	of_node_put(canvas_node);

	/*
	 * If priv is NULL, it's probably because the canvas hasn't
	 * properly initialized. Bail out with -EINVAL because, in the
	 * current state, this driver probe cannot return -EPROBE_DEFER
	 */
	canvas = dev_get_drvdata(&canvas_pdev->dev);
	if (!canvas)
		return ERR_PTR(-EINVAL);

	return canvas;
}
EXPORT_SYMBOL_GPL(meson_canvas_get);

int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index,
			u32 addr, u32 stride, u32 height,
			unsigned int wrap,
			unsigned int blkmode,
			unsigned int endian)
{
	unsigned long flags;

	if (endian && !canvas->supports_endianness) {
		dev_err(canvas->dev,
			"Endianness is not supported on this SoC\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&canvas->lock, flags);
	if (!canvas->used[canvas_index]) {
		dev_err(canvas->dev,
			"Trying to setup non allocated canvas %u\n",
			canvas_index);
		spin_unlock_irqrestore(&canvas->lock, flags);
		return -EINVAL;
	}

	canvas_write(canvas, DMC_CAV_LUT_DATAL,
		     ((addr + 7) >> 3) |
		     (((stride + 7) >> 3) << CANVAS_WIDTH_LBIT));

	canvas_write(canvas, DMC_CAV_LUT_DATAH,
		     ((((stride + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
						CANVAS_WIDTH_HBIT) |
		     (height << CANVAS_HEIGHT_BIT) |
		     (wrap << CANVAS_WRAP_BIT) |
		     (blkmode << CANVAS_BLKMODE_BIT) |
		     (endian << CANVAS_ENDIAN_BIT));

	canvas_write(canvas, DMC_CAV_LUT_ADDR,
		     CANVAS_LUT_WR_EN | canvas_index);

	/* Force a read-back to make sure everything is flushed. */
	canvas_read(canvas, DMC_CAV_LUT_DATAH);
	spin_unlock_irqrestore(&canvas->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(meson_canvas_config);

int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index)
{
	int i;
	unsigned long flags;

	spin_lock_irqsave(&canvas->lock, flags);
	for (i = 0; i < NUM_CANVAS; ++i) {
		if (!canvas->used[i]) {
			canvas->used[i] = 1;
			spin_unlock_irqrestore(&canvas->lock, flags);
			*canvas_index = i;
			return 0;
		}
	}
	spin_unlock_irqrestore(&canvas->lock, flags);

	dev_err(canvas->dev, "No more canvas available\n");
	return -ENODEV;
}
EXPORT_SYMBOL_GPL(meson_canvas_alloc);

int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index)
{
	unsigned long flags;

	spin_lock_irqsave(&canvas->lock, flags);
	if (!canvas->used[canvas_index]) {
		dev_err(canvas->dev,
			"Trying to free unused canvas %u\n", canvas_index);
		spin_unlock_irqrestore(&canvas->lock, flags);
		return -EINVAL;
	}
	canvas->used[canvas_index] = 0;
	spin_unlock_irqrestore(&canvas->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(meson_canvas_free);

static int meson_canvas_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct meson_canvas *canvas;
	struct device *dev = &pdev->dev;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	canvas->reg_base = devm_ioremap_resource(dev, res);
	if (IS_ERR(canvas->reg_base))
		return PTR_ERR(canvas->reg_base);

	canvas->supports_endianness = of_device_get_match_data(dev);

	canvas->dev = dev;
	spin_lock_init(&canvas->lock);
	dev_set_drvdata(dev, canvas);

	return 0;
}

static const struct of_device_id canvas_dt_match[] = {
	{ .compatible = "amlogic,meson8-canvas", .data = (void *)false, },
	{ .compatible = "amlogic,meson8b-canvas", .data = (void *)false, },
	{ .compatible = "amlogic,meson8m2-canvas", .data = (void *)false, },
	{ .compatible = "amlogic,canvas", .data = (void *)true, },
	{}
};
MODULE_DEVICE_TABLE(of, canvas_dt_match);

static struct platform_driver meson_canvas_driver = {
	.probe = meson_canvas_probe,
	.driver = {
		.name = "amlogic-canvas",
		.of_match_table = canvas_dt_match,
	},
};
module_platform_driver(meson_canvas_driver);

MODULE_DESCRIPTION("Amlogic Canvas driver");
MODULE_AUTHOR("Maxime Jourdan <mjourdan@baylibre.com>");
MODULE_LICENSE("GPL");
