// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019-2022 Bootlin
 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/regmap.h>
#include <linux/types.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_generic.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_print.h>

#include "logicvc_crtc.h"
#include "logicvc_drm.h"
#include "logicvc_interface.h"
#include "logicvc_mode.h"
#include "logicvc_layer.h"
#include "logicvc_of.h"
#include "logicvc_regs.h"

DEFINE_DRM_GEM_DMA_FOPS(logicvc_drm_fops);

static int logicvc_drm_gem_dma_dumb_create(struct drm_file *file_priv,
					   struct drm_device *drm_dev,
					   struct drm_mode_create_dumb *args)
{
	struct logicvc_drm *logicvc = logicvc_drm(drm_dev);

	/* Stride is always fixed to its configuration value. */
	args->pitch = logicvc->config.row_stride * DIV_ROUND_UP(args->bpp, 8);

	return drm_gem_dma_dumb_create_internal(file_priv, drm_dev, args);
}

static struct drm_driver logicvc_drm_driver = {
	.driver_features		= DRIVER_GEM | DRIVER_MODESET |
					  DRIVER_ATOMIC,

	.fops				= &logicvc_drm_fops,
	.name				= "logicvc-drm",
	.desc				= "Xylon LogiCVC DRM driver",
	.date				= "20200403",
	.major				= 1,
	.minor				= 0,

	DRM_GEM_DMA_DRIVER_OPS_VMAP_WITH_DUMB_CREATE(logicvc_drm_gem_dma_dumb_create),
};

static struct regmap_config logicvc_drm_regmap_config = {
	.reg_bits	= 32,
	.val_bits	= 32,
	.reg_stride	= 4,
	.name		= "logicvc-drm",
};

static irqreturn_t logicvc_drm_irq_handler(int irq, void *data)
{
	struct logicvc_drm *logicvc = data;
	irqreturn_t ret = IRQ_NONE;
	u32 stat = 0;

	/* Get pending interrupt sources. */
	regmap_read(logicvc->regmap, LOGICVC_INT_STAT_REG, &stat);

	/* Clear all pending interrupt sources. */
	regmap_write(logicvc->regmap, LOGICVC_INT_STAT_REG, stat);

	if (stat & LOGICVC_INT_STAT_V_SYNC) {
		logicvc_crtc_vblank_handler(logicvc);
		ret = IRQ_HANDLED;
	}

	return ret;
}

static int logicvc_drm_config_parse(struct logicvc_drm *logicvc)
{
	struct drm_device *drm_dev = &logicvc->drm_dev;
	struct device *dev = drm_dev->dev;
	struct device_node *of_node = dev->of_node;
	struct logicvc_drm_config *config = &logicvc->config;
	struct device_node *layers_node;
	int ret;

	logicvc_of_property_parse_bool(of_node, LOGICVC_OF_PROPERTY_DITHERING,
				       &config->dithering);
	logicvc_of_property_parse_bool(of_node,
				       LOGICVC_OF_PROPERTY_BACKGROUND_LAYER,
				       &config->background_layer);
	logicvc_of_property_parse_bool(of_node,
				       LOGICVC_OF_PROPERTY_LAYERS_CONFIGURABLE,
				       &config->layers_configurable);

	ret = logicvc_of_property_parse_u32(of_node,
					    LOGICVC_OF_PROPERTY_DISPLAY_INTERFACE,
					    &config->display_interface);
	if (ret)
		return ret;

	ret = logicvc_of_property_parse_u32(of_node,
					    LOGICVC_OF_PROPERTY_DISPLAY_COLORSPACE,
					    &config->display_colorspace);
	if (ret)
		return ret;

	ret = logicvc_of_property_parse_u32(of_node,
					    LOGICVC_OF_PROPERTY_DISPLAY_DEPTH,
					    &config->display_depth);
	if (ret)
		return ret;

	ret = logicvc_of_property_parse_u32(of_node,
					    LOGICVC_OF_PROPERTY_ROW_STRIDE,
					    &config->row_stride);
	if (ret)
		return ret;

	layers_node = of_get_child_by_name(of_node, "layers");
	if (!layers_node) {
		drm_err(drm_dev, "Missing non-optional layers node\n");
		return -EINVAL;
	}

	config->layers_count = of_get_child_count(layers_node);
	if (!config->layers_count) {
		drm_err(drm_dev,
			"Missing a non-optional layers children node\n");
		return -EINVAL;
	}

	return 0;
}

static int logicvc_clocks_prepare(struct logicvc_drm *logicvc)
{
	struct drm_device *drm_dev = &logicvc->drm_dev;
	struct device *dev = drm_dev->dev;

	struct {
		struct clk **clk;
		char *name;
		bool optional;
	} clocks_map[] = {
		{
			.clk = &logicvc->vclk,
			.name = "vclk",
			.optional = false,
		},
		{
			.clk = &logicvc->vclk2,
			.name = "vclk2",
			.optional = true,
		},
		{
			.clk = &logicvc->lvdsclk,
			.name = "lvdsclk",
			.optional = true,
		},
		{
			.clk = &logicvc->lvdsclkn,
			.name = "lvdsclkn",
			.optional = true,
		},
	};
	unsigned int i;
	int ret;

	for (i = 0; i < ARRAY_SIZE(clocks_map); i++) {
		struct clk *clk;

		clk = devm_clk_get(dev, clocks_map[i].name);
		if (IS_ERR(clk)) {
			if (PTR_ERR(clk) == -ENOENT && clocks_map[i].optional)
				continue;

			drm_err(drm_dev, "Missing non-optional clock %s\n",
				clocks_map[i].name);

			ret = PTR_ERR(clk);
			goto error;
		}

		ret = clk_prepare_enable(clk);
		if (ret) {
			drm_err(drm_dev,
				"Failed to prepare and enable clock %s\n",
				clocks_map[i].name);
			goto error;
		}

		*clocks_map[i].clk = clk;
	}

	return 0;

error:
	for (i = 0; i < ARRAY_SIZE(clocks_map); i++) {
		if (!*clocks_map[i].clk)
			continue;

		clk_disable_unprepare(*clocks_map[i].clk);
		*clocks_map[i].clk = NULL;
	}

	return ret;
}

static int logicvc_clocks_unprepare(struct logicvc_drm *logicvc)
{
	struct clk **clocks[] = {
		&logicvc->vclk,
		&logicvc->vclk2,
		&logicvc->lvdsclk,
		&logicvc->lvdsclkn,
	};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(clocks); i++) {
		if (!*clocks[i])
			continue;

		clk_disable_unprepare(*clocks[i]);
		*clocks[i] = NULL;
	}

	return 0;
}

static const struct logicvc_drm_caps logicvc_drm_caps[] = {
	{
		.major		= 3,
		.layer_address	= false,
	},
	{
		.major		= 4,
		.layer_address	= true,
	},
	{
		.major		= 5,
		.layer_address	= true,
	},
};

static const struct logicvc_drm_caps *
logicvc_drm_caps_match(struct logicvc_drm *logicvc)
{
	struct drm_device *drm_dev = &logicvc->drm_dev;
	const struct logicvc_drm_caps *caps = NULL;
	unsigned int major, minor;
	char level;
	unsigned int i;
	u32 version;

	regmap_read(logicvc->regmap, LOGICVC_IP_VERSION_REG, &version);

	major = FIELD_GET(LOGICVC_IP_VERSION_MAJOR_MASK, version);
	minor = FIELD_GET(LOGICVC_IP_VERSION_MINOR_MASK, version);
	level = FIELD_GET(LOGICVC_IP_VERSION_LEVEL_MASK, version) + 'a';

	for (i = 0; i < ARRAY_SIZE(logicvc_drm_caps); i++) {
		if (logicvc_drm_caps[i].major &&
		    logicvc_drm_caps[i].major != major)
			continue;

		if (logicvc_drm_caps[i].minor &&
		    logicvc_drm_caps[i].minor != minor)
			continue;

		if (logicvc_drm_caps[i].level &&
		    logicvc_drm_caps[i].level != level)
			continue;

		caps = &logicvc_drm_caps[i];
	}

	drm_info(drm_dev, "LogiCVC version %d.%02d.%c\n", major, minor, level);

	return caps;
}

static int logicvc_drm_probe(struct platform_device *pdev)
{
	struct device_node *of_node = pdev->dev.of_node;
	struct device_node *reserved_mem_node;
	struct reserved_mem *reserved_mem = NULL;
	const struct logicvc_drm_caps *caps;
	struct logicvc_drm *logicvc;
	struct device *dev = &pdev->dev;
	struct drm_device *drm_dev;
	struct regmap *regmap = NULL;
	struct resource res;
	void __iomem *base;
	int irq;
	int ret;

	ret = of_reserved_mem_device_init(dev);
	if (ret && ret != -ENODEV) {
		dev_err(dev, "Failed to init memory region\n");
		goto error_early;
	}

	reserved_mem_node = of_parse_phandle(of_node, "memory-region", 0);
	if (reserved_mem_node) {
		reserved_mem = of_reserved_mem_lookup(reserved_mem_node);
		of_node_put(reserved_mem_node);
	}

	/* Get regmap from parent if available. */
	if (of_node->parent)
		regmap = syscon_node_to_regmap(of_node->parent);

	/* Register our own regmap otherwise. */
	if (IS_ERR_OR_NULL(regmap)) {
		ret = of_address_to_resource(of_node, 0, &res);
		if (ret) {
			dev_err(dev, "Failed to get resource from address\n");
			goto error_reserved_mem;
		}

		base = devm_ioremap_resource(dev, &res);
		if (IS_ERR(base)) {
			dev_err(dev, "Failed to map I/O base\n");
			ret = PTR_ERR(base);
			goto error_reserved_mem;
		}

		logicvc_drm_regmap_config.max_register = resource_size(&res) -
							 4;

		regmap = devm_regmap_init_mmio(dev, base,
					       &logicvc_drm_regmap_config);
		if (IS_ERR(regmap)) {
			dev_err(dev, "Failed to create regmap for I/O\n");
			ret = PTR_ERR(regmap);
			goto error_reserved_mem;
		}
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = -ENODEV;
		goto error_reserved_mem;
	}

	logicvc = devm_drm_dev_alloc(dev, &logicvc_drm_driver,
				     struct logicvc_drm, drm_dev);
	if (IS_ERR(logicvc)) {
		ret = PTR_ERR(logicvc);
		goto error_reserved_mem;
	}

	platform_set_drvdata(pdev, logicvc);
	drm_dev = &logicvc->drm_dev;

	logicvc->regmap = regmap;
	INIT_LIST_HEAD(&logicvc->layers_list);

	caps = logicvc_drm_caps_match(logicvc);
	if (!caps) {
		ret = -EINVAL;
		goto error_reserved_mem;
	}

	logicvc->caps = caps;

	if (reserved_mem)
		logicvc->reserved_mem_base = reserved_mem->base;

	ret = logicvc_clocks_prepare(logicvc);
	if (ret) {
		drm_err(drm_dev, "Failed to prepare clocks\n");
		goto error_reserved_mem;
	}

	ret = devm_request_irq(dev, irq, logicvc_drm_irq_handler, 0,
			       dev_name(dev), logicvc);
	if (ret) {
		drm_err(drm_dev, "Failed to request IRQ\n");
		goto error_clocks;
	}

	ret = logicvc_drm_config_parse(logicvc);
	if (ret && ret != -ENODEV) {
		drm_err(drm_dev, "Failed to parse config\n");
		goto error_clocks;
	}

	ret = drmm_mode_config_init(drm_dev);
	if (ret) {
		drm_err(drm_dev, "Failed to init mode config\n");
		goto error_clocks;
	}

	ret = logicvc_layers_init(logicvc);
	if (ret) {
		drm_err(drm_dev, "Failed to initialize layers\n");
		goto error_clocks;
	}

	ret = logicvc_crtc_init(logicvc);
	if (ret) {
		drm_err(drm_dev, "Failed to initialize CRTC\n");
		goto error_clocks;
	}

	logicvc_layers_attach_crtc(logicvc);

	ret = logicvc_interface_init(logicvc);
	if (ret) {
		if (ret != -EPROBE_DEFER)
			drm_err(drm_dev, "Failed to initialize interface\n");

		goto error_clocks;
	}

	logicvc_interface_attach_crtc(logicvc);

	ret = logicvc_mode_init(logicvc);
	if (ret) {
		drm_err(drm_dev, "Failed to initialize KMS\n");
		goto error_clocks;
	}

	ret = drm_dev_register(drm_dev, 0);
	if (ret) {
		drm_err(drm_dev, "Failed to register DRM device\n");
		goto error_mode;
	}

	drm_fbdev_generic_setup(drm_dev, drm_dev->mode_config.preferred_depth);

	return 0;

error_mode:
	logicvc_mode_fini(logicvc);

error_clocks:
	logicvc_clocks_unprepare(logicvc);

error_reserved_mem:
	of_reserved_mem_device_release(dev);

error_early:
	return ret;
}

static int logicvc_drm_remove(struct platform_device *pdev)
{
	struct logicvc_drm *logicvc = platform_get_drvdata(pdev);
	struct device *dev = &pdev->dev;
	struct drm_device *drm_dev = &logicvc->drm_dev;

	drm_dev_unregister(drm_dev);
	drm_atomic_helper_shutdown(drm_dev);

	logicvc_mode_fini(logicvc);

	logicvc_clocks_unprepare(logicvc);

	of_reserved_mem_device_release(dev);

	return 0;
}

static const struct of_device_id logicvc_drm_of_table[] = {
	{ .compatible = "xylon,logicvc-3.02.a-display" },
	{ .compatible = "xylon,logicvc-4.01.a-display" },
	{},
};
MODULE_DEVICE_TABLE(of, logicvc_drm_of_table);

static struct platform_driver logicvc_drm_platform_driver = {
	.probe		= logicvc_drm_probe,
	.remove		= logicvc_drm_remove,
	.driver		= {
		.name		= "logicvc-drm",
		.of_match_table	= logicvc_drm_of_table,
	},
};

module_platform_driver(logicvc_drm_platform_driver);

MODULE_AUTHOR("Paul Kocialkowski <paul.kocialkowski@bootlin.com>");
MODULE_DESCRIPTION("Xylon LogiCVC DRM driver");
MODULE_LICENSE("GPL");
