/*
 * (C) Copyright 2001
 * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
 *  and
 * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
 *
 * 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
 */
#include <config.h>
#include <common.h>
#include "w7o.h"
#include <asm/processor.h>
#include "errors.h"

static void
fpga_img_write(unsigned long *src, unsigned long len, unsigned short *daddr)
{
    unsigned long i;
    volatile unsigned long val;
    volatile unsigned short *dest = daddr;	/* volatile-bypass optimizer */

    for (i = 0; i < len; i++, src++) {
	val = *src;
	*dest = (unsigned short)((val & 0xff000000L) >> 16);
	*dest = (unsigned short)((val & 0x00ff0000L) >> 8);
	*dest = (unsigned short)(val & 0x0000ff00L);
	*dest = (unsigned short)((val & 0x000000ffL) << 8);
    }

    /* Terminate programming with 4 C clocks */
    dest = daddr;
    val = *(unsigned short *)dest;
    val = *(unsigned short *)dest;
    val = *(unsigned short *)dest;
    val = *(unsigned short *)dest;

}


int
fpgaDownload(unsigned char *saddr,
	     unsigned long size,
	     unsigned short *daddr)
{
    int i;					/* index, intr disable flag */
    int start;					/* timer */
    unsigned long greg, grego;			/* GPIO & output register */
    unsigned long length;			/* image size in words */
    unsigned long *source;			/* image source addr */
    unsigned short *dest;			/* destination FPGA addr */
    volatile unsigned short *ndest;		/* temp dest FPGA addr */
    volatile unsigned short val;		/* temp val */
    unsigned long cnfg = GPIO_XCV_CNFG;		/* FPGA CNFG */
    unsigned long eirq = GPIO_XCV_IRQ;
    int retval = -1;				/* Function return value */

    /* Setup some basic values */
    length = (size / 4) + 1;			/* size in words, rounding UP
						    is OK */
    source = (unsigned long *)saddr;
    dest = (unsigned short *)daddr;

    /* Get DCR output register */
    grego = in32(IBM405GP_GPIO0_OR);

    /* Reset FPGA */
    grego &= ~GPIO_XCV_PROG;			/* PROG line low */
    out32(IBM405GP_GPIO0_OR, grego);

    /* Setup timeout timer */
    start = get_timer(0);

    /* Wait for FPGA init line */
    while(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT) { /* Wait INIT line low */
	/* Check for timeout - 100us max, so use 3ms */
	if (get_timer(start) > 3) {
	    printf("     failed to start init.\n");
	    log_warn(ERR_XINIT0);		/* Don't halt */

	    /* Reset line stays low */
	    goto done;				/* I like gotos... */
	}
    }

    /* Unreset FPGA */
    grego |= GPIO_XCV_PROG;			/* PROG line high */
    out32(IBM405GP_GPIO0_OR, grego);

    /* Wait for FPGA end of init period .  */
    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT)) { /* Wait for INIT hi */

	/* Check for timeout */
	if (get_timer(start) > 3) {
	    printf("     failed to exit init.\n");
	    log_warn(ERR_XINIT1);

	    /* Reset FPGA */
	    grego &= ~GPIO_XCV_PROG;		/* PROG line low */
	    out32(IBM405GP_GPIO0_OR, grego);

	    goto done;
	}
    }

    /* Now program FPGA ... */
    ndest = dest;
    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
	/* Toggle IRQ/GPIO */
	greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */
	greg |= eirq;				/* toggle irq/gpio */
	mtdcr(CPC0_CR0, greg);			/*  ... just do it */

	/* turn on open drain for CNFG */
	greg = in32(IBM405GP_GPIO0_ODR);	/* get open drain register */
	greg |= cnfg;				/* CNFG open drain */
	out32(IBM405GP_GPIO0_ODR, greg);	/*  .. just do it */

	/* Turn output enable on for CNFG */
	greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */
	greg |= cnfg;				/* CNFG tristate inactive */
	out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */

	/* Setup FPGA for programming */
	grego &= ~cnfg;				/* CONFIG line low */
	out32(IBM405GP_GPIO0_OR, grego);

	/*
	 * Program the FPGA
	 */
	printf("\n       destination: 0x%lx ", (unsigned long)ndest);

	fpga_img_write(source,  length,  (unsigned short *)ndest);

	/* Done programming */
	grego |= cnfg;				/* CONFIG line high */
	out32(IBM405GP_GPIO0_OR, grego);

	/* Turn output enable OFF for CNFG */
	greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */
	greg &= ~cnfg;				/* CNFG tristate inactive */
	out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */

	/* Toggle IRQ/GPIO */
	greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */
	greg &= ~eirq;				/* toggle irq/gpio */
	mtdcr(CPC0_CR0, greg);			/*  ... just do it */

	ndest = (unsigned short *)((char *)ndest + 0x00100000L); /* XXX - Next FPGA addr */
	cnfg >>= 1;				/* XXX - Next  */
	eirq >>= 1;
    }

    /* Terminate programming with 4 C clocks */
    ndest = dest;
    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
	val = *ndest;
	val = *ndest;
	val = *ndest;
	val = *ndest;
	ndest = (unsigned short *)((char *)ndest + 0x00100000L);
    }

    /* Setup timer */
    start = get_timer(0);

    /* Wait for FPGA end of programming period .  */
    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_DONE)) { /* Test DONE low */

	/* Check for timeout */
	if (get_timer(start) > 3) {
	    printf("     done failed to come high.\n");
	    log_warn(ERR_XDONE1);

	    /* Reset FPGA */
	    grego &= ~GPIO_XCV_PROG;		/* PROG line low */
	    out32(IBM405GP_GPIO0_OR, grego);

	    goto done;
	}
    }

    printf("\n       FPGA load succeeded\n");
    retval = 0;					/* Program OK */

done:
    return retval;
}

/* FPGA image is stored in flash */
extern flash_info_t    flash_info[];

int init_fpga(void)
{
    unsigned int i,j,ptr;			/* General purpose */
    unsigned char bufchar;			/* General purpose character */
    unsigned char *buf;				/* Start of image pointer */
    unsigned long len;				/* Length of image */
    unsigned char *fn_buf;			/* Start of filename string */
    unsigned int fn_len;			/* Length of filename string */
    unsigned char *xcv_buf;			/* Pointer to start of image */
    unsigned long xcv_len;			/* Length of image */
    unsigned long crc;				/* 30bit crc in image */
    unsigned long calc_crc;			/* Calc'd 30bit crc */
    int retval = -1;

    /* Tell the world what we are doing */
    printf("FPGA:  ");

    /*
     * Get address of first sector where the FPGA
     * image is stored.
     */
    buf = (unsigned char *)flash_info[1].start[0];

    /*
     * Get the stored image's CRC & length.
     */
    crc = *(unsigned long *)(buf+4);		/* CRC is first long word */
    len = *(unsigned long *)(buf+8);		/* Image len is next long */

    /* Pedantic */
    if ((len < 0x133A4) || (len > 0x80000))
	goto bad_image;

    /*
     * Get the file name pointer and length.
     */
    fn_len = (*(unsigned short *)(buf+12) & 0xff); /* filename length
						      is next short */
    fn_buf = buf + 14;

    /*
     * Get the FPGA image pointer and length length.
     */
    xcv_buf = fn_buf + fn_len;			/* pointer to fpga image */
    xcv_len = len - 14 - fn_len;		/* fpga image length */

    /* Check for uninitialized FLASH */
    if ((strncmp(buf, "w7o", 3)!=0) || (len > 0x0007ffffL) || (len == 0))
	goto bad_image;

    /*
     * Calculate and Check the image's CRC.
     */
    calc_crc = crc32(0, xcv_buf, xcv_len);
    if (crc != calc_crc) {
	printf("\nfailed - bad CRC\n");
	goto done;
    }

    /* Output the file name */
    printf("file name  : ");
    for (i=0;i<fn_len;i++) {
	bufchar = fn_buf[+i];
	if (bufchar<' ' || bufchar>'~') bufchar = '.';
	putc(bufchar);
    }

    /*
     * find rest of display data
     */
    ptr = 15;					/* Offset to ncd filename
						   length in fpga image */
    j = xcv_buf[ptr];				/* Get len of ncd filename */
    if (j > 32) goto bad_image;
    ptr = ptr + j + 3;				/* skip ncd filename string +
						   3 bytes more bytes */

    /*
     * output target device string
     */
    j = xcv_buf[ptr++] - 1;			/* len of targ str less term */
    if (j > 32) goto bad_image;
    printf("\n       target     : ");
    for (i = 0; i < j; i++) {
	bufchar = (xcv_buf[ptr++]);
	if (bufchar<' ' || bufchar>'~') bufchar = '.';
	putc(bufchar);
    }

    /*
     * output compilation date string and time string
     */
    ptr += 3;					/* skip 2 bytes */
    printf("\n       synth time : ");
    j = (xcv_buf[ptr++] - 1);			/* len of date str less term */
    if (j > 32) goto bad_image;
    for (i = 0; i < j; i++) {
	bufchar = (xcv_buf[ptr++]);
	if (bufchar<' ' || bufchar>'~') bufchar = '.';
	putc(bufchar);
    }

    ptr += 3;					/* Skip 2 bytes */
    printf(" - ");
    j = (xcv_buf[ptr++] - 1);			/* slen = targ dev str len */
    if (j > 32) goto bad_image;
    for (i = 0; i < j; i++) {
	bufchar = (xcv_buf[ptr++]);
	if (bufchar<' ' || bufchar>'~') bufchar = '.';
	putc(bufchar);
    }

    /*
     * output crc and length strings
     */
    printf("\n       len & crc  : 0x%lx  0x%lx", len, crc);

    /*
     * Program the FPGA.
     */
    retval = fpgaDownload((unsigned char*)xcv_buf, xcv_len,
			  (unsigned short *)0xfd000000L);
    return retval;

bad_image:
    printf("\n       BAD FPGA image format @ %lx\n", flash_info[1].start[0]);
    log_warn(ERR_XIMAGE);
done:
    return retval;
}

void test_fpga(unsigned short *daddr)
{
    int i;
    volatile unsigned short *ndest = daddr;

    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {
#if defined(CONFIG_W7OLMG)
	ndest[0x7e] = 0x55aa;
	if (ndest[0x7e] != 0x55aa)
	    log_warn(ERR_XRW1 + i);
	ndest[0x7e] = 0xaa55;
	if (ndest[0x7e] != 0xaa55)
	    log_warn(ERR_XRW1 + i);
	ndest[0x7e] = 0xc318;
	if (ndest[0x7e] != 0xc318)
	    log_warn(ERR_XRW1 + i);

#elif defined(CONFIG_W7OLMC)
	ndest[0x800] = 0x55aa;
	ndest[0x801] = 0xaa55;
	ndest[0x802] = 0xc318;
	ndest[0x4800] = 0x55aa;
	ndest[0x4801] = 0xaa55;
	ndest[0x4802] = 0xc318;
	if ((ndest[0x800] != 0x55aa) ||
	    (ndest[0x801] != 0xaa55) ||
	    (ndest[0x802] != 0xc318))
	    log_warn(ERR_XRW1 + (2 * i));       /* Auto gen error code */
	if ((ndest[0x4800] != 0x55aa) ||
	    (ndest[0x4801] != 0xaa55) ||
	    (ndest[0x4802] != 0xc318))
	    log_warn(ERR_XRW2 + (2 * i));       /* Auto gen error code */

#else
# error "Unknown W7O board configuration"
#endif
    }

    printf("       FPGA ready\n");
    return;
}
