// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2015 Samsung Electronics Co., Ltd.
//	      http://www.samsung.com/
//
// Exynos - SROM Controller support
// Author: Pankaj Dubey <pankaj.dubey@samsung.com>

#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "exynos-srom.h"

static const unsigned long exynos_srom_offsets[] = {
	/* SROM side */
	EXYNOS_SROM_BW,
	EXYNOS_SROM_BC0,
	EXYNOS_SROM_BC1,
	EXYNOS_SROM_BC2,
	EXYNOS_SROM_BC3,
};

/**
 * struct exynos_srom_reg_dump: register dump of SROM Controller registers.
 * @offset: srom register offset from the controller base address.
 * @value: the value of register under the offset.
 */
struct exynos_srom_reg_dump {
	u32     offset;
	u32     value;
};

/**
 * struct exynos_srom: platform data for exynos srom controller driver.
 * @dev: platform device pointer
 * @reg_base: srom base address
 * @reg_offset: exynos_srom_reg_dump pointer to hold offset and its value.
 */
struct exynos_srom {
	struct device *dev;
	void __iomem *reg_base;
	struct exynos_srom_reg_dump *reg_offset;
};

static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
		const unsigned long *rdump,
		unsigned long nr_rdump)
{
	struct exynos_srom_reg_dump *rd;
	unsigned int i;

	rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
	if (!rd)
		return NULL;

	for (i = 0; i < nr_rdump; ++i)
		rd[i].offset = rdump[i];

	return rd;
}

static int exynos_srom_configure_bank(struct exynos_srom *srom,
				      struct device_node *np)
{
	u32 bank, width, pmc = 0;
	u32 timing[6];
	u32 cs, bw;

	if (of_property_read_u32(np, "reg", &bank))
		return -EINVAL;
	if (of_property_read_u32(np, "reg-io-width", &width))
		width = 1;
	if (of_property_read_bool(np, "samsung,srom-page-mode"))
		pmc = 1 << EXYNOS_SROM_BCX__PMC__SHIFT;
	if (of_property_read_u32_array(np, "samsung,srom-timing", timing,
				       ARRAY_SIZE(timing)))
		return -EINVAL;

	bank *= 4; /* Convert bank into shift/offset */

	cs = 1 << EXYNOS_SROM_BW__BYTEENABLE__SHIFT;
	if (width == 2)
		cs |= 1 << EXYNOS_SROM_BW__DATAWIDTH__SHIFT;

	bw = readl_relaxed(srom->reg_base + EXYNOS_SROM_BW);
	bw = (bw & ~(EXYNOS_SROM_BW__CS_MASK << bank)) | (cs << bank);
	writel_relaxed(bw, srom->reg_base + EXYNOS_SROM_BW);

	writel_relaxed(pmc | (timing[0] << EXYNOS_SROM_BCX__TACP__SHIFT) |
		       (timing[1] << EXYNOS_SROM_BCX__TCAH__SHIFT) |
		       (timing[2] << EXYNOS_SROM_BCX__TCOH__SHIFT) |
		       (timing[3] << EXYNOS_SROM_BCX__TACC__SHIFT) |
		       (timing[4] << EXYNOS_SROM_BCX__TCOS__SHIFT) |
		       (timing[5] << EXYNOS_SROM_BCX__TACS__SHIFT),
		       srom->reg_base + EXYNOS_SROM_BC0 + bank);

	return 0;
}

static int exynos_srom_probe(struct platform_device *pdev)
{
	struct device_node *np, *child;
	struct exynos_srom *srom;
	struct device *dev = &pdev->dev;
	bool bad_bank_config = false;

	np = dev->of_node;
	if (!np) {
		dev_err(&pdev->dev, "could not find device info\n");
		return -EINVAL;
	}

	srom = devm_kzalloc(&pdev->dev,
			sizeof(struct exynos_srom), GFP_KERNEL);
	if (!srom)
		return -ENOMEM;

	srom->dev = dev;
	srom->reg_base = of_iomap(np, 0);
	if (!srom->reg_base) {
		dev_err(&pdev->dev, "iomap of exynos srom controller failed\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, srom);

	srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
			ARRAY_SIZE(exynos_srom_offsets));
	if (!srom->reg_offset) {
		iounmap(srom->reg_base);
		return -ENOMEM;
	}

	for_each_child_of_node(np, child) {
		if (exynos_srom_configure_bank(srom, child)) {
			dev_err(dev,
				"Could not decode bank configuration for %pOFn\n",
				child);
			bad_bank_config = true;
		}
	}

	/*
	 * If any bank failed to configure, we still provide suspend/resume,
	 * but do not probe child devices
	 */
	if (bad_bank_config)
		return 0;

	return of_platform_populate(np, NULL, NULL, dev);
}

#ifdef CONFIG_PM_SLEEP
static void exynos_srom_save(void __iomem *base,
				    struct exynos_srom_reg_dump *rd,
				    unsigned int num_regs)
{
	for (; num_regs > 0; --num_regs, ++rd)
		rd->value = readl(base + rd->offset);
}

static void exynos_srom_restore(void __iomem *base,
				      const struct exynos_srom_reg_dump *rd,
				      unsigned int num_regs)
{
	for (; num_regs > 0; --num_regs, ++rd)
		writel(rd->value, base + rd->offset);
}

static int exynos_srom_suspend(struct device *dev)
{
	struct exynos_srom *srom = dev_get_drvdata(dev);

	exynos_srom_save(srom->reg_base, srom->reg_offset,
				ARRAY_SIZE(exynos_srom_offsets));
	return 0;
}

static int exynos_srom_resume(struct device *dev)
{
	struct exynos_srom *srom = dev_get_drvdata(dev);

	exynos_srom_restore(srom->reg_base, srom->reg_offset,
				ARRAY_SIZE(exynos_srom_offsets));
	return 0;
}
#endif

static const struct of_device_id of_exynos_srom_ids[] = {
	{
		.compatible	= "samsung,exynos4210-srom",
	},
	{},
};

static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume);

static struct platform_driver exynos_srom_driver = {
	.probe = exynos_srom_probe,
	.driver = {
		.name = "exynos-srom",
		.of_match_table = of_exynos_srom_ids,
		.pm = &exynos_srom_pm_ops,
		.suppress_bind_attrs = true,
	},
};
builtin_platform_driver(exynos_srom_driver);
