/*
 * OMAP2+ common Power & Reset Management (PRM) IP block functions
 *
 * Copyright (C) 2011 Texas Instruments, Inc.
 * Tero Kristo <t-kristo@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *
 * For historical purposes, the API used to configure the PRM
 * interrupt handler refers to it as the "PRCM interrupt."  The
 * underlying registers are located in the PRM on OMAP3/4.
 *
 * XXX This code should eventually be moved to a PRM driver.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/clk-provider.h>
#include <linux/clk/ti.h>

#include "soc.h"
#include "prm2xxx_3xxx.h"
#include "prm2xxx.h"
#include "prm3xxx.h"
#include "prm44xx.h"
#include "common.h"
#include "clock.h"
#include "cm.h"
#include "control.h"

/*
 * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
 * XXX this is technically not needed, since
 * omap_prcm_register_chain_handler() could allocate this based on the
 * actual amount of memory needed for the SoC
 */
#define OMAP_PRCM_MAX_NR_PENDING_REG		2

/*
 * prcm_irq_chips: an array of all of the "generic IRQ chips" in use
 * by the PRCM interrupt handler code.  There will be one 'chip' per
 * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair.  (So OMAP3 will have
 * one "chip" and OMAP4 will have two.)
 */
static struct irq_chip_generic **prcm_irq_chips;

/*
 * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code
 * is currently running on.  Defined and passed by initialization code
 * that calls omap_prcm_register_chain_handler().
 */
static struct omap_prcm_irq_setup *prcm_irq_setup;

/* prm_base: base virtual address of the PRM IP block */
void __iomem *prm_base;

u16 prm_features;

/*
 * prm_ll_data: function pointers to SoC-specific implementations of
 * common PRM functions
 */
static struct prm_ll_data null_prm_ll_data;
static struct prm_ll_data *prm_ll_data = &null_prm_ll_data;

/* Private functions */

/*
 * Move priority events from events to priority_events array
 */
static void omap_prcm_events_filter_priority(unsigned long *events,
	unsigned long *priority_events)
{
	int i;

	for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
		priority_events[i] =
			events[i] & prcm_irq_setup->priority_mask[i];
		events[i] ^= priority_events[i];
	}
}

/*
 * PRCM Interrupt Handler
 *
 * This is a common handler for the OMAP PRCM interrupts. Pending
 * interrupts are detected by a call to prcm_pending_events and
 * dispatched accordingly. Clearing of the wakeup events should be
 * done by the SoC specific individual handlers.
 */
static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
	unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
	struct irq_chip *chip = irq_desc_get_chip(desc);
	unsigned int virtirq;
	int nr_irq = prcm_irq_setup->nr_regs * 32;

	/*
	 * If we are suspended, mask all interrupts from PRCM level,
	 * this does not ack them, and they will be pending until we
	 * re-enable the interrupts, at which point the
	 * omap_prcm_irq_handler will be executed again.  The
	 * _save_and_clear_irqen() function must ensure that the PRM
	 * write to disable all IRQs has reached the PRM before
	 * returning, or spurious PRCM interrupts may occur during
	 * suspend.
	 */
	if (prcm_irq_setup->suspended) {
		prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask);
		prcm_irq_setup->suspend_save_flag = true;
	}

	/*
	 * Loop until all pending irqs are handled, since
	 * generic_handle_irq() can cause new irqs to come
	 */
	while (!prcm_irq_setup->suspended) {
		prcm_irq_setup->read_pending_irqs(pending);

		/* No bit set, then all IRQs are handled */
		if (find_first_bit(pending, nr_irq) >= nr_irq)
			break;

		omap_prcm_events_filter_priority(pending, priority_pending);

		/*
		 * Loop on all currently pending irqs so that new irqs
		 * cannot starve previously pending irqs
		 */

		/* Serve priority events first */
		for_each_set_bit(virtirq, priority_pending, nr_irq)
			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);

		/* Serve normal events next */
		for_each_set_bit(virtirq, pending, nr_irq)
			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
	}
	if (chip->irq_ack)
		chip->irq_ack(&desc->irq_data);
	if (chip->irq_eoi)
		chip->irq_eoi(&desc->irq_data);
	chip->irq_unmask(&desc->irq_data);

	prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */
}

/* Public functions */

/**
 * omap_prcm_event_to_irq - given a PRCM event name, returns the
 * corresponding IRQ on which the handler should be registered
 * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq
 *
 * Returns the Linux internal IRQ ID corresponding to @name upon success,
 * or -ENOENT upon failure.
 */
int omap_prcm_event_to_irq(const char *name)
{
	int i;

	if (!prcm_irq_setup || !name)
		return -ENOENT;

	for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
		if (!strcmp(prcm_irq_setup->irqs[i].name, name))
			return prcm_irq_setup->base_irq +
				prcm_irq_setup->irqs[i].offset;

	return -ENOENT;
}

/**
 * omap_prcm_irq_cleanup - reverses memory allocated and other steps
 * done by omap_prcm_register_chain_handler()
 *
 * No return value.
 */
void omap_prcm_irq_cleanup(void)
{
	unsigned int irq;
	int i;

	if (!prcm_irq_setup) {
		pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n");
		return;
	}

	if (prcm_irq_chips) {
		for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
			if (prcm_irq_chips[i])
				irq_remove_generic_chip(prcm_irq_chips[i],
					0xffffffff, 0, 0);
			prcm_irq_chips[i] = NULL;
		}
		kfree(prcm_irq_chips);
		prcm_irq_chips = NULL;
	}

	kfree(prcm_irq_setup->saved_mask);
	prcm_irq_setup->saved_mask = NULL;

	kfree(prcm_irq_setup->priority_mask);
	prcm_irq_setup->priority_mask = NULL;

	if (prcm_irq_setup->xlate_irq)
		irq = prcm_irq_setup->xlate_irq(prcm_irq_setup->irq);
	else
		irq = prcm_irq_setup->irq;
	irq_set_chained_handler(irq, NULL);

	if (prcm_irq_setup->base_irq > 0)
		irq_free_descs(prcm_irq_setup->base_irq,
			prcm_irq_setup->nr_regs * 32);
	prcm_irq_setup->base_irq = 0;
}

void omap_prcm_irq_prepare(void)
{
	prcm_irq_setup->suspended = true;
}

void omap_prcm_irq_complete(void)
{
	prcm_irq_setup->suspended = false;

	/* If we have not saved the masks, do not attempt to restore */
	if (!prcm_irq_setup->suspend_save_flag)
		return;

	prcm_irq_setup->suspend_save_flag = false;

	/*
	 * Re-enable all masked PRCM irq sources, this causes the PRCM
	 * interrupt to fire immediately if the events were masked
	 * previously in the chain handler
	 */
	prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask);
}

/**
 * omap_prcm_register_chain_handler - initializes the prcm chained interrupt
 * handler based on provided parameters
 * @irq_setup: hardware data about the underlying PRM/PRCM
 *
 * Set up the PRCM chained interrupt handler on the PRCM IRQ.  Sets up
 * one generic IRQ chip per PRM interrupt status/enable register pair.
 * Returns 0 upon success, -EINVAL if called twice or if invalid
 * arguments are passed, or -ENOMEM on any other error.
 */
int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
{
	int nr_regs;
	u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
	int offset, i;
	struct irq_chip_generic *gc;
	struct irq_chip_type *ct;
	unsigned int irq;

	if (!irq_setup)
		return -EINVAL;

	nr_regs = irq_setup->nr_regs;

	if (prcm_irq_setup) {
		pr_err("PRCM: already initialized; won't reinitialize\n");
		return -EINVAL;
	}

	if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
		pr_err("PRCM: nr_regs too large\n");
		return -EINVAL;
	}

	prcm_irq_setup = irq_setup;

	prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
	prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
	prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
		GFP_KERNEL);

	if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
	    !prcm_irq_setup->priority_mask) {
		pr_err("PRCM: kzalloc failed\n");
		goto err;
	}

	memset(mask, 0, sizeof(mask));

	for (i = 0; i < irq_setup->nr_irqs; i++) {
		offset = irq_setup->irqs[i].offset;
		mask[offset >> 5] |= 1 << (offset & 0x1f);
		if (irq_setup->irqs[i].priority)
			irq_setup->priority_mask[offset >> 5] |=
				1 << (offset & 0x1f);
	}

	if (irq_setup->xlate_irq)
		irq = irq_setup->xlate_irq(irq_setup->irq);
	else
		irq = irq_setup->irq;
	irq_set_chained_handler(irq, omap_prcm_irq_handler);

	irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
		0);

	if (irq_setup->base_irq < 0) {
		pr_err("PRCM: failed to allocate irq descs: %d\n",
			irq_setup->base_irq);
		goto err;
	}

	for (i = 0; i < irq_setup->nr_regs; i++) {
		gc = irq_alloc_generic_chip("PRCM", 1,
			irq_setup->base_irq + i * 32, prm_base,
			handle_level_irq);

		if (!gc) {
			pr_err("PRCM: failed to allocate generic chip\n");
			goto err;
		}
		ct = gc->chip_types;
		ct->chip.irq_ack = irq_gc_ack_set_bit;
		ct->chip.irq_mask = irq_gc_mask_clr_bit;
		ct->chip.irq_unmask = irq_gc_mask_set_bit;

		ct->regs.ack = irq_setup->ack + i * 4;
		ct->regs.mask = irq_setup->mask + i * 4;

		irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
		prcm_irq_chips[i] = gc;
	}

	if (of_have_populated_dt()) {
		int irq = omap_prcm_event_to_irq("io");
		omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain);
	}

	return 0;

err:
	omap_prcm_irq_cleanup();
	return -ENOMEM;
}

/**
 * omap2_set_globals_prm - set the PRM base address (for early use)
 * @prm: PRM base virtual address
 *
 * XXX Will be replaced when the PRM/CM drivers are completed.
 */
void __init omap2_set_globals_prm(void __iomem *prm)
{
	prm_base = prm;
}

/**
 * prm_read_reset_sources - return the sources of the SoC's last reset
 *
 * Return a u32 bitmask representing the reset sources that caused the
 * SoC to reset.  The low-level per-SoC functions called by this
 * function remap the SoC-specific reset source bits into an
 * OMAP-common set of reset source bits, defined in
 * arch/arm/mach-omap2/prm.h.  Returns the standardized reset source
 * u32 bitmask from the hardware upon success, or returns (1 <<
 * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources()
 * function was registered.
 */
u32 prm_read_reset_sources(void)
{
	u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT;

	if (prm_ll_data->read_reset_sources)
		ret = prm_ll_data->read_reset_sources();
	else
		WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__);

	return ret;
}

/**
 * prm_was_any_context_lost_old - was device context lost? (old API)
 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
 * @idx: CONTEXT register offset
 *
 * Return 1 if any bits were set in the *_CONTEXT_* register
 * identified by (@part, @inst, @idx), which means that some context
 * was lost for that module; otherwise, return 0.  XXX Deprecated;
 * callers need to use a less-SoC-dependent way to identify hardware
 * IP blocks.
 */
bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
{
	bool ret = true;

	if (prm_ll_data->was_any_context_lost_old)
		ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
	else
		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
			  __func__);

	return ret;
}

/**
 * prm_clear_context_lost_flags_old - clear context loss flags (old API)
 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
 * @idx: CONTEXT register offset
 *
 * Clear hardware context loss bits for the module identified by
 * (@part, @inst, @idx).  No return value.  XXX Deprecated; callers
 * need to use a less-SoC-dependent way to identify hardware IP
 * blocks.
 */
void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
{
	if (prm_ll_data->clear_context_loss_flags_old)
		prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
	else
		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
			  __func__);
}

/**
 * omap_prm_assert_hardreset - assert hardreset for an IP block
 * @shift: register bit shift corresponding to the reset line
 * @part: PRM partition
 * @prm_mod: PRM submodule base or instance offset
 * @offset: register offset
 *
 * Asserts a hardware reset line for an IP block.
 */
int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset)
{
	if (!prm_ll_data->assert_hardreset) {
		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
			  __func__);
		return -EINVAL;
	}

	return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset);
}

/**
 * omap_prm_deassert_hardreset - deassert hardreset for an IP block
 * @shift: register bit shift corresponding to the reset line
 * @st_shift: reset status bit shift corresponding to the reset line
 * @part: PRM partition
 * @prm_mod: PRM submodule base or instance offset
 * @offset: register offset
 * @st_offset: status register offset
 *
 * Deasserts a hardware reset line for an IP block.
 */
int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
				u16 offset, u16 st_offset)
{
	if (!prm_ll_data->deassert_hardreset) {
		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
			  __func__);
		return -EINVAL;
	}

	return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod,
					       offset, st_offset);
}

/**
 * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block
 * @shift: register bit shift corresponding to the reset line
 * @part: PRM partition
 * @prm_mod: PRM submodule base or instance offset
 * @offset: register offset
 *
 * Checks if a hardware reset line for an IP block is enabled or not.
 */
int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset)
{
	if (!prm_ll_data->is_hardreset_asserted) {
		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
			  __func__);
		return -EINVAL;
	}

	return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset);
}

/**
 * omap_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
 *
 * Clear any previously-latched I/O wakeup events and ensure that the
 * I/O wakeup gates are aligned with the current mux settings.
 * Calls SoC specific I/O chain reconfigure function if available,
 * otherwise does nothing.
 */
void omap_prm_reconfigure_io_chain(void)
{
	if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain)
		return;

	prcm_irq_setup->reconfigure_io_chain();
}

/**
 * omap_prm_reset_system - trigger global SW reset
 *
 * Triggers SoC specific global warm reset to reboot the device.
 */
void omap_prm_reset_system(void)
{
	if (!prm_ll_data->reset_system) {
		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
			  __func__);
		return;
	}

	prm_ll_data->reset_system();

	while (1)
		cpu_relax();
}

/**
 * prm_register - register per-SoC low-level data with the PRM
 * @pld: low-level per-SoC OMAP PRM data & function pointers to register
 *
 * Register per-SoC low-level OMAP PRM data and function pointers with
 * the OMAP PRM common interface.  The caller must keep the data
 * pointed to by @pld valid until it calls prm_unregister() and
 * it returns successfully.  Returns 0 upon success, -EINVAL if @pld
 * is NULL, or -EEXIST if prm_register() has already been called
 * without an intervening prm_unregister().
 */
int prm_register(struct prm_ll_data *pld)
{
	if (!pld)
		return -EINVAL;

	if (prm_ll_data != &null_prm_ll_data)
		return -EEXIST;

	prm_ll_data = pld;

	return 0;
}

/**
 * prm_unregister - unregister per-SoC low-level data & function pointers
 * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
 *
 * Unregister per-SoC low-level OMAP PRM data and function pointers
 * that were previously registered with prm_register().  The
 * caller may not destroy any of the data pointed to by @pld until
 * this function returns successfully.  Returns 0 upon success, or
 * -EINVAL if @pld is NULL or if @pld does not match the struct
 * prm_ll_data * previously registered by prm_register().
 */
int prm_unregister(struct prm_ll_data *pld)
{
	if (!pld || prm_ll_data != pld)
		return -EINVAL;

	prm_ll_data = &null_prm_ll_data;

	return 0;
}

static const struct of_device_id omap_prcm_dt_match_table[] = {
	{ .compatible = "ti,am3-prcm" },
	{ .compatible = "ti,am3-scrm" },
	{ .compatible = "ti,am4-prcm" },
	{ .compatible = "ti,am4-scrm" },
	{ .compatible = "ti,dm814-prcm" },
	{ .compatible = "ti,dm814-scrm" },
	{ .compatible = "ti,dm816-prcm" },
	{ .compatible = "ti,dm816-scrm" },
	{ .compatible = "ti,omap2-prcm" },
	{ .compatible = "ti,omap2-scrm" },
	{ .compatible = "ti,omap3-prm" },
	{ .compatible = "ti,omap3-cm" },
	{ .compatible = "ti,omap3-scrm" },
	{ .compatible = "ti,omap4-cm1" },
	{ .compatible = "ti,omap4-prm" },
	{ .compatible = "ti,omap4-cm2" },
	{ .compatible = "ti,omap4-scrm" },
	{ .compatible = "ti,omap5-prm" },
	{ .compatible = "ti,omap5-cm-core-aon" },
	{ .compatible = "ti,omap5-scrm" },
	{ .compatible = "ti,omap5-cm-core" },
	{ .compatible = "ti,dra7-prm" },
	{ .compatible = "ti,dra7-cm-core-aon" },
	{ .compatible = "ti,dra7-cm-core" },
	{ }
};

static struct clk_hw_omap memmap_dummy_ck = {
	.flags = MEMMAP_ADDRESSING,
};

static u32 prm_clk_readl(void __iomem *reg)
{
	return omap2_clk_readl(&memmap_dummy_ck, reg);
}

static void prm_clk_writel(u32 val, void __iomem *reg)
{
	omap2_clk_writel(val, &memmap_dummy_ck, reg);
}

static struct ti_clk_ll_ops omap_clk_ll_ops = {
	.clk_readl = prm_clk_readl,
	.clk_writel = prm_clk_writel,
};

int __init of_prcm_init(void)
{
	struct device_node *np;
	void __iomem *mem;
	int memmap_index = 0;

	ti_clk_ll_ops = &omap_clk_ll_ops;

	for_each_matching_node(np, omap_prcm_dt_match_table) {
		mem = of_iomap(np, 0);
		clk_memmaps[memmap_index] = mem;
		ti_dt_clk_init_provider(np, memmap_index);
		memmap_index++;
	}

	return 0;
}

void __init omap3_prcm_legacy_iomaps_init(void)
{
	ti_clk_ll_ops = &omap_clk_ll_ops;

	clk_memmaps[TI_CLKM_CM] = cm_base + OMAP3430_IVA2_MOD;
	clk_memmaps[TI_CLKM_PRM] = prm_base + OMAP3430_IVA2_MOD;
	clk_memmaps[TI_CLKM_SCRM] = omap_ctrl_base_get();
}

static int __init prm_late_init(void)
{
	if (prm_ll_data->late_init)
		return prm_ll_data->late_init();
	return 0;
}
subsys_initcall(prm_late_init);
