/*
 * Firmware loader for ETRAX FS IO-Processor
 *
 * Copyright (C) 2004  Axis Communications AB
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/firmware.h>

#include <hwregs/reg_rdwr.h>
#include <hwregs/reg_map.h>
#include <hwregs/iop/iop_reg_space.h>
#include <hwregs/iop/iop_mpu_macros.h>
#include <hwregs/iop/iop_mpu_defs.h>
#include <hwregs/iop/iop_spu_defs.h>
#include <hwregs/iop/iop_sw_cpu_defs.h>

#define IOP_TIMEOUT 100

#error "This driver is broken with regard to its driver core usage."
#error "Please contact <greg@kroah.com> for details on how to fix it properly."

static struct device iop_spu_device[2] = {
	{ .init_name =     "iop-spu0", },
	{ .init_name =     "iop-spu1", },
};

static struct device iop_mpu_device = {
	.init_name =       "iop-mpu",
};

static int wait_mpu_idle(void)
{
	reg_iop_mpu_r_stat mpu_stat;
	unsigned int timeout = IOP_TIMEOUT;

	do {
		mpu_stat = REG_RD(iop_mpu, regi_iop_mpu, r_stat);
	} while (mpu_stat.instr_reg_busy == regk_iop_mpu_yes && --timeout > 0);
	if (timeout == 0) {
		printk(KERN_ERR "Timeout waiting for MPU to be idle\n");
		return -EBUSY;
	}
	return 0;
}

int iop_fw_load_spu(const unsigned char *fw_name, unsigned int spu_inst)
{
	reg_iop_sw_cpu_rw_mc_ctrl mc_ctrl = {
		.wr_spu0_mem =    regk_iop_sw_cpu_no,
		.wr_spu1_mem =    regk_iop_sw_cpu_no,
		.size =           4,
		.cmd =            regk_iop_sw_cpu_reg_copy,
		.keep_owner =     regk_iop_sw_cpu_yes
	};
	reg_iop_spu_rw_ctrl spu_ctrl = {
		.en  =            regk_iop_spu_no,
		.fsm =            regk_iop_spu_no,
	};
	reg_iop_sw_cpu_r_mc_stat mc_stat;
        const struct firmware *fw_entry;
	u32 *data;
	unsigned int timeout;
	int retval, i;

	if (spu_inst > 1)
		return -ENODEV;

	/* get firmware */
	retval = request_firmware(&fw_entry,
				  fw_name,
				  &iop_spu_device[spu_inst]);
	if (retval != 0)
	{
		printk(KERN_ERR
		       "iop_load_spu: Failed to load firmware \"%s\"\n",
		       fw_name);
		return retval;
	}
	data = (u32 *) fw_entry->data;

	/* acquire ownership of memory controller */
	switch (spu_inst) {
	case 0:
		mc_ctrl.wr_spu0_mem = regk_iop_sw_cpu_yes;
		REG_WR(iop_spu, regi_iop_spu0, rw_ctrl, spu_ctrl);
		break;
	case 1:
		mc_ctrl.wr_spu1_mem = regk_iop_sw_cpu_yes;
		REG_WR(iop_spu, regi_iop_spu1, rw_ctrl, spu_ctrl);
		break;
	}
	timeout = IOP_TIMEOUT;
	do {
		REG_WR(iop_sw_cpu, regi_iop_sw_cpu, rw_mc_ctrl, mc_ctrl);
		mc_stat = REG_RD(iop_sw_cpu, regi_iop_sw_cpu, r_mc_stat);
	} while (mc_stat.owned_by_cpu == regk_iop_sw_cpu_no && --timeout > 0);
	if (timeout == 0) {
		printk(KERN_ERR "Timeout waiting to acquire MC\n");
		retval = -EBUSY;
		goto out;
	}

	/* write to SPU memory */
	for (i = 0; i < (fw_entry->size/4); i++) {
		switch (spu_inst) {
		case 0:
			REG_WR_INT(iop_spu, regi_iop_spu0, rw_seq_pc, (i*4));
			break;
		case 1:
			REG_WR_INT(iop_spu, regi_iop_spu1, rw_seq_pc, (i*4));
			break;
		}
		REG_WR_INT(iop_sw_cpu, regi_iop_sw_cpu, rw_mc_data, *data);
		data++;
	}

	/* release ownership of memory controller */
	(void) REG_RD(iop_sw_cpu, regi_iop_sw_cpu, rs_mc_data);

 out:
	release_firmware(fw_entry);
	return retval;
}

int iop_fw_load_mpu(unsigned char *fw_name)
{
	const unsigned int start_addr = 0;
	reg_iop_mpu_rw_ctrl mpu_ctrl;
        const struct firmware *fw_entry;
	u32 *data;
	int retval, i;

	/* get firmware */
	retval = request_firmware(&fw_entry, fw_name, &iop_mpu_device);
	if (retval != 0)
	{
		printk(KERN_ERR
		       "iop_load_spu: Failed to load firmware \"%s\"\n",
		       fw_name);
		return retval;
	}
	data = (u32 *) fw_entry->data;

	/* disable MPU */
	mpu_ctrl.en = regk_iop_mpu_no;
	REG_WR(iop_mpu, regi_iop_mpu, rw_ctrl, mpu_ctrl);
	/* put start address in R0 */
	REG_WR_VECT(iop_mpu, regi_iop_mpu, rw_r, 0, start_addr);
	/* write to memory by executing 'SWX i, 4, R0' for each word */
	if ((retval = wait_mpu_idle()) != 0)
		goto out;
	REG_WR(iop_mpu, regi_iop_mpu, rw_instr, MPU_SWX_IIR_INSTR(0, 4, 0));
	for (i = 0; i < (fw_entry->size / 4); i++) {
		REG_WR_INT(iop_mpu, regi_iop_mpu, rw_immediate, *data);
		if ((retval = wait_mpu_idle()) != 0)
			goto out;
		data++;
	}

 out:
	release_firmware(fw_entry);
	return retval;
}

int iop_start_mpu(unsigned int start_addr)
{
	reg_iop_mpu_rw_ctrl mpu_ctrl = { .en = regk_iop_mpu_yes };
	int retval;

	/* disable MPU */
	if ((retval = wait_mpu_idle()) != 0)
		goto out;
	REG_WR(iop_mpu, regi_iop_mpu, rw_instr, MPU_HALT());
	if ((retval = wait_mpu_idle()) != 0)
		goto out;
	/* set PC and wait for it to bite */
	if ((retval = wait_mpu_idle()) != 0)
		goto out;
	REG_WR_INT(iop_mpu, regi_iop_mpu, rw_instr, MPU_BA_I(start_addr));
	if ((retval = wait_mpu_idle()) != 0)
		goto out;
	/* make sure the MPU starts executing with interrupts disabled */
	REG_WR(iop_mpu, regi_iop_mpu, rw_instr, MPU_DI());
	if ((retval = wait_mpu_idle()) != 0)
		goto out;
	/* enable MPU */
	REG_WR(iop_mpu, regi_iop_mpu, rw_ctrl, mpu_ctrl);
 out:
	return retval;
}

static int __init iop_fw_load_init(void)
{
#if 0
	/*
	 * static struct devices can not be added directly to sysfs by ignoring
	 * the driver model infrastructure.  To fix this properly, please use
	 * the platform_bus to register these devices to be able to properly
	 * use the firmware infrastructure.
	 */
	device_initialize(&iop_spu_device[0]);
	kobject_set_name(&iop_spu_device[0].kobj, "iop-spu0");
	kobject_add(&iop_spu_device[0].kobj);
	device_initialize(&iop_spu_device[1]);
	kobject_set_name(&iop_spu_device[1].kobj, "iop-spu1");
	kobject_add(&iop_spu_device[1].kobj);
	device_initialize(&iop_mpu_device);
	kobject_set_name(&iop_mpu_device.kobj, "iop-mpu");
	kobject_add(&iop_mpu_device.kobj);
#endif
	return 0;
}

static void __exit iop_fw_load_exit(void)
{
}

module_init(iop_fw_load_init);
module_exit(iop_fw_load_exit);

MODULE_DESCRIPTION("ETRAX FS IO-Processor Firmware Loader");
MODULE_LICENSE("GPL");

EXPORT_SYMBOL(iop_fw_load_spu);
EXPORT_SYMBOL(iop_fw_load_mpu);
EXPORT_SYMBOL(iop_start_mpu);
