/*
 * Copyright 2018 NXP
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <video/imx8-pc.h>

#define REG0				0x0
#define PIX_COMBINE_ENABLE		BIT(0)
#define DISP_PIX_COMBINE_BYPASS(n)	BIT(1 + 21 * (n))
#define DISP_HSYNC_POLARITY(n)		BIT(2 + 11 * (n))
#define DISP_HSYNC_POLARITY_POS(n)	DISP_HSYNC_POLARITY(n)
#define DISP_VSYNC_POLARITY(n)		BIT(3 + 11 * (n))
#define DISP_VSYNC_POLARITY_POS(n)	DISP_VSYNC_POLARITY(n)
#define DISP_DVALID_POLARITY(n)		BIT(4 + 11 * (n))
#define DISP_DVALID_POLARITY_POS(n)	DISP_DVALID_POLARITY(n)
#define VSYNC_MASK_ENABLE		BIT(5)
#define SKIP_MODE			BIT(6)
#define SKIP_NUMBER(n)			(((n) & 0x3F) << 7)
#define DISP_PIX_DATA_FORMAT_MASK(n)    (0x7 << (16 + (n) * 3))
#define DISP_PIX_DATA_FORMAT_SHIFT(n)   (16 + (n) * 3)
enum {
	RGB = 0,
	YUV444,
	YUV422,
	SPLIT_RGB,
};

#define REG1				0x10
#define BUF_ACTIVE_DEPTH(n)		((n) & 0x7FF)

#define REG2				0x20
#define PC_SW_RESET_N			BIT(0)
#define DISP_SW_RESET_N(n)		BIT(1 + (n))
#define PC_FULL_RESET_N			(PC_SW_RESET_N |	\
					 DISP_SW_RESET_N(0) |	\
					 DISP_SW_RESET_N(1))

struct pc {
	struct device *dev;
	void __iomem *base;
	struct list_head list;
};

static DEFINE_MUTEX(pc_list_mutex);
static LIST_HEAD(pc_list);

static inline u32 pc_read(struct pc *pc, unsigned int offset)
{
	return readl(pc->base + offset);
}

static inline void pc_write(struct pc *pc, u32 value, unsigned int offset)
{
	writel(value, pc->base + offset);
}

static void pc_reset(struct pc *pc)
{
	pc_write(pc, 0, REG2);
	usleep_range(1000, 2000);
	pc_write(pc, PC_FULL_RESET_N, REG2);
}

void pc_enable(struct pc *pc)
{
	u32 val;

	if (WARN_ON(!pc))
		return;

	val = pc_read(pc, REG0);
	val |= PIX_COMBINE_ENABLE;
	pc_write(pc, val, REG0);

	dev_dbg(pc->dev, "enable\n");
}
EXPORT_SYMBOL_GPL(pc_enable);

void pc_disable(struct pc *pc)
{
	if (WARN_ON(!pc))
		return;

	pc_reset(pc);

	dev_dbg(pc->dev, "disable\n");
}
EXPORT_SYMBOL_GPL(pc_disable);

void pc_configure(struct pc *pc, unsigned int di, unsigned int frame_width,
		u32 mode, u32 format)
{
	u32 val;

	if (WARN_ON(!pc))
		return;

	if (WARN_ON(di != 0 && di != 1))
		return;

	dev_dbg(pc->dev, "configure mode-0x%08x frame_width-%u\n",
							mode, frame_width);

	val = pc_read(pc, REG0);
	if (mode == PC_BYPASS) {
		val |= DISP_PIX_COMBINE_BYPASS(di);
	} else if (mode == PC_COMBINE) {
		val &= ~DISP_PIX_COMBINE_BYPASS(di);
		frame_width /= 4;
	}

	pc_write(pc, val, REG0);
	pc_write(pc, BUF_ACTIVE_DEPTH(frame_width), REG1);
}
EXPORT_SYMBOL_GPL(pc_configure);

struct pc *pc_lookup_by_phandle(struct device *dev, const char *name)
{
	struct device_node *pc_node = of_parse_phandle(dev->of_node,
							name, 0);
	struct pc *pc;

	mutex_lock(&pc_list_mutex);
	list_for_each_entry(pc, &pc_list, list) {
		if (pc_node == pc->dev->of_node) {
			mutex_unlock(&pc_list_mutex);
			device_link_add(dev, pc->dev, DL_FLAG_AUTOREMOVE);
			return pc;
		}
	}
	mutex_unlock(&pc_list_mutex);

	return NULL;
}
EXPORT_SYMBOL_GPL(pc_lookup_by_phandle);

static int pc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct pc *pc;
	u32 val;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	pc->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(pc->base))
		return PTR_ERR(pc->base);

	pc->dev = dev;
	platform_set_drvdata(pdev, pc);
	mutex_lock(&pc_list_mutex);
	list_add(&pc->list, &pc_list);
	mutex_unlock(&pc_list_mutex);

	pc_reset(pc);

	/*
	 * assume data enable is active high and HSYNC/VSYNC are active low
	 * also, bypass combine at startup
	 */
	val = DISP_DVALID_POLARITY_POS(0) | DISP_DVALID_POLARITY_POS(1) |
	      DISP_PIX_COMBINE_BYPASS(0)  | DISP_PIX_COMBINE_BYPASS(1)  |
	      VSYNC_MASK_ENABLE;

	pc_write(pc, val, REG0);

	return 0;
}

static int pc_remove(struct platform_device *pdev)
{
	struct pc *pc = platform_get_drvdata(pdev);

	mutex_lock(&pc_list_mutex);
	list_del(&pc->list);
	mutex_unlock(&pc_list_mutex);

	return 0;
}

static const struct of_device_id pc_dt_ids[] = {
	{ .compatible = "fsl,imx8qm-pixel-combiner", },
	{ .compatible = "fsl,imx8qxp-pixel-combiner", },
	{ /* sentinel */ },
};

struct platform_driver pc_drv = {
	.probe = pc_probe,
	.remove = pc_remove,
	.driver = {
		.name = "imx8-pixel-combiner",
		.of_match_table = pc_dt_ids,
	},
};
module_platform_driver(pc_drv);

MODULE_DESCRIPTION("i.MX8 Pixel Combiner driver");
MODULE_AUTHOR("NXP Semiconductor");
MODULE_LICENSE("GPL");
