/*
 * (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(PPC405GP_GPIO0_OR);

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

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

    /* Wait for FPGA init line */
    while(in32(PPC405GP_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(PPC405GP_GPIO0_OR, grego);

    /* Wait for FPGA end of init period .  */
    while(!(in32(PPC405GP_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(PPC405GP_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(PPC405GP_GPIO0_ODR);	/* get open drain register */
	greg |= cnfg;				/* CNFG open drain */
	out32(PPC405GP_GPIO0_ODR, greg);	/*  .. just do it */

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

	/* Setup FPGA for programming */
	grego &= ~cnfg;				/* CONFIG line low */
	out32(PPC405GP_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(PPC405GP_GPIO0_OR, grego);

	/* Turn output enable OFF for CNFG */
	greg = in32(PPC405GP_GPIO0_TCR);	/* get tristate register */
	greg &= ~cnfg;				/* CNFG tristate inactive */
	out32(PPC405GP_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(PPC405GP_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(PPC405GP_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((char *)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;
}
