/*
 * Generic library functions for the microengines found on the Intel
 * IXP2000 series of network processors.
 *
 * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
 * Dedicated to Marija Kulikova.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
#include <asm/arch/hardware.h>
#include <asm/hardware/uengine.h>
#include <asm/io.h>

#if defined(CONFIG_ARCH_IXP2000)
#define IXP_UENGINE_CSR_VIRT_BASE	IXP2000_UENGINE_CSR_VIRT_BASE
#define IXP_PRODUCT_ID			IXP2000_PRODUCT_ID
#define IXP_MISC_CONTROL		IXP2000_MISC_CONTROL
#define IXP_RESET1			IXP2000_RESET1
#else
#if defined(CONFIG_ARCH_IXP23XX)
#define IXP_UENGINE_CSR_VIRT_BASE	IXP23XX_UENGINE_CSR_VIRT_BASE
#define IXP_PRODUCT_ID			IXP23XX_PRODUCT_ID
#define IXP_MISC_CONTROL		IXP23XX_MISC_CONTROL
#define IXP_RESET1			IXP23XX_RESET1
#else
#error unknown platform
#endif
#endif

#define USTORE_ADDRESS			0x000
#define USTORE_DATA_LOWER		0x004
#define USTORE_DATA_UPPER		0x008
#define CTX_ENABLES			0x018
#define CC_ENABLE			0x01c
#define CSR_CTX_POINTER			0x020
#define INDIRECT_CTX_STS		0x040
#define ACTIVE_CTX_STS			0x044
#define INDIRECT_CTX_SIG_EVENTS		0x048
#define INDIRECT_CTX_WAKEUP_EVENTS	0x050
#define NN_PUT				0x080
#define NN_GET				0x084
#define TIMESTAMP_LOW			0x0c0
#define TIMESTAMP_HIGH			0x0c4
#define T_INDEX_BYTE_INDEX		0x0f4
#define LOCAL_CSR_STATUS		0x180

u32 ixp2000_uengine_mask;

static void *ixp2000_uengine_csr_area(int uengine)
{
	return ((void *)IXP_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
}

/*
 * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR
 * space means that the microengine we tried to access was also trying
 * to access its own CSR space on the same clock cycle as we did.  When
 * this happens, we lose the arbitration process by default, and the
 * read or write we tried to do was not actually performed, so we try
 * again until it succeeds.
 */
u32 ixp2000_uengine_csr_read(int uengine, int offset)
{
	void *uebase;
	u32 *local_csr_status;
	u32 *reg;
	u32 value;

	uebase = ixp2000_uengine_csr_area(uengine);

	local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
	reg = (u32 *)(uebase + offset);
	do {
		value = ixp2000_reg_read(reg);
	} while (ixp2000_reg_read(local_csr_status) & 1);

	return value;
}
EXPORT_SYMBOL(ixp2000_uengine_csr_read);

void ixp2000_uengine_csr_write(int uengine, int offset, u32 value)
{
	void *uebase;
	u32 *local_csr_status;
	u32 *reg;

	uebase = ixp2000_uengine_csr_area(uengine);

	local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
	reg = (u32 *)(uebase + offset);
	do {
		ixp2000_reg_write(reg, value);
	} while (ixp2000_reg_read(local_csr_status) & 1);
}
EXPORT_SYMBOL(ixp2000_uengine_csr_write);

void ixp2000_uengine_reset(u32 uengine_mask)
{
	u32 value;

	value = ixp2000_reg_read(IXP_RESET1) & ~ixp2000_uengine_mask;

	uengine_mask &= ixp2000_uengine_mask;
	ixp2000_reg_wrb(IXP_RESET1, value | uengine_mask);
	ixp2000_reg_wrb(IXP_RESET1, value);
}
EXPORT_SYMBOL(ixp2000_uengine_reset);

void ixp2000_uengine_set_mode(int uengine, u32 mode)
{
	/*
	 * CTL_STR_PAR_EN: unconditionally enable parity checking on
	 * control store.
	 */
	mode |= 0x10000000;
	ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode);

	/*
	 * Enable updating of condition codes.
	 */
	ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000);

	/*
	 * Initialise other per-microengine registers.
	 */
	ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00);
	ixp2000_uengine_csr_write(uengine, NN_GET, 0x00);
	ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0);
}
EXPORT_SYMBOL(ixp2000_uengine_set_mode);

static int make_even_parity(u32 x)
{
	return hweight32(x) & 1;
}

static void ustore_write(int uengine, u64 insn)
{
	/*
	 * Generate even parity for top and bottom 20 bits.
	 */
	insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41;
	insn |= (u64)make_even_parity(insn & 0x000fffff) << 40;

	/*
	 * Write to microstore.  The second write auto-increments
	 * the USTORE_ADDRESS index register.
	 */
	ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn);
	ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32));
}

void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns)
{
	int i;

	/*
	 * Start writing to microstore at address 0.
	 */
	ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000);
	for (i = 0; i < insns; i++) {
		u64 insn;

		insn = (((u64)ucode[0]) << 32) |
			(((u64)ucode[1]) << 24) |
			(((u64)ucode[2]) << 16) |
			(((u64)ucode[3]) << 8) |
			((u64)ucode[4]);
		ucode += 5;

		ustore_write(uengine, insn);
	}

	/*
 	 * Pad with a few NOPs at the end (to avoid the microengine
	 * aborting as it prefetches beyond the last instruction), unless
	 * we run off the end of the instruction store first, at which
	 * point the address register will wrap back to zero.
	 */
	for (i = 0; i < 4; i++) {
		u32 addr;

		addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS);
		if (addr == 0x80000000)
			break;
		ustore_write(uengine, 0xf0000c0300ULL);
	}

	/*
	 * End programming.
	 */
	ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000);
}
EXPORT_SYMBOL(ixp2000_uengine_load_microcode);

void ixp2000_uengine_init_context(int uengine, int context, int pc)
{
	/*
	 * Select the right context for indirect access.
	 */
	ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context);

	/*
	 * Initialise signal masks to immediately go to Ready state.
	 */
	ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1);
	ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1);

	/*
	 * Set program counter.
	 */
	ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc);
}
EXPORT_SYMBOL(ixp2000_uengine_init_context);

void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask)
{
	u32 mask;

	/*
	 * Enable the specified context to go to Executing state.
	 */
	mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
	mask |= ctx_mask << 8;
	ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
}
EXPORT_SYMBOL(ixp2000_uengine_start_contexts);

void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask)
{
	u32 mask;

	/*
	 * Disable the Ready->Executing transition.  Note that this
	 * does not stop the context until it voluntarily yields.
	 */
	mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
	mask &= ~(ctx_mask << 8);
	ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
}
EXPORT_SYMBOL(ixp2000_uengine_stop_contexts);

static int check_ixp_type(struct ixp2000_uengine_code *c)
{
	u32 product_id;
	u32 rev;

	product_id = ixp2000_reg_read(IXP_PRODUCT_ID);
	if (((product_id >> 16) & 0x1f) != 0)
		return 0;

	switch ((product_id >> 8) & 0xff) {
#ifdef CONFIG_ARCH_IXP2000
	case 0:		/* IXP2800 */
		if (!(c->cpu_model_bitmask & 4))
			return 0;
		break;

	case 1:		/* IXP2850 */
		if (!(c->cpu_model_bitmask & 8))
			return 0;
		break;

	case 2:		/* IXP2400 */
		if (!(c->cpu_model_bitmask & 2))
			return 0;
		break;
#endif

#ifdef CONFIG_ARCH_IXP23XX
	case 4:		/* IXP23xx */
		if (!(c->cpu_model_bitmask & 0x3f0))
			return 0;
		break;
#endif

	default:
		return 0;
	}

	rev = product_id & 0xff;
	if (rev < c->cpu_min_revision || rev > c->cpu_max_revision)
		return 0;

	return 1;
}

static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
{
	int offset;
	int i;

	offset = 0;

	for (i = 0; i < 128; i++) {
		u8 b3;
		u8 b2;
		u8 b1;
		u8 b0;

		b3 = (gpr_a[i] >> 24) & 0xff;
		b2 = (gpr_a[i] >> 16) & 0xff;
		b1 = (gpr_a[i] >> 8) & 0xff;
		b0 = gpr_a[i] & 0xff;

		// immed[@ai, (b1 << 8) | b0]
		// 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII
		ucode[offset++] = 0xf0;
		ucode[offset++] = (b1 >> 4);
		ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
		ucode[offset++] = (b0 << 2);
		ucode[offset++] = 0x80 | i;

		// immed_w1[@ai, (b3 << 8) | b2]
		// 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII
		ucode[offset++] = 0xf4;
		ucode[offset++] = 0x40 | (b3 >> 4);
		ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
		ucode[offset++] = (b2 << 2);
		ucode[offset++] = 0x80 | i;
	}

	for (i = 0; i < 128; i++) {
		u8 b3;
		u8 b2;
		u8 b1;
		u8 b0;

		b3 = (gpr_b[i] >> 24) & 0xff;
		b2 = (gpr_b[i] >> 16) & 0xff;
		b1 = (gpr_b[i] >> 8) & 0xff;
		b0 = gpr_b[i] & 0xff;

		// immed[@bi, (b1 << 8) | b0]
		// 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV
		ucode[offset++] = 0xf0;
		ucode[offset++] = (b1 >> 4);
		ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
		ucode[offset++] = (i << 2) | 0x03;
		ucode[offset++] = b0;

		// immed_w1[@bi, (b3 << 8) | b2]
		// 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV
		ucode[offset++] = 0xf4;
		ucode[offset++] = 0x40 | (b3 >> 4);
		ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
		ucode[offset++] = (i << 2) | 0x03;
		ucode[offset++] = b2;
	}

	// ctx_arb[kill]
	ucode[offset++] = 0xe0;
	ucode[offset++] = 0x00;
	ucode[offset++] = 0x01;
	ucode[offset++] = 0x00;
	ucode[offset++] = 0x00;
}

static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
{
	int per_ctx_regs;
	u32 *gpr_a;
	u32 *gpr_b;
	u8 *ucode;
	int i;

	gpr_a = kzalloc(128 * sizeof(u32), GFP_KERNEL);
	gpr_b = kzalloc(128 * sizeof(u32), GFP_KERNEL);
	ucode = kmalloc(513 * 5, GFP_KERNEL);
	if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
		kfree(ucode);
		kfree(gpr_b);
		kfree(gpr_a);
		return 1;
	}

	per_ctx_regs = 16;
	if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
		per_ctx_regs = 32;

	for (i = 0; i < 256; i++) {
		struct ixp2000_reg_value *r = c->initial_reg_values + i;
		u32 *bank;
		int inc;
		int j;

		if (r->reg == -1)
			break;

		bank = (r->reg & 0x400) ? gpr_b : gpr_a;
		inc = (r->reg & 0x80) ? 128 : per_ctx_regs;

		j = r->reg & 0x7f;
		while (j < 128) {
			bank[j] = r->value;
			j += inc;
		}
	}

	generate_ucode(ucode, gpr_a, gpr_b);
	ixp2000_uengine_load_microcode(uengine, ucode, 513);
	ixp2000_uengine_init_context(uengine, 0, 0);
	ixp2000_uengine_start_contexts(uengine, 0x01);
	for (i = 0; i < 100; i++) {
		u32 status;

		status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS);
		if (!(status & 0x80000000))
			break;
	}
	ixp2000_uengine_stop_contexts(uengine, 0x01);

	kfree(ucode);
	kfree(gpr_b);
	kfree(gpr_a);

	return !!(i == 100);
}

int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c)
{
	int ctx;

	if (!check_ixp_type(c))
		return 1;

	if (!(ixp2000_uengine_mask & (1 << uengine)))
		return 1;

	ixp2000_uengine_reset(1 << uengine);
	ixp2000_uengine_set_mode(uengine, c->uengine_parameters);
	if (set_initial_registers(uengine, c))
		return 1;
	ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns);

	for (ctx = 0; ctx < 8; ctx++)
		ixp2000_uengine_init_context(uengine, ctx, 0);

	return 0;
}
EXPORT_SYMBOL(ixp2000_uengine_load);


static int __init ixp2000_uengine_init(void)
{
	int uengine;
	u32 value;

	/*
	 * Determine number of microengines present.
	 */
	switch ((ixp2000_reg_read(IXP_PRODUCT_ID) >> 8) & 0x1fff) {
#ifdef CONFIG_ARCH_IXP2000
	case 0:		/* IXP2800 */
	case 1:		/* IXP2850 */
		ixp2000_uengine_mask = 0x00ff00ff;
		break;

	case 2:		/* IXP2400 */
		ixp2000_uengine_mask = 0x000f000f;
		break;
#endif

#ifdef CONFIG_ARCH_IXP23XX
	case 4:		/* IXP23xx */
		ixp2000_uengine_mask = (*IXP23XX_EXP_CFG_FUSE >> 8) & 0xf;
		break;
#endif

	default:
		printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
			(unsigned int)ixp2000_reg_read(IXP_PRODUCT_ID));
		ixp2000_uengine_mask = 0x00000000;
		break;
	}

	/*
	 * Reset microengines.
	 */
	ixp2000_uengine_reset(ixp2000_uengine_mask);

	/*
	 * Synchronise timestamp counters across all microengines.
	 */
	value = ixp2000_reg_read(IXP_MISC_CONTROL);
	ixp2000_reg_wrb(IXP_MISC_CONTROL, value & ~0x80);
	for (uengine = 0; uengine < 32; uengine++) {
		if (ixp2000_uengine_mask & (1 << uengine)) {
			ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
			ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
		}
	}
	ixp2000_reg_wrb(IXP_MISC_CONTROL, value | 0x80);

	return 0;
}

subsys_initcall(ixp2000_uengine_init);
