/*
 * Copyright (C) 2020, Red Hat Inc, Eric Auger <eric.auger@redhat.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.
 */
#include <asm/gic.h>
#include <alloc_page.h>

void its_parse_typer(void)
{
	u64 typer = readq(gicv3_its_base() + GITS_TYPER);
	struct its_typer *t = &its_data.typer;

	t->ite_size = ((typer & GITS_TYPER_ITT_ENTRY_SIZE) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) + 1;
	t->pta = typer & GITS_TYPER_PTA;
	t->eventid_bits = ((typer & GITS_TYPER_IDBITS) >> GITS_TYPER_IDBITS_SHIFT) + 1;
	t->deviceid_bits = ((typer & GITS_TYPER_DEVBITS) >> GITS_TYPER_DEVBITS_SHIFT) + 1;

	if (typer & GITS_TYPER_CIL)
		t->collid_bits = ((typer & GITS_TYPER_CIDBITS) >> GITS_TYPER_CIDBITS_SHIFT) + 1;
	else
		t->collid_bits = 16;

	t->virt_lpi = typer & GITS_TYPER_VLPIS;
	t->phys_lpi = typer & GITS_TYPER_PLPIS;
}

int its_baser_lookup(int type, struct its_baser *baser)
{
	int i;

	for (i = 0; i < GITS_BASER_NR_REGS; i++) {
		void *reg_addr = gicv3_its_base() + GITS_BASER + i * 8;
		u64 val = readq(reg_addr);

		if (GITS_BASER_TYPE(val) == type) {
			assert((val & GITS_BASER_PAGE_SIZE_MASK) == GITS_BASER_PAGE_SIZE_64K);
			baser->esz = GITS_BASER_ENTRY_SIZE(val);
			baser->indirect = val & GITS_BASER_INDIRECT;
			baser->index = i;
			return 0;
		}
	}
	return -1;
}

/*
 * Allocate the BASER table (a single page of size @baser->psz)
 * and set the BASER valid
 */
static void its_baser_alloc_table(struct its_baser *baser, size_t size)
{
	unsigned long order = get_order(size >> PAGE_SHIFT);
	void *reg_addr = gicv3_its_base() + GITS_BASER + baser->index * 8;
	u64 val = readq(reg_addr);

	baser->table_addr = alloc_pages(order);

	val |= virt_to_phys(baser->table_addr) | GITS_BASER_VALID;

	writeq(val, reg_addr);
}

/*
 * init_cmd_queue - Allocate the command queue and initialize
 * CBASER, CWRITER
 */
static void its_cmd_queue_init(void)
{
	unsigned long order = get_order(SZ_64K >> PAGE_SHIFT);
	u64 cbaser;

	its_data.cmd_base = alloc_pages(order);

	cbaser = virt_to_phys(its_data.cmd_base) | (SZ_64K / SZ_4K - 1) | GITS_CBASER_VALID;

	writeq(cbaser, its_data.base + GITS_CBASER);

	its_data.cmd_write = its_data.cmd_base;
	writeq(0, its_data.base + GITS_CWRITER);
}

void its_init(void)
{
	if (!its_data.base)
		return;

	its_parse_typer();

	assert(!its_baser_lookup(GITS_BASER_TYPE_DEVICE, &its_data.device_baser));
	assert(!its_baser_lookup(GITS_BASER_TYPE_COLLECTION, &its_data.coll_baser));

	its_baser_alloc_table(&its_data.device_baser, SZ_64K);
	its_baser_alloc_table(&its_data.coll_baser, SZ_64K);

	its_cmd_queue_init();
}

/* must be called after gicv3_enable_defaults */
void its_enable_defaults(void)
{
	int cpu;

	/* Allocate LPI config and pending tables */
	gicv3_lpi_alloc_tables();

	for_each_online_cpu(cpu)
		gicv3_lpi_rdist_enable(cpu);

	writel(GITS_CTLR_ENABLE, its_data.base + GITS_CTLR);
}

struct its_device *its_create_device(u32 device_id, int nr_ites)
{
	struct its_device *new;
	unsigned long n;

	assert(its_data.nr_devices < GITS_MAX_DEVICES);

	new = &its_data.devices[its_data.nr_devices];

	new->device_id = device_id;
	new->nr_ites = nr_ites;

	n = (its_data.typer.ite_size * nr_ites) >> PAGE_SHIFT;
	new->itt = alloc_pages(get_order(n));

	its_data.nr_devices++;
	return new;
}

struct its_collection *its_create_collection(u16 col_id, u32 pe)
{
	struct its_collection *new;

	assert(its_data.nr_collections < GITS_MAX_COLLECTIONS);

	new = &its_data.collections[its_data.nr_collections];

	new->col_id = col_id;

	if (its_data.typer.pta)
		new->target_address = (u64)gicv3_data.redist_base[pe];
	else
		new->target_address = pe << 16;

	its_data.nr_collections++;
	return new;
}

struct its_device *its_get_device(u32 id)
{
	int i;

	for (i = 0; i < GITS_MAX_DEVICES; i++) {
		if (its_data.devices[i].device_id == id)
			return &its_data.devices[i];
	}
	assert(0);
}

struct its_collection *its_get_collection(u32 id)
{
	int i;

	for (i = 0; i < GITS_MAX_COLLECTIONS; i++) {
		if (its_data.collections[i].col_id == id)
			return &its_data.collections[i];
	}
	assert(0);
}
