/*
 * (C) Copyright 2006
 * Markus Klotzbuecher, DENX Software Engineering, mk@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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; either version 2 of
 * the License, or (at your option) any later version.
 *
 * 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
 */

/*
 * Host Port Interface (HPI)
 */

/* debug levels:
 *  0 : errors
 *  1 : usefull info
 *  2 : lots of info
 *  3 : noisy
 */

#define DEBUG 0

#include <config.h>
#include <common.h>
#include <mpc8xx.h>

#include "pld.h"
#include "hpi.h"

#define	_NOT_USED_	0xFFFFFFFF

/* original table:
 * - inserted loops to achieve long CS low and high Periods (~217ns)
 * - move cs high 2/4 to the right
 */
const uint dsp_table_slow[] =
{
	/* single read   (offset  0x00 in upm ram) */
	0x8fffdc04, 0x0fffdc84, 0x0fffdc84, 0x0fffdc00,
	0x3fffdc04, 0xffffdc84, 0xffffdc84, 0xffffdc05,

	/* burst read    (offset 0x08 in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,

	/* single write  (offset 0x18 in upm ram) */
	0x8fffd004, 0x0fffd084, 0x0fffd084, 0x3fffd000,
	0xffffd084, 0xffffd084, 0xffffd005, _NOT_USED_,

	/* burst write   (offset 0x20 in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	/* refresh       (offset 0x30 in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	/* exception     (offset 0x3C in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
};

/* dsp hpi upm ram table
 * works fine for noninc access, failes on incremental.
 * - removed first word
 */
const uint dsp_table_fast[] =
{
	/* single read   (offset  0x00 in upm ram) */
	0x8fffdc04, 0x0fffdc04, 0x0fffdc00, 0x3fffdc04,
	0xffffdc05, _NOT_USED_, _NOT_USED_, _NOT_USED_,

	/* burst read    (offset 0x08 in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,

	/* single write  (offset 0x18 in upm ram) */
	0x8fffd004, 0x0fffd004, 0x3fffd000, 0xffffd005,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,

	/* burst write   (offset 0x20 in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	/* refresh       (offset 0x30 in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	/* exception     (offset 0x3C in upm ram) */
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
};


#ifdef CONFIG_SPC1920_HPI_TEST
#undef HPI_TEST_OSZI

#define HPI_TEST_CHUNKSIZE	0x1000
#define HPI_TEST_PATTERN	0x00000000
#define HPI_TEST_START		0x0
#define HPI_TEST_END		0x30000

#define TINY_AUTOINC_DATA_SIZE 16 /* 32bit words */
#define TINY_AUTOINC_BASE_ADDR 0x0

static int hpi_activate(void);
#if 0
static void hpi_inactivate(void);
#endif
static void dsp_reset(void);

static int hpi_write_inc(u32 addr, u32 *data, u32 count);
static int hpi_read_inc(u32 addr, u32 *buf, u32 count);
static int hpi_write_noinc(u32 addr, u32 data);
static u32 hpi_read_noinc(u32 addr);

int hpi_test(void);
static int hpi_write_addr_test(u32 addr);
static int hpi_read_write_test(u32 addr, u32 data);
#ifdef DO_TINY_TEST
static int hpi_tiny_autoinc_test(void);
#endif /* DO_TINY_TEST */
#endif /* CONFIG_SPC1920_HPI_TEST */


/* init the host port interface on UPMA */
int hpi_init(void)
{
	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
	volatile memctl8xx_t *memctl = &immr->im_memctl;
	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CONFIG_SYS_SPC1920_PLD_BASE;

	upmconfig(UPMA, (uint *)dsp_table_slow, sizeof(dsp_table_slow)/sizeof(uint));
	udelay(100);

	memctl->memc_mamr = CONFIG_SYS_MAMR;
	memctl->memc_or3 = CONFIG_SYS_OR3;
	memctl->memc_br3 = CONFIG_SYS_BR3;

	/* reset dsp */
	dsp_reset();

	/* activate hpi switch*/
	pld->dsp_hpi_on = 0x1;

	udelay(100);

	return 0;
}

#ifdef CONFIG_SPC1920_HPI_TEST
/* activate the Host Port interface */
static int hpi_activate(void)
{
	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CONFIG_SYS_SPC1920_PLD_BASE;

	/* turn on hpi */
	pld->dsp_hpi_on = 0x1;

	udelay(5);

	/* turn on the power EN_DSP_POWER high*/
	/* currently always on TBD */

	/* setup hpi control register */
	HPI_HPIC_1 = (u16) 0x0008;
	HPI_HPIC_2 = (u16) 0x0008;

	udelay(100);

	return 0;
}

#if 0
/* turn off the host port interface */
static void hpi_inactivate(void)
{
	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CONFIG_SYS_SPC1920_PLD_BASE;

	/* deactivate hpi */
	pld->dsp_hpi_on = 0x0;

	/* reset the dsp */
	/* pld->dsp_reset = 0x0; */

	/* turn off the power EN_DSP_POWER# high*/
	/* currently always on TBD */

}
#endif

/* reset the DSP */
static void dsp_reset(void)
{
	volatile spc1920_pld_t *pld = (spc1920_pld_t *) CONFIG_SYS_SPC1920_PLD_BASE;
	pld->dsp_reset = 0x1;
	pld->dsp_hpi_on = 0x0;

	udelay(300000);

	pld->dsp_reset = 0x0;
	pld->dsp_hpi_on = 0x1;
}


/* write using autoinc (count is number of 32bit words) */
static int hpi_write_inc(u32 addr, u32 *data, u32 count)
{
	int i;
	u16 addr1, addr2;

	addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
	addr2 = (u16) (addr & 0xffff);

	/* write address */
	HPI_HPIA_1 = addr1;
	HPI_HPIA_2 = addr2;

	debug("writing from data=0x%lx to 0x%lx\n",
		(ulong)data, (ulong)(data+count));

	for(i=0; i<count; i++) {
		HPI_HPID_INC_1 = (u16) ((data[i] >> 16) & 0xffff);
		HPI_HPID_INC_2 = (u16) (data[i] & 0xffff);
		debug("hpi_write_inc: data1=0x%x, data2=0x%x\n",
		       (u16) ((data[i] >> 16) & 0xffff),
		       (u16) (data[i] & 0xffff));
	}
#if 0
	while(data_ptr < (u16*) (data + count)) {
		HPI_HPID_INC_1 = *(data_ptr++);
		HPI_HPID_INC_2 = *(data_ptr++);
	}
#endif

	/* return number of bytes written */
	return count;
}

/*
 * read using autoinc (count is number of 32bit words)
 */
static int hpi_read_inc(u32 addr, u32 *buf, u32 count)
{
	int i;
	u16 addr1, addr2, data1, data2;

	addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
	addr2 = (u16) (addr & 0xffff);

	/* write address */
	HPI_HPIA_1 = addr1;
	HPI_HPIA_2 = addr2;

	for(i=0; i<count; i++) {
		data1 = HPI_HPID_INC_1;
		data2 = HPI_HPID_INC_2;
		debug("hpi_read_inc: data1=0x%x, data2=0x%x\n", data1, data2);
		buf[i] = (((u32) data1) << 16) | (data2 & 0xffff);
	}

#if 0
	while(buf_ptr < (u16*) (buf + count)) {
		*(buf_ptr++) = HPI_HPID_INC_1;
		*(buf_ptr++) = HPI_HPID_INC_2;
	}
#endif

	/* return number of bytes read */
	return count;
}


/* write to non- auto inc regs */
static int hpi_write_noinc(u32 addr, u32 data)
{

	u16 addr1, addr2, data1, data2;

	addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
	addr2 = (u16) (addr & 0xffff);

	/* printf("hpi_write_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */

	HPI_HPIA_1 = addr1;
	HPI_HPIA_2 = addr2;

	data1 = (u16) ((data >> 16) & 0xffff);
	data2 = (u16) (data & 0xffff);

	/* printf("hpi_write_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */

	HPI_HPID_NOINC_1 = data1;
	HPI_HPID_NOINC_2 = data2;

	return 0;
}

/* read from non- auto inc regs */
static u32 hpi_read_noinc(u32 addr)
{
	u16 addr1, addr2, data1, data2;
	u32 ret;

	addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
	addr2 = (u16) (addr & 0xffff);

	HPI_HPIA_1 = addr1;
	HPI_HPIA_2 = addr2;

	/* printf("hpi_read_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */

	data1 = HPI_HPID_NOINC_1;
	data2 = HPI_HPID_NOINC_2;

	/* printf("hpi_read_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */

	ret = (((u32) data1) << 16) | (data2 & 0xffff);
	return ret;

}

/*
 * Host Port Interface Tests
 */

#ifndef HPI_TEST_OSZI
/* main test function */
int hpi_test(void)
{
	int err = 0;
	u32 i, ii, pattern, tmp;

	pattern = HPI_TEST_PATTERN;

	u32 test_data[HPI_TEST_CHUNKSIZE];
	u32 read_data[HPI_TEST_CHUNKSIZE];

	debug("hpi_test: activating hpi...");
	hpi_activate();
	debug("OK.\n");

#if 0
	/* Dump the first 1024 bytes
	 *
	 */
	for(i=0; i<1024; i+=4) {
		if(i%16==0)
			printf("\n0x%08x: ", i);
		printf("0x%08x ", hpi_read_noinc(i));
	}
#endif

	/* HPIA read-write test
	 *
	 */
	debug("hpi_test: starting HPIA read-write tests...\n");
	err |= hpi_write_addr_test(0xdeadc0de);
	err |= hpi_write_addr_test(0xbeefd00d);
	err |= hpi_write_addr_test(0xabcd1234);
	err |= hpi_write_addr_test(0xaaaaaaaa);
	if(err) {
		debug("hpi_test: HPIA read-write tests: *** FAILED ***\n");
		return -1;
	}
	debug("hpi_test: HPIA read-write tests: OK\n");


	/* read write test using nonincremental data regs
	 *
	 */
	debug("hpi_test: starting nonincremental tests...\n");
	for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
		err |= hpi_read_write_test(i, pattern);

		/* stolen from cmd_mem.c */
		if(pattern & 0x80000000) {
			pattern = -pattern;	/* complement & increment */
		} else {
			pattern = ~pattern;
		}
		err |= hpi_read_write_test(i, pattern);

		if(err) {
			debug("hpi_test: nonincremental tests *** FAILED ***\n");
			return -1;
		}
	}
	debug("hpi_test: nonincremental test OK\n");

	/* read write a chunk of data using nonincremental data regs
	 *
	 */
	debug("hpi_test: starting nonincremental chunk tests...\n");
	pattern = HPI_TEST_PATTERN;
	for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
		hpi_write_noinc(i, pattern);

		/* stolen from cmd_mem.c */
		if(pattern & 0x80000000) {
			pattern = -pattern;	/* complement & increment */
		} else {
			pattern = ~pattern;
		}
	}
	pattern = HPI_TEST_PATTERN;
	for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
		tmp = hpi_read_noinc(i);

		if(tmp != pattern) {
			debug("hpi_test: noninc chunk test *** FAILED *** @ 0x%x, written=0x%x, read=0x%x\n", i, pattern, tmp);
			err = -1;
		}
		/* stolen from cmd_mem.c */
		if(pattern & 0x80000000) {
			pattern = -pattern;	/* complement & increment */
		} else {
			pattern = ~pattern;
		}
	}
	if(err)
		return -1;
	debug("hpi_test: nonincremental chunk test OK\n");


#ifdef DO_TINY_TEST
	/* small verbose test using autoinc and nonautoinc to compare
	 *
	 */
	debug("hpi_test: tiny_autoinc_test...\n");
	hpi_tiny_autoinc_test();
	debug("hpi_test: tiny_autoinc_test done\n");
#endif /* DO_TINY_TEST */


	/* $%& write a chunk of data using the autoincremental regs
	 *
	 */
	debug("hpi_test: starting autoinc test %d chunks with 0x%x bytes...\n",
	       ((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE),
	       HPI_TEST_CHUNKSIZE);

	for(i=HPI_TEST_START;
	    i < ((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE);
	    i++) {
		/* generate the pattern data */
		debug("generating pattern data: ");
		for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
			debug("0x%x ", pattern);

			test_data[ii] = pattern;
			read_data[ii] = 0x0; /* zero to be sure */

			/* stolen from cmd_mem.c */
			if(pattern & 0x80000000) {
				pattern = -pattern;	/* complement & increment */
			} else {
				pattern = ~pattern;
			}
		}
		debug("done\n");

		debug("Writing autoinc data @ 0x%x\n", i);
		hpi_write_inc(i, test_data, HPI_TEST_CHUNKSIZE);

		debug("Reading autoinc data @ 0x%x\n", i);
		hpi_read_inc(i, read_data, HPI_TEST_CHUNKSIZE);

		/* compare */
		for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
			debug("hpi_test_autoinc: @ 0x%x, written=0x%x, read=0x%x", i+ii, test_data[ii], read_data[ii]);
			if(read_data[ii] != test_data[ii]) {
				debug("hpi_test: autoinc test @ 0x%x, written=0x%x, read=0x%x *** FAILED ***\n", i+ii, test_data[ii], read_data[ii]);
				return -1;
			}
		}
	}
	debug("hpi_test: autoinc test OK\n");

	return 0;
}
#else /* HPI_TEST_OSZI */
int hpi_test(void)
{
	int i;
	u32 read_data[TINY_AUTOINC_DATA_SIZE];

	unsigned int dummy_data[TINY_AUTOINC_DATA_SIZE] = {
		0x11112222, 0x33334444, 0x55556666, 0x77778888,
		0x9999aaaa, 0xbbbbcccc, 0xddddeeee, 0xffff1111,
		0x00010002, 0x00030004, 0x00050006, 0x00070008,
		0x0009000a, 0x000b000c, 0x000d000e, 0x000f0001
	};

	debug("hpi_test: activating hpi...");
	hpi_activate();
	debug("OK.\n");

	while(1) {
		led9(1);
		debug(" writing to autoinc...\n");
		hpi_write_inc(TINY_AUTOINC_BASE_ADDR,
			      dummy_data, TINY_AUTOINC_DATA_SIZE);

		debug(" reading from autoinc...\n");
		hpi_read_inc(TINY_AUTOINC_BASE_ADDR,
			     read_data, TINY_AUTOINC_DATA_SIZE);

		for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++) {
			debug(" written=0x%x, read(inc)=0x%x\n",
			       dummy_data[i], read_data[i]);
		}
		led9(0);
		udelay(2000000);
	}
	return 0;
}
#endif

/* test if Host Port Address Register can be written correctly */
static int hpi_write_addr_test(u32 addr)
{
	u32 read_back;
	/* write address */
	HPI_HPIA_1 = ((u16) (addr >> 16)); /* First HW is most significant */
	HPI_HPIA_2 = ((u16) addr);

	read_back = (((u32) HPI_HPIA_1)<<16) | ((u32) HPI_HPIA_2);

	if(read_back == addr) {
		debug(" hpi_write_addr_test OK: written=0x%x, read=0x%x\n",
		       addr, read_back);
		return 0;
	} else {
		debug(" hpi_write_addr_test *** FAILED ***: written=0x%x, read=0x%x\n",
		      addr, read_back);
		return -1;
	}

	return 0;
}

/* test if a simple read/write sequence succeeds */
static int hpi_read_write_test(u32 addr, u32 data)
{
	u32 read_back;

	hpi_write_noinc(addr, data);
	read_back = hpi_read_noinc(addr);

	if(read_back == data) {
		debug(" hpi_read_write_test: OK, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
		return 0;
	} else {
		debug(" hpi_read_write_test: *** FAILED ***, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
		return -1;
	}

	return 0;
}

#ifdef DO_TINY_TEST
static int hpi_tiny_autoinc_test(void)
{
	int i;
	u32 read_data[TINY_AUTOINC_DATA_SIZE];
	u32 read_data_noinc[TINY_AUTOINC_DATA_SIZE];

	unsigned int dummy_data[TINY_AUTOINC_DATA_SIZE] = {
		0x11112222, 0x33334444, 0x55556666, 0x77778888,
		0x9999aaaa, 0xbbbbcccc, 0xddddeeee, 0xffff1111,
		0x00010002, 0x00030004, 0x00050006, 0x00070008,
		0x0009000a, 0x000b000c, 0x000d000e, 0x000f0001
	};

	printf(" writing to autoinc...\n");
	hpi_write_inc(TINY_AUTOINC_BASE_ADDR, dummy_data, TINY_AUTOINC_DATA_SIZE);

	printf(" reading from autoinc...\n");
	hpi_read_inc(TINY_AUTOINC_BASE_ADDR, read_data, TINY_AUTOINC_DATA_SIZE);

	printf(" reading from noinc for comparison...\n");
	for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++)
		read_data_noinc[i] = hpi_read_noinc(TINY_AUTOINC_BASE_ADDR+i*4);

	for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++) {
		printf(" written=0x%x, read(inc)=0x%x, read(noinc)=0x%x\n",
		       dummy_data[i], read_data[i], read_data_noinc[i]);
	}
	return 0;
}
#endif /* DO_TINY_TEST */

#endif /* CONFIG_SPC1920_HPI_TEST */
