// SPDX-License-Identifier: GPL-2.0
/*
 * PRU-ICSS platform driver for various TI SoCs
 *
 * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
 */

#include <dm.h>
#include <dm/of_access.h>
#include <errno.h>
#include <clk.h>
#include <reset.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
#include <power-domain.h>
#include <linux/pruss_driver.h>
#include <dm/device_compat.h>

#define PRUSS_CFG_IEPCLK	0x30
#define ICSSG_CFG_CORE_SYNC	0x3c

#define ICSSG_TASK_MGR_OFFSET	0x2a000

/* PRUSS_IEPCLK register bits */
#define PRUSS_IEPCLK_IEP_OCP_CLK_EN		BIT(0)

/* ICSSG CORE_SYNC register bits */
#define ICSSG_CORE_VBUSP_SYNC_EN		BIT(0)

/*
 * pruss_request_tm_region() - Request pruss for task manager region
 * @dev:	corresponding k3 device
 * @loc:	the task manager physical address
 *
 * Return: 0 if all goes good, else appropriate error message.
 */
int pruss_request_tm_region(struct udevice *dev, phys_addr_t *loc)
{
	struct pruss *priv;

	priv = dev_get_priv(dev);
	if (!priv || !priv->mem_regions[PRUSS_MEM_DRAM0].pa)
		return -EINVAL;

	*loc = priv->mem_regions[PRUSS_MEM_DRAM0].pa + ICSSG_TASK_MGR_OFFSET;

	return 0;
}

/**
 * pruss_request_mem_region() - request a memory resource
 * @dev: the pruss device
 * @mem_id: the memory resource id
 * @region: pointer to memory region structure to be filled in
 *
 * This function allows a client driver to request a memory resource,
 * and if successful, will let the client driver own the particular
 * memory region until released using the pruss_release_mem_region()
 * API.
 *
 * Returns the memory region if requested resource is available, an
 * error otherwise
 */
int pruss_request_mem_region(struct udevice *dev, enum pruss_mem mem_id,
			     struct pruss_mem_region *region)
{
	struct pruss *pruss;

	pruss = dev_get_priv(dev);
	if (!pruss || !region)
		return -EINVAL;

	if (mem_id >= PRUSS_MEM_MAX)
		return -EINVAL;

	if (pruss->mem_in_use[mem_id])
		return -EBUSY;

	*region = pruss->mem_regions[mem_id];
	pruss->mem_in_use[mem_id] = region;

	return 0;
}

/**
 * pruss_release_mem_region() - release a memory resource
 * @dev: the pruss device
 * @region: the memory region to release
 *
 * This function is the complimentary function to
 * pruss_request_mem_region(), and allows the client drivers to
 * release back a memory resource.
 *
 * Returns 0 on success, an error code otherwise
 */
int pruss_release_mem_region(struct udevice *dev,
			     struct pruss_mem_region *region)
{
	struct pruss *pruss;
	int id;

	pruss = dev_get_priv(dev);
	if (!pruss || !region)
		return -EINVAL;

	/* find out the memory region being released */
	for (id = 0; id < PRUSS_MEM_MAX; id++) {
		if (pruss->mem_in_use[id] == region)
			break;
	}

	if (id == PRUSS_MEM_MAX)
		return -EINVAL;

	pruss->mem_in_use[id] = NULL;

	return 0;
}

/**
 * pruss_cfg_update() - configure a PRUSS CFG sub-module register
 * @dev: the pruss device
 * @reg: register offset within the CFG sub-module
 * @mask: bit mask to use for programming the @val
 * @val: value to write
 *
 * Programs a given register within the PRUSS CFG sub-module
 *
 * Returns 0 on success, or an error code otherwise
 */
int pruss_cfg_update(struct udevice *dev, unsigned int reg,
		     unsigned int mask, unsigned int val)
{
	struct pruss *pruss;

	pruss = dev_get_priv(dev);
	if (IS_ERR_OR_NULL(pruss))
		return -EINVAL;

	return regmap_update_bits(pruss->cfg, reg, mask, val);
}

/**
 * pruss_probe() - Basic probe
 * @dev:	corresponding k3 device
 *
 * Return: 0 if all goes good, else appropriate error message.
 */
static int pruss_probe(struct udevice *dev)
{
	const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" };
	ofnode sub_node, node, memories;
	struct udevice *syscon;
	struct pruss *priv;
	int ret, idx, i;

	priv = dev_get_priv(dev);
	node = dev_ofnode(dev);
	priv->dev = dev;
	memories = ofnode_find_subnode(node, "memories");

	for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
		idx = ofnode_stringlist_search(memories, "reg-names", mem_names[i]);
		priv->mem_regions[i].pa = ofnode_get_addr_size_index(memories, idx,
						       (u64 *)&priv->mem_regions[i].size);
	}

	sub_node = ofnode_find_subnode(node, "cfg");
	ret = uclass_get_device_by_ofnode(UCLASS_SYSCON, sub_node,
					  &syscon);

	priv->cfg = syscon_get_regmap(syscon);
	if (IS_ERR(priv->cfg)) {
		dev_err(dev, "unable to get cfg regmap (%ld)\n",
			PTR_ERR(priv->cfg));
		return -ENODEV;
	}

	/*
	 * ToDo: To be modelled as clocks.
	 * The CORE block uses two multiplexers to allow software to
	 * select one of three source clocks (ICSSGn_CORE_CLK, ICSSGn_ICLK or
	 * ICSSGn_IEP_CLK) for the final clock source of the CORE block.
	 * The user needs to configure ICSSG_CORE_SYNC_REG[0] CORE_VBUSP_SYNC_EN
	 * bit & ICSSG_IEPCLK_REG[0] IEP_OCP_CLK_EN bit in order to select the
	 * clock source to the CORE block.
	 */
	ret = regmap_update_bits(priv->cfg, ICSSG_CFG_CORE_SYNC,
				 ICSSG_CORE_VBUSP_SYNC_EN,
				 ICSSG_CORE_VBUSP_SYNC_EN);
	if (ret)
		return ret;
	ret = regmap_update_bits(priv->cfg, PRUSS_CFG_IEPCLK,
				 PRUSS_IEPCLK_IEP_OCP_CLK_EN,
				 PRUSS_IEPCLK_IEP_OCP_CLK_EN);
	if (ret)
		return ret;

	dev_dbg(dev, "pruss successfully probed %s\n", dev->name);

	return 0;
}

static const struct udevice_id pruss_ids[] = {
	{ .compatible = "ti,am654-icssg"},
	{ .compatible = "ti,am642-icssg"},
	{}
};

U_BOOT_DRIVER(pruss) = {
	.name = "pruss",
	.of_match = pruss_ids,
	.id = UCLASS_MISC,
	.probe = pruss_probe,
	.priv_auto = sizeof(struct pruss),
};
