/*
 *  PS3 Platform spu routines.
 *
 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
 *  Copyright 2006 Sony Corp.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mmzone.h>
#include <linux/io.h>
#include <linux/mm.h>

#include <asm/spu.h>
#include <asm/spu_priv1.h>
#include <asm/lv1call.h>
#include <asm/ps3.h>

#include "../cell/spufs/spufs.h"
#include "platform.h"

/* spu_management_ops */

/**
 * enum spe_type - Type of spe to create.
 * @spe_type_logical: Standard logical spe.
 *
 * For use with lv1_construct_logical_spe().  The current HV does not support
 * any types other than those listed.
 */

enum spe_type {
	SPE_TYPE_LOGICAL = 0,
};

/**
 * struct spe_shadow - logical spe shadow register area.
 *
 * Read-only shadow of spe registers.
 */

struct spe_shadow {
	u8 padding_0140[0x0140];
	u64 int_status_class0_RW;       /* 0x0140 */
	u64 int_status_class1_RW;       /* 0x0148 */
	u64 int_status_class2_RW;       /* 0x0150 */
	u8 padding_0158[0x0610-0x0158];
	u64 mfc_dsisr_RW;               /* 0x0610 */
	u8 padding_0618[0x0620-0x0618];
	u64 mfc_dar_RW;                 /* 0x0620 */
	u8 padding_0628[0x0800-0x0628];
	u64 mfc_dsipr_R;                /* 0x0800 */
	u8 padding_0808[0x0810-0x0808];
	u64 mfc_lscrr_R;                /* 0x0810 */
	u8 padding_0818[0x0c00-0x0818];
	u64 mfc_cer_R;                  /* 0x0c00 */
	u8 padding_0c08[0x0f00-0x0c08];
	u64 spe_execution_status;       /* 0x0f00 */
	u8 padding_0f08[0x1000-0x0f08];
};

/**
 * enum spe_ex_state - Logical spe execution state.
 * @spe_ex_state_unexecutable: Uninitialized.
 * @spe_ex_state_executable: Enabled, not ready.
 * @spe_ex_state_executed: Ready for use.
 *
 * The execution state (status) of the logical spe as reported in
 * struct spe_shadow:spe_execution_status.
 */

enum spe_ex_state {
	SPE_EX_STATE_UNEXECUTABLE = 0,
	SPE_EX_STATE_EXECUTABLE = 2,
	SPE_EX_STATE_EXECUTED = 3,
};

/**
 * struct priv1_cache - Cached values of priv1 registers.
 * @masks[]: Array of cached spe interrupt masks, indexed by class.
 * @sr1: Cached mfc_sr1 register.
 * @tclass_id: Cached mfc_tclass_id register.
 */

struct priv1_cache {
	u64 masks[3];
	u64 sr1;
	u64 tclass_id;
};

/**
 * struct spu_pdata - Platform state variables.
 * @spe_id: HV spe id returned by lv1_construct_logical_spe().
 * @resource_id: HV spe resource id returned by
 * 	ps3_repository_read_spe_resource_id().
 * @priv2_addr: lpar address of spe priv2 area returned by
 * 	lv1_construct_logical_spe().
 * @shadow_addr: lpar address of spe register shadow area returned by
 * 	lv1_construct_logical_spe().
 * @shadow: Virtual (ioremap) address of spe register shadow area.
 * @cache: Cached values of priv1 registers.
 */

struct spu_pdata {
	u64 spe_id;
	u64 resource_id;
	u64 priv2_addr;
	u64 shadow_addr;
	struct spe_shadow __iomem *shadow;
	struct priv1_cache cache;
};

static struct spu_pdata *spu_pdata(struct spu *spu)
{
	return spu->pdata;
}

#define dump_areas(_a, _b, _c, _d, _e) \
	_dump_areas(_a, _b, _c, _d, _e, __func__, __LINE__)
static void _dump_areas(unsigned int spe_id, unsigned long priv2,
	unsigned long problem, unsigned long ls, unsigned long shadow,
	const char* func, int line)
{
	pr_debug("%s:%d: spe_id:  %xh (%u)\n", func, line, spe_id, spe_id);
	pr_debug("%s:%d: priv2:   %lxh\n", func, line, priv2);
	pr_debug("%s:%d: problem: %lxh\n", func, line, problem);
	pr_debug("%s:%d: ls:      %lxh\n", func, line, ls);
	pr_debug("%s:%d: shadow:  %lxh\n", func, line, shadow);
}

inline u64 ps3_get_spe_id(void *arg)
{
	return spu_pdata(arg)->spe_id;
}
EXPORT_SYMBOL_GPL(ps3_get_spe_id);

static unsigned long get_vas_id(void)
{
	u64 id;

	lv1_get_logical_ppe_id(&id);
	lv1_get_virtual_address_space_id_of_ppe(id, &id);

	return id;
}

static int __init construct_spu(struct spu *spu)
{
	int result;
	u64 unused;
	u64 problem_phys;
	u64 local_store_phys;

	result = lv1_construct_logical_spe(PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT,
		PAGE_SHIFT, PAGE_SHIFT, get_vas_id(), SPE_TYPE_LOGICAL,
		&spu_pdata(spu)->priv2_addr, &problem_phys,
		&local_store_phys, &unused,
		&spu_pdata(spu)->shadow_addr,
		&spu_pdata(spu)->spe_id);
	spu->problem_phys = problem_phys;
	spu->local_store_phys = local_store_phys;

	if (result) {
		pr_debug("%s:%d: lv1_construct_logical_spe failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	return result;
}

static void spu_unmap(struct spu *spu)
{
	iounmap(spu->priv2);
	iounmap(spu->problem);
	iounmap((__force u8 __iomem *)spu->local_store);
	iounmap(spu_pdata(spu)->shadow);
}

/**
 * setup_areas - Map the spu regions into the address space.
 *
 * The current HV requires the spu shadow regs to be mapped with the
 * PTE page protection bits set as read-only (PP=3).  This implementation
 * uses the low level __ioremap() to bypass the page protection settings
 * inforced by ioremap_flags() to get the needed PTE bits set for the
 * shadow regs.
 */

static int __init setup_areas(struct spu *spu)
{
	struct table {char* name; unsigned long addr; unsigned long size;};
	static const unsigned long shadow_flags = _PAGE_NO_CACHE | 3;

	spu_pdata(spu)->shadow = __ioremap(spu_pdata(spu)->shadow_addr,
					   sizeof(struct spe_shadow),
					   shadow_flags);
	if (!spu_pdata(spu)->shadow) {
		pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
		goto fail_ioremap;
	}

	spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys,
		LS_SIZE, _PAGE_NO_CACHE);

	if (!spu->local_store) {
		pr_debug("%s:%d: ioremap local_store failed\n",
			__func__, __LINE__);
		goto fail_ioremap;
	}

	spu->problem = ioremap(spu->problem_phys,
		sizeof(struct spu_problem));

	if (!spu->problem) {
		pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
		goto fail_ioremap;
	}

	spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
		sizeof(struct spu_priv2));

	if (!spu->priv2) {
		pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
		goto fail_ioremap;
	}

	dump_areas(spu_pdata(spu)->spe_id, spu_pdata(spu)->priv2_addr,
		spu->problem_phys, spu->local_store_phys,
		spu_pdata(spu)->shadow_addr);
	dump_areas(spu_pdata(spu)->spe_id, (unsigned long)spu->priv2,
		(unsigned long)spu->problem, (unsigned long)spu->local_store,
		(unsigned long)spu_pdata(spu)->shadow);

	return 0;

fail_ioremap:
	spu_unmap(spu);

	return -ENOMEM;
}

static int __init setup_interrupts(struct spu *spu)
{
	int result;

	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
		0, &spu->irqs[0]);

	if (result)
		goto fail_alloc_0;

	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
		1, &spu->irqs[1]);

	if (result)
		goto fail_alloc_1;

	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
		2, &spu->irqs[2]);

	if (result)
		goto fail_alloc_2;

	return result;

fail_alloc_2:
	ps3_spe_irq_destroy(spu->irqs[1]);
fail_alloc_1:
	ps3_spe_irq_destroy(spu->irqs[0]);
fail_alloc_0:
	spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
	return result;
}

static int __init enable_spu(struct spu *spu)
{
	int result;

	result = lv1_enable_logical_spe(spu_pdata(spu)->spe_id,
		spu_pdata(spu)->resource_id);

	if (result) {
		pr_debug("%s:%d: lv1_enable_logical_spe failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		goto fail_enable;
	}

	result = setup_areas(spu);

	if (result)
		goto fail_areas;

	result = setup_interrupts(spu);

	if (result)
		goto fail_interrupts;

	return 0;

fail_interrupts:
	spu_unmap(spu);
fail_areas:
	lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
fail_enable:
	return result;
}

static int ps3_destroy_spu(struct spu *spu)
{
	int result;

	pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number);

	result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
	BUG_ON(result);

	ps3_spe_irq_destroy(spu->irqs[2]);
	ps3_spe_irq_destroy(spu->irqs[1]);
	ps3_spe_irq_destroy(spu->irqs[0]);

	spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;

	spu_unmap(spu);

	result = lv1_destruct_logical_spe(spu_pdata(spu)->spe_id);
	BUG_ON(result);

	kfree(spu->pdata);
	spu->pdata = NULL;

	return 0;
}

static int __init ps3_create_spu(struct spu *spu, void *data)
{
	int result;

	pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number);

	spu->pdata = kzalloc(sizeof(struct spu_pdata),
		GFP_KERNEL);

	if (!spu->pdata) {
		result = -ENOMEM;
		goto fail_malloc;
	}

	spu_pdata(spu)->resource_id = (unsigned long)data;

	/* Init cached reg values to HV defaults. */

	spu_pdata(spu)->cache.sr1 = 0x33;

	result = construct_spu(spu);

	if (result)
		goto fail_construct;

	/* For now, just go ahead and enable it. */

	result = enable_spu(spu);

	if (result)
		goto fail_enable;

	/* Make sure the spu is in SPE_EX_STATE_EXECUTED. */

	/* need something better here!!! */
	while (in_be64(&spu_pdata(spu)->shadow->spe_execution_status)
		!= SPE_EX_STATE_EXECUTED)
		(void)0;

	return result;

fail_enable:
fail_construct:
	ps3_destroy_spu(spu);
fail_malloc:
	return result;
}

static int __init ps3_enumerate_spus(int (*fn)(void *data))
{
	int result;
	unsigned int num_resource_id;
	unsigned int i;

	result = ps3_repository_read_num_spu_resource_id(&num_resource_id);

	pr_debug("%s:%d: num_resource_id %u\n", __func__, __LINE__,
		num_resource_id);

	/*
	 * For now, just create logical spus equal to the number
	 * of physical spus reserved for the partition.
	 */

	for (i = 0; i < num_resource_id; i++) {
		enum ps3_spu_resource_type resource_type;
		unsigned int resource_id;

		result = ps3_repository_read_spu_resource_id(i,
			&resource_type, &resource_id);

		if (result)
			break;

		if (resource_type == PS3_SPU_RESOURCE_TYPE_EXCLUSIVE) {
			result = fn((void*)(unsigned long)resource_id);

			if (result)
				break;
		}
	}

	if (result) {
		printk(KERN_WARNING "%s:%d: Error initializing spus\n",
			__func__, __LINE__);
		return result;
	}

	return num_resource_id;
}

static int ps3_init_affinity(void)
{
	return 0;
}

/**
 * ps3_enable_spu - Enable SPU run control.
 *
 * An outstanding enhancement for the PS3 would be to add a guard to check
 * for incorrect access to the spu problem state when the spu context is
 * disabled.  This check could be implemented with a flag added to the spu
 * context that would inhibit mapping problem state pages, and a routine
 * to unmap spu problem state pages.  When the spu is enabled with
 * ps3_enable_spu() the flag would be set allowing pages to be mapped,
 * and when the spu is disabled with ps3_disable_spu() the flag would be
 * cleared and the mapped problem state pages would be unmapped.
 */

static void ps3_enable_spu(struct spu_context *ctx)
{
}

static void ps3_disable_spu(struct spu_context *ctx)
{
	ctx->ops->runcntl_stop(ctx);
}

const struct spu_management_ops spu_management_ps3_ops = {
	.enumerate_spus = ps3_enumerate_spus,
	.create_spu = ps3_create_spu,
	.destroy_spu = ps3_destroy_spu,
	.enable_spu = ps3_enable_spu,
	.disable_spu = ps3_disable_spu,
	.init_affinity = ps3_init_affinity,
};

/* spu_priv1_ops */

static void int_mask_and(struct spu *spu, int class, u64 mask)
{
	u64 old_mask;

	/* are these serialized by caller??? */
	old_mask = spu_int_mask_get(spu, class);
	spu_int_mask_set(spu, class, old_mask & mask);
}

static void int_mask_or(struct spu *spu, int class, u64 mask)
{
	u64 old_mask;

	old_mask = spu_int_mask_get(spu, class);
	spu_int_mask_set(spu, class, old_mask | mask);
}

static void int_mask_set(struct spu *spu, int class, u64 mask)
{
	spu_pdata(spu)->cache.masks[class] = mask;
	lv1_set_spe_interrupt_mask(spu_pdata(spu)->spe_id, class,
		spu_pdata(spu)->cache.masks[class]);
}

static u64 int_mask_get(struct spu *spu, int class)
{
	return spu_pdata(spu)->cache.masks[class];
}

static void int_stat_clear(struct spu *spu, int class, u64 stat)
{
	/* Note that MFC_DSISR will be cleared when class1[MF] is set. */

	lv1_clear_spe_interrupt_status(spu_pdata(spu)->spe_id, class,
		stat, 0);
}

static u64 int_stat_get(struct spu *spu, int class)
{
	u64 stat;

	lv1_get_spe_interrupt_status(spu_pdata(spu)->spe_id, class, &stat);
	return stat;
}

static void cpu_affinity_set(struct spu *spu, int cpu)
{
	/* No support. */
}

static u64 mfc_dar_get(struct spu *spu)
{
	return in_be64(&spu_pdata(spu)->shadow->mfc_dar_RW);
}

static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
{
	/* Nothing to do, cleared in int_stat_clear(). */
}

static u64 mfc_dsisr_get(struct spu *spu)
{
	return in_be64(&spu_pdata(spu)->shadow->mfc_dsisr_RW);
}

static void mfc_sdr_setup(struct spu *spu)
{
	/* Nothing to do. */
}

static void mfc_sr1_set(struct spu *spu, u64 sr1)
{
	/* Check bits allowed by HV. */

	static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
		| MFC_STATE1_PROBLEM_STATE_MASK);

	BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));

	spu_pdata(spu)->cache.sr1 = sr1;
	lv1_set_spe_privilege_state_area_1_register(
		spu_pdata(spu)->spe_id,
		offsetof(struct spu_priv1, mfc_sr1_RW),
		spu_pdata(spu)->cache.sr1);
}

static u64 mfc_sr1_get(struct spu *spu)
{
	return spu_pdata(spu)->cache.sr1;
}

static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
{
	spu_pdata(spu)->cache.tclass_id = tclass_id;
	lv1_set_spe_privilege_state_area_1_register(
		spu_pdata(spu)->spe_id,
		offsetof(struct spu_priv1, mfc_tclass_id_RW),
		spu_pdata(spu)->cache.tclass_id);
}

static u64 mfc_tclass_id_get(struct spu *spu)
{
	return spu_pdata(spu)->cache.tclass_id;
}

static void tlb_invalidate(struct spu *spu)
{
	/* Nothing to do. */
}

static void resource_allocation_groupID_set(struct spu *spu, u64 id)
{
	/* No support. */
}

static u64 resource_allocation_groupID_get(struct spu *spu)
{
	return 0; /* No support. */
}

static void resource_allocation_enable_set(struct spu *spu, u64 enable)
{
	/* No support. */
}

static u64 resource_allocation_enable_get(struct spu *spu)
{
	return 0; /* No support. */
}

const struct spu_priv1_ops spu_priv1_ps3_ops = {
	.int_mask_and = int_mask_and,
	.int_mask_or = int_mask_or,
	.int_mask_set = int_mask_set,
	.int_mask_get = int_mask_get,
	.int_stat_clear = int_stat_clear,
	.int_stat_get = int_stat_get,
	.cpu_affinity_set = cpu_affinity_set,
	.mfc_dar_get = mfc_dar_get,
	.mfc_dsisr_set = mfc_dsisr_set,
	.mfc_dsisr_get = mfc_dsisr_get,
	.mfc_sdr_setup = mfc_sdr_setup,
	.mfc_sr1_set = mfc_sr1_set,
	.mfc_sr1_get = mfc_sr1_get,
	.mfc_tclass_id_set = mfc_tclass_id_set,
	.mfc_tclass_id_get = mfc_tclass_id_get,
	.tlb_invalidate = tlb_invalidate,
	.resource_allocation_groupID_set = resource_allocation_groupID_set,
	.resource_allocation_groupID_get = resource_allocation_groupID_get,
	.resource_allocation_enable_set = resource_allocation_enable_set,
	.resource_allocation_enable_get = resource_allocation_enable_get,
};

void ps3_spu_set_platform(void)
{
	spu_priv1_ops = &spu_priv1_ps3_ops;
	spu_management_ops = &spu_management_ps3_ops;
}
