/*
 * ARM Specific GTDT table Support
 *
 * Copyright (C) 2016, Linaro Ltd.
 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
 *         Fu Wei <fu.wei@linaro.org>
 *         Hanjun Guo <hanjun.guo@linaro.org>
 *
 * 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.
 */

#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>

#include <clocksource/arm_arch_timer.h>

#undef pr_fmt
#define pr_fmt(fmt) "ACPI GTDT: " fmt

/**
 * struct acpi_gtdt_descriptor - Store the key info of GTDT for all functions
 * @gtdt:	The pointer to the struct acpi_table_gtdt of GTDT table.
 * @gtdt_end:	The pointer to the end of GTDT table.
 * @platform_timer:	The pointer to the start of Platform Timer Structure
 *
 * The struct store the key info of GTDT table, it should be initialized by
 * acpi_gtdt_init.
 */
struct acpi_gtdt_descriptor {
	struct acpi_table_gtdt *gtdt;
	void *gtdt_end;
	void *platform_timer;
};

static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;

static inline void *next_platform_timer(void *platform_timer)
{
	struct acpi_gtdt_header *gh = platform_timer;

	platform_timer += gh->length;
	if (platform_timer < acpi_gtdt_desc.gtdt_end)
		return platform_timer;

	return NULL;
}

#define for_each_platform_timer(_g)				\
	for (_g = acpi_gtdt_desc.platform_timer; _g;	\
	     _g = next_platform_timer(_g))

static inline bool is_timer_block(void *platform_timer)
{
	struct acpi_gtdt_header *gh = platform_timer;

	return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
}

static inline bool is_non_secure_watchdog(void *platform_timer)
{
	struct acpi_gtdt_header *gh = platform_timer;
	struct acpi_gtdt_watchdog *wd = platform_timer;

	if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
		return false;

	return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
}

static int __init map_gt_gsi(u32 interrupt, u32 flags)
{
	int trigger, polarity;

	trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
			: ACPI_LEVEL_SENSITIVE;

	polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
			: ACPI_ACTIVE_HIGH;

	return acpi_register_gsi(NULL, interrupt, trigger, polarity);
}

/**
 * acpi_gtdt_map_ppi() - Map the PPIs of per-cpu arch_timer.
 * @type:	the type of PPI.
 *
 * Note: Secure state is not managed by the kernel on ARM64 systems.
 * So we only handle the non-secure timer PPIs,
 * ARCH_TIMER_PHYS_SECURE_PPI is treated as invalid type.
 *
 * Return: the mapped PPI value, 0 if error.
 */
int __init acpi_gtdt_map_ppi(int type)
{
	struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;

	switch (type) {
	case ARCH_TIMER_PHYS_NONSECURE_PPI:
		return map_gt_gsi(gtdt->non_secure_el1_interrupt,
				  gtdt->non_secure_el1_flags);
	case ARCH_TIMER_VIRT_PPI:
		return map_gt_gsi(gtdt->virtual_timer_interrupt,
				  gtdt->virtual_timer_flags);

	case ARCH_TIMER_HYP_PPI:
		return map_gt_gsi(gtdt->non_secure_el2_interrupt,
				  gtdt->non_secure_el2_flags);
	default:
		pr_err("Failed to map timer interrupt: invalid type.\n");
	}

	return 0;
}

/**
 * acpi_gtdt_c3stop() - Got c3stop info from GTDT according to the type of PPI.
 * @type:	the type of PPI.
 *
 * Return: true if the timer HW state is lost when a CPU enters an idle state,
 * false otherwise
 */
bool __init acpi_gtdt_c3stop(int type)
{
	struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;

	switch (type) {
	case ARCH_TIMER_PHYS_NONSECURE_PPI:
		return !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);

	case ARCH_TIMER_VIRT_PPI:
		return !(gtdt->virtual_timer_flags & ACPI_GTDT_ALWAYS_ON);

	case ARCH_TIMER_HYP_PPI:
		return !(gtdt->non_secure_el2_flags & ACPI_GTDT_ALWAYS_ON);

	default:
		pr_err("Failed to get c3stop info: invalid type.\n");
	}

	return false;
}

/**
 * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
 * @table:			The pointer to GTDT table.
 * @platform_timer_count:	It points to a integer variable which is used
 *				for storing the number of platform timers.
 *				This pointer could be NULL, if the caller
 *				doesn't need this info.
 *
 * Return: 0 if success, -EINVAL if error.
 */
int __init acpi_gtdt_init(struct acpi_table_header *table,
			  int *platform_timer_count)
{
	void *platform_timer;
	struct acpi_table_gtdt *gtdt;

	gtdt = container_of(table, struct acpi_table_gtdt, header);
	acpi_gtdt_desc.gtdt = gtdt;
	acpi_gtdt_desc.gtdt_end = (void *)table + table->length;
	acpi_gtdt_desc.platform_timer = NULL;
	if (platform_timer_count)
		*platform_timer_count = 0;

	if (table->revision < 2) {
		pr_warn("Revision:%d doesn't support Platform Timers.\n",
			table->revision);
		return 0;
	}

	if (!gtdt->platform_timer_count) {
		pr_debug("No Platform Timer.\n");
		return 0;
	}

	platform_timer = (void *)gtdt + gtdt->platform_timer_offset;
	if (platform_timer < (void *)table + sizeof(struct acpi_table_gtdt)) {
		pr_err(FW_BUG "invalid timer data.\n");
		return -EINVAL;
	}
	acpi_gtdt_desc.platform_timer = platform_timer;
	if (platform_timer_count)
		*platform_timer_count = gtdt->platform_timer_count;

	return 0;
}

static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block,
					 struct arch_timer_mem *timer_mem)
{
	int i;
	struct arch_timer_mem_frame *frame;
	struct acpi_gtdt_timer_entry *gtdt_frame;

	if (!block->timer_count) {
		pr_err(FW_BUG "GT block present, but frame count is zero.\n");
		return -ENODEV;
	}

	if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) {
		pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n",
		       block->timer_count);
		return -EINVAL;
	}

	timer_mem->cntctlbase = (phys_addr_t)block->block_address;
	/*
	 * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
	 * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
	 * "CNTCTLBase memory map".
	 */
	timer_mem->size = SZ_4K;

	gtdt_frame = (void *)block + block->timer_offset;
	if (gtdt_frame + block->timer_count != (void *)block + block->header.length)
		return -EINVAL;

	/*
	 * Get the GT timer Frame data for every GT Block Timer
	 */
	for (i = 0; i < block->timer_count; i++, gtdt_frame++) {
		if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
			continue;
		if (gtdt_frame->frame_number >= ARCH_TIMER_MEM_MAX_FRAMES ||
		    !gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
			goto error;

		frame = &timer_mem->frame[gtdt_frame->frame_number];

		/* duplicate frame */
		if (frame->valid)
			goto error;

		frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
					     gtdt_frame->timer_flags);
		if (frame->phys_irq <= 0) {
			pr_warn("failed to map physical timer irq in frame %d.\n",
				gtdt_frame->frame_number);
			goto error;
		}

		if (gtdt_frame->virtual_timer_interrupt) {
			frame->virt_irq =
				map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
					   gtdt_frame->virtual_timer_flags);
			if (frame->virt_irq <= 0) {
				pr_warn("failed to map virtual timer irq in frame %d.\n",
					gtdt_frame->frame_number);
				goto error;
			}
		} else {
			pr_debug("virtual timer in frame %d not implemented.\n",
				 gtdt_frame->frame_number);
		}

		frame->cntbase = gtdt_frame->base_address;
		/*
		 * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
		 * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
		 * "CNTBaseN memory map".
		 */
		frame->size = SZ_4K;
		frame->valid = true;
	}

	return 0;

error:
	do {
		if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER ||
		    gtdt_frame->frame_number >= ARCH_TIMER_MEM_MAX_FRAMES)
			continue;

		frame = &timer_mem->frame[gtdt_frame->frame_number];

		if (frame->phys_irq > 0)
			acpi_unregister_gsi(gtdt_frame->timer_interrupt);
		frame->phys_irq = 0;

		if (frame->virt_irq > 0)
			acpi_unregister_gsi(gtdt_frame->virtual_timer_interrupt);
		frame->virt_irq = 0;
	} while (i-- >= 0 && gtdt_frame--);

	return -EINVAL;
}

/**
 * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
 * @timer_mem:	The pointer to the array of struct arch_timer_mem for returning
 *		the result of parsing. The element number of this array should
 *		be platform_timer_count(the total number of platform timers).
 * @timer_count: It points to a integer variable which is used for storing the
 *		number of GT blocks we have parsed.
 *
 * Return: 0 if success, -EINVAL/-ENODEV if error.
 */
int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
				    int *timer_count)
{
	int ret;
	void *platform_timer;

	*timer_count = 0;
	for_each_platform_timer(platform_timer) {
		if (is_timer_block(platform_timer)) {
			ret = gtdt_parse_timer_block(platform_timer, timer_mem);
			if (ret)
				return ret;
			timer_mem++;
			(*timer_count)++;
		}
	}

	if (*timer_count)
		pr_info("found %d memory-mapped timer block(s).\n",
			*timer_count);

	return 0;
}

/*
 * Initialize a SBSA generic Watchdog platform device info from GTDT
 */
static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd,
					int index)
{
	struct platform_device *pdev;
	int irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags);

	/*
	 * According to SBSA specification the size of refresh and control
	 * frames of SBSA Generic Watchdog is SZ_4K(Offset 0x000 – 0xFFF).
	 */
	struct resource res[] = {
		DEFINE_RES_MEM(wd->control_frame_address, SZ_4K),
		DEFINE_RES_MEM(wd->refresh_frame_address, SZ_4K),
		DEFINE_RES_IRQ(irq),
	};
	int nr_res = ARRAY_SIZE(res);

	pr_debug("found a Watchdog (0x%llx/0x%llx gsi:%u flags:0x%x).\n",
		 wd->refresh_frame_address, wd->control_frame_address,
		 wd->timer_interrupt, wd->timer_flags);

	if (!(wd->refresh_frame_address && wd->control_frame_address)) {
		pr_err(FW_BUG "failed to get the Watchdog base address.\n");
		acpi_unregister_gsi(wd->timer_interrupt);
		return -EINVAL;
	}

	if (irq <= 0) {
		pr_warn("failed to map the Watchdog interrupt.\n");
		nr_res--;
	}

	/*
	 * Add a platform device named "sbsa-gwdt" to match the platform driver.
	 * "sbsa-gwdt": SBSA(Server Base System Architecture) Generic Watchdog
	 * The platform driver can get device info below by matching this name.
	 */
	pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
	if (IS_ERR(pdev)) {
		acpi_unregister_gsi(wd->timer_interrupt);
		return PTR_ERR(pdev);
	}

	return 0;
}

static int __init gtdt_sbsa_gwdt_init(void)
{
	void *platform_timer;
	struct acpi_table_header *table;
	int ret, timer_count, gwdt_count = 0;

	if (acpi_disabled)
		return 0;

	if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0, &table)))
		return -EINVAL;

	/*
	 * Note: Even though the global variable acpi_gtdt_desc has been
	 * initialized by acpi_gtdt_init() while initializing the arch timers,
	 * when we call this function to get SBSA watchdogs info from GTDT, the
	 * pointers stashed in it are stale (since they are early temporary
	 * mappings carried out before acpi_permanent_mmap is set) and we need
	 * to re-initialize them with permanent mapped pointer values to let the
	 * GTDT parsing possible.
	 */
	ret = acpi_gtdt_init(table, &timer_count);
	if (ret || !timer_count)
		return ret;

	for_each_platform_timer(platform_timer) {
		if (is_non_secure_watchdog(platform_timer)) {
			ret = gtdt_import_sbsa_gwdt(platform_timer, gwdt_count);
			if (ret)
				break;
			gwdt_count++;
		}
	}

	if (gwdt_count)
		pr_info("found %d SBSA generic Watchdog(s).\n", gwdt_count);

	return ret;
}

device_initcall(gtdt_sbsa_gwdt_init);
