// SPDX-License-Identifier: GPL-2.0-only
/*
 * OMAP IOMMU quirks for various TI SoCs
 *
 * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti.com/
 *      Suman Anna <s-anna@ti.com>
 */

#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/list.h>

#include "clockdomain.h"
#include "powerdomain.h"

struct pwrdm_link {
	struct device *dev;
	struct powerdomain *pwrdm;
	struct list_head node;
};

static DEFINE_SPINLOCK(iommu_lock);
static struct clockdomain *emu_clkdm;
static atomic_t emu_count;

static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
					     bool enable)
{
	struct device_node *np = pdev->dev.of_node;
	unsigned long flags;

	if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
		return;

	if (!emu_clkdm) {
		emu_clkdm = clkdm_lookup("emu_clkdm");
		if (WARN_ON_ONCE(!emu_clkdm))
			return;
	}

	spin_lock_irqsave(&iommu_lock, flags);

	if (enable && (atomic_inc_return(&emu_count) == 1))
		clkdm_deny_idle(emu_clkdm);
	else if (!enable && (atomic_dec_return(&emu_count) == 0))
		clkdm_allow_idle(emu_clkdm);

	spin_unlock_irqrestore(&iommu_lock, flags);
}

static struct powerdomain *_get_pwrdm(struct device *dev)
{
	struct clk *clk;
	struct clk_hw_omap *hwclk;
	struct clockdomain *clkdm;
	struct powerdomain *pwrdm = NULL;
	struct pwrdm_link *entry;
	unsigned long flags;
	static LIST_HEAD(cache);

	spin_lock_irqsave(&iommu_lock, flags);

	list_for_each_entry(entry, &cache, node) {
		if (entry->dev == dev) {
			pwrdm = entry->pwrdm;
			break;
		}
	}

	spin_unlock_irqrestore(&iommu_lock, flags);

	if (pwrdm)
		return pwrdm;

	clk = of_clk_get(dev->of_node->parent, 0);
	if (!clk) {
		dev_err(dev, "no fck found\n");
		return NULL;
	}

	hwclk = to_clk_hw_omap(__clk_get_hw(clk));
	clk_put(clk);
	if (!hwclk || !hwclk->clkdm_name) {
		dev_err(dev, "no hwclk data\n");
		return NULL;
	}

	clkdm = clkdm_lookup(hwclk->clkdm_name);
	if (!clkdm) {
		dev_err(dev, "clkdm not found: %s\n", hwclk->clkdm_name);
		return NULL;
	}

	pwrdm = clkdm_get_pwrdm(clkdm);
	if (!pwrdm) {
		dev_err(dev, "pwrdm not found: %s\n", clkdm->name);
		return NULL;
	}

	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (entry) {
		entry->dev = dev;
		entry->pwrdm = pwrdm;
		spin_lock_irqsave(&iommu_lock, flags);
		list_add(&entry->node, &cache);
		spin_unlock_irqrestore(&iommu_lock, flags);
	}

	return pwrdm;
}

int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
				    u8 *pwrst)
{
	struct powerdomain *pwrdm;
	u8 next_pwrst;
	int ret = 0;

	pwrdm = _get_pwrdm(&pdev->dev);
	if (!pwrdm)
		return -ENODEV;

	if (request) {
		*pwrst = pwrdm_read_next_pwrst(pwrdm);
		omap_iommu_dra7_emu_swsup_config(pdev, true);
	}

	if (*pwrst > PWRDM_POWER_RET)
		goto out;

	next_pwrst = request ? PWRDM_POWER_ON : *pwrst;

	ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst);

out:
	if (!request)
		omap_iommu_dra7_emu_swsup_config(pdev, false);

	return ret;
}
