/*
 * (C) Copyright 2001-2003
 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
 *
 * 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 <common.h>
#include <asm/processor.h>
#include <command.h>

/* ------------------------------------------------------------------------- */

#ifdef FPGA_DEBUG
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif /* DEBUG */

#define MAX_ONES               226

#ifdef CFG_FPGA_PRG
# define FPGA_PRG              CFG_FPGA_PRG /* FPGA program pin (ppc output)*/
# define FPGA_CLK              CFG_FPGA_CLK /* FPGA clk pin (ppc output)    */
# define FPGA_DATA             CFG_FPGA_DATA /* FPGA data pin (ppc output)  */
# define FPGA_DONE             CFG_FPGA_DONE /* FPGA done pin (ppc input)   */
# define FPGA_INIT             CFG_FPGA_INIT /* FPGA init pin (ppc input)   */
#else
# define FPGA_PRG              0x04000000  /* FPGA program pin (ppc output) */
# define FPGA_CLK              0x02000000  /* FPGA clk pin (ppc output)     */
# define FPGA_DATA             0x01000000  /* FPGA data pin (ppc output)    */
# define FPGA_DONE             0x00800000  /* FPGA done pin (ppc input)     */
# define FPGA_INIT             0x00400000  /* FPGA init pin (ppc input)     */
#endif

#define ERROR_FPGA_PRG_INIT_LOW  -1        /* Timeout after PRG* asserted   */
#define ERROR_FPGA_PRG_INIT_HIGH -2        /* Timeout after PRG* deasserted */
#define ERROR_FPGA_PRG_DONE      -3        /* Timeout after programming     */

#define SET_FPGA(data)         out32(GPIO0_OR, data)

#define FPGA_WRITE_1 {                                                    \
	SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
	SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set data to 1  */  \
	SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* set clock to 1 */  \
	SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1  */

#define FPGA_WRITE_0 {                                                    \
	SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
	SET_FPGA(FPGA_PRG);                         /* set data to 0  */  \
	SET_FPGA(FPGA_PRG | FPGA_CLK);              /* set clock to 1 */  \
	SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1  */


static int fpga_boot(unsigned char *fpgadata, int size)
{
  int i,index,len;
  int count;
#ifdef CFG_FPGA_SPARTAN2
  int j;
#else
  unsigned char b;
  int bit;
#endif

  /* display infos on fpgaimage */
  index = 15;
  for (i=0; i<4; i++)
    {
      len = fpgadata[index];
      DBG("FPGA: %s\n", &(fpgadata[index+1]));
      index += len+3;
    }

#ifdef CFG_FPGA_SPARTAN2
  /* search for preamble 0xFFFFFFFF */
  while (1)
    {
      if ((fpgadata[index] == 0xff) && (fpgadata[index+1] == 0xff) &&
	  (fpgadata[index+2] == 0xff) && (fpgadata[index+3] == 0xff))
	break; /* preamble found */
      else
	index++;
    }
#else
  /* search for preamble 0xFF2X */
  for (index = 0; index < size-1 ; index++)
    {
      if ((fpgadata[index] == 0xff) && ((fpgadata[index+1] & 0xf0) == 0x30))
	break;
    }
  index += 2;
#endif

  DBG("FPGA: configdata starts at position 0x%x\n",index);
  DBG("FPGA: length of fpga-data %d\n", size-index);

  /*
   * Setup port pins for fpga programming
   */
  out32(GPIO0_ODR, 0x00000000);                                      /* no open drain pins */
  out32(GPIO0_TCR, in32(GPIO0_TCR) | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* setup for output */
  out32(GPIO0_OR, in32(GPIO0_OR) | FPGA_PRG | FPGA_CLK | FPGA_DATA);   /* set pins to high */

  DBG("%s, ",((in32(GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
  DBG("%s\n",((in32(GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );

  /*
   * Init fpga by asserting and deasserting PROGRAM*
   */
  SET_FPGA(FPGA_CLK | FPGA_DATA);

  /* Wait for FPGA init line low */
  count = 0;
  while (in32(GPIO0_IR) & FPGA_INIT)
    {
      udelay(1000); /* wait 1ms */
      /* Check for timeout - 100us max, so use 3ms */
      if (count++ > 3)
	{
	  DBG("FPGA: Booting failed!\n");
	  return ERROR_FPGA_PRG_INIT_LOW;
	}
    }

  DBG("%s, ",((in32(GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
  DBG("%s\n",((in32(GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );

  /* deassert PROGRAM* */
  SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);

  /* Wait for FPGA end of init period .  */
  count = 0;
  while (!(in32(GPIO0_IR) & FPGA_INIT))
    {
      udelay(1000); /* wait 1ms */
      /* Check for timeout */
      if (count++ > 3)
	{
	  DBG("FPGA: Booting failed!\n");
	  return ERROR_FPGA_PRG_INIT_HIGH;
	}
    }

  DBG("%s, ",((in32(GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
  DBG("%s\n",((in32(GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );

  DBG("write configuration data into fpga\n");
  /* write configuration-data into fpga... */

#ifdef CFG_FPGA_SPARTAN2
  /*
   * Load uncompressed image into fpga
   */
  for (i=index; i<size; i++)
    {
      for (j=0; j<8; j++)
	{
	  if ((fpgadata[i] & 0x80) == 0x80)
	    {
	      FPGA_WRITE_1;
	    }
	  else
	    {
	      FPGA_WRITE_0;
	    }
	  fpgadata[i] <<= 1;
	}
    }
#else
  /* send 0xff 0x20 */
  FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
  FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1;
  FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_1; FPGA_WRITE_0;
  FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0;

  /*
  ** Bit_DeCompression
  **   Code 1           .. maxOnes     : n                 '1's followed by '0'
  **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0'
  **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1'
  **        255                        :                   '1'
  */

  for (i=index; i<size; i++)
    {
      b = fpgadata[i];
      if ((b >= 1) && (b <= MAX_ONES))
	{
	  for(bit=0; bit<b; bit++)
	    {
	      FPGA_WRITE_1;
	    }
	  FPGA_WRITE_0;
	}
      else if (b == (MAX_ONES+1))
	{
	  for(bit=1; bit<b; bit++)
	    {
	      FPGA_WRITE_1;
	    }
	}
      else if ((b >= (MAX_ONES+2)) && (b <= 254))
	{
	  for(bit=0; bit<(b-(MAX_ONES+2)); bit++)
	    {
	      FPGA_WRITE_0;
	    }
	  FPGA_WRITE_1;
	}
      else if (b == 255)
	{
	  FPGA_WRITE_1;
	}
    }
#endif

  DBG("%s, ",((in32(GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" );
  DBG("%s\n",((in32(GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" );

  /*
   * Check if fpga's DONE signal - correctly booted ?
   */

  /* Wait for FPGA end of programming period .  */
  count = 0;
  while (!(in32(GPIO0_IR) & FPGA_DONE))
    {
      udelay(1000); /* wait 1ms */
      /* Check for timeout */
      if (count++ > 3)
	{
	  DBG("FPGA: Booting failed!\n");
	  return ERROR_FPGA_PRG_DONE;
	}
    }

  DBG("FPGA: Booting successful!\n");
  return 0;
}
