uboot/board/esd/common/fpga.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001-2004
   3 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
   4 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24
  25#include <common.h>
  26#include <asm/processor.h>
  27#include <asm/io.h>
  28#include <command.h>
  29
  30/* ------------------------------------------------------------------------- */
  31
  32#ifdef FPGA_DEBUG
  33#define DBG(x...) printf(x)
  34#else
  35#define DBG(x...)
  36#endif /* DEBUG */
  37
  38#define MAX_ONES               226
  39
  40#ifdef CONFIG_SYS_FPGA_PRG
  41# define FPGA_PRG              CONFIG_SYS_FPGA_PRG      /* FPGA program pin (ppc output) */
  42# define FPGA_CLK              CONFIG_SYS_FPGA_CLK      /* FPGA clk pin (ppc output)    */
  43# define FPGA_DATA             CONFIG_SYS_FPGA_DATA     /* FPGA data pin (ppc output)  */
  44# define FPGA_DONE             CONFIG_SYS_FPGA_DONE     /* FPGA done pin (ppc input)   */
  45# define FPGA_INIT             CONFIG_SYS_FPGA_INIT     /* FPGA init pin (ppc input)   */
  46#else
  47# define FPGA_PRG              0x04000000       /* FPGA program pin (ppc output) */
  48# define FPGA_CLK              0x02000000       /* FPGA clk pin (ppc output)     */
  49# define FPGA_DATA             0x01000000       /* FPGA data pin (ppc output)    */
  50# define FPGA_DONE             0x00800000       /* FPGA done pin (ppc input)     */
  51# define FPGA_INIT             0x00400000       /* FPGA init pin (ppc input)     */
  52#endif
  53
  54#define ERROR_FPGA_PRG_INIT_LOW  -1     /* Timeout after PRG* asserted   */
  55#define ERROR_FPGA_PRG_INIT_HIGH -2     /* Timeout after PRG* deasserted */
  56#define ERROR_FPGA_PRG_DONE      -3     /* Timeout after programming     */
  57
  58#ifndef SET_FPGA
  59# define SET_FPGA(data)         out_be32((void *)GPIO0_OR, data)
  60#endif
  61
  62#ifdef FPGA_PROG_ACTIVE_HIGH
  63# define FPGA_PRG_LOW           FPGA_PRG
  64# define FPGA_PRG_HIGH          0
  65#else
  66# define FPGA_PRG_LOW           0
  67# define FPGA_PRG_HIGH          FPGA_PRG
  68#endif
  69
  70#define FPGA_CLK_LOW            0
  71#define FPGA_CLK_HIGH           FPGA_CLK
  72
  73#define FPGA_DATA_LOW           0
  74#define FPGA_DATA_HIGH          FPGA_DATA
  75
  76#define FPGA_WRITE_1 {                                                                   \
  77        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set clock to 0 */  \
  78        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set data to 1  */  \
  79        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);  /* set clock to 1 */  \
  80        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);}      /* set data to 1  */
  81
  82#define FPGA_WRITE_0 {                                                    \
  83        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set clock to 0 */  \
  84        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_LOW);   /* set data to 0  */  \
  85        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_LOW);   /* set clock to 1 */  \
  86        SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);}      /* set data to 1  */
  87
  88#ifndef FPGA_DONE_STATE
  89# define FPGA_DONE_STATE (in_be32((void *)GPIO0_IR) & FPGA_DONE)
  90#endif
  91#ifndef FPGA_INIT_STATE
  92# define FPGA_INIT_STATE (in_be32((void *)GPIO0_IR) & FPGA_INIT)
  93#endif
  94
  95
  96static int fpga_boot (const unsigned char *fpgadata, int size)
  97{
  98        int i, index, len;
  99        int count;
 100        unsigned char b;
 101
 102#ifdef CONFIG_SYS_FPGA_SPARTAN2
 103        int j;
 104#else
 105        int bit;
 106#endif
 107
 108        /* display infos on fpgaimage */
 109        index = 15;
 110        for (i = 0; i < 4; i++) {
 111                len = fpgadata[index];
 112                DBG ("FPGA: %s\n", &(fpgadata[index + 1]));
 113                index += len + 3;
 114        }
 115
 116#ifdef CONFIG_SYS_FPGA_SPARTAN2
 117        /* search for preamble 0xFFFFFFFF */
 118        while (1) {
 119                if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff)
 120                    && (fpgadata[index + 2] == 0xff)
 121                    && (fpgadata[index + 3] == 0xff))
 122                        break;  /* preamble found */
 123                else
 124                        index++;
 125        }
 126#else
 127        /* search for preamble 0xFF2X */
 128        for (index = 0; index < size - 1; index++) {
 129                if ((fpgadata[index] == 0xff)
 130                    && ((fpgadata[index + 1] & 0xf0) == 0x30))
 131                        break;
 132        }
 133        index += 2;
 134#endif
 135
 136        DBG ("FPGA: configdata starts at position 0x%x\n", index);
 137        DBG ("FPGA: length of fpga-data %d\n", size - index);
 138
 139        /*
 140         * Setup port pins for fpga programming
 141         */
 142#ifndef CONFIG_M5249
 143        out_be32 ((void *)GPIO0_ODR, 0x00000000); /* no open drain pins */
 144        /* setup for output */
 145        out_be32 ((void *)GPIO0_TCR,
 146                  in_be32 ((void *)GPIO0_TCR) |
 147                  FPGA_PRG | FPGA_CLK | FPGA_DATA);
 148#endif
 149        SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);      /* set pins to high */
 150
 151        DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
 152        DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
 153
 154        /*
 155         * Init fpga by asserting and deasserting PROGRAM*
 156         */
 157        SET_FPGA (FPGA_PRG_LOW | FPGA_CLK_HIGH | FPGA_DATA_HIGH);       /* set prog active */
 158
 159        /* Wait for FPGA init line low */
 160        count = 0;
 161        while (FPGA_INIT_STATE) {
 162                udelay (1000);  /* wait 1ms */
 163                /* Check for timeout - 100us max, so use 3ms */
 164                if (count++ > 3) {
 165                        DBG ("FPGA: Booting failed!\n");
 166                        return ERROR_FPGA_PRG_INIT_LOW;
 167                }
 168        }
 169
 170        DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
 171        DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
 172
 173        /* deassert PROGRAM* */
 174        SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);      /* set prog inactive */
 175
 176        /* Wait for FPGA end of init period .  */
 177        count = 0;
 178        while (!(FPGA_INIT_STATE)) {
 179                udelay (1000);  /* wait 1ms */
 180                /* Check for timeout */
 181                if (count++ > 3) {
 182                        DBG ("FPGA: Booting failed!\n");
 183                        return ERROR_FPGA_PRG_INIT_HIGH;
 184                }
 185        }
 186
 187        DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
 188        DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
 189
 190        DBG ("write configuration data into fpga\n");
 191        /* write configuration-data into fpga... */
 192
 193#ifdef CONFIG_SYS_FPGA_SPARTAN2
 194        /*
 195         * Load uncompressed image into fpga
 196         */
 197        for (i = index; i < size; i++) {
 198                b = fpgadata[i];
 199                for (j = 0; j < 8; j++) {
 200                        if ((b & 0x80) == 0x80) {
 201                                FPGA_WRITE_1;
 202                        } else {
 203                                FPGA_WRITE_0;
 204                        }
 205                        b <<= 1;
 206                }
 207        }
 208#else
 209        /* send 0xff 0x20 */
 210        FPGA_WRITE_1;
 211        FPGA_WRITE_1;
 212        FPGA_WRITE_1;
 213        FPGA_WRITE_1;
 214        FPGA_WRITE_1;
 215        FPGA_WRITE_1;
 216        FPGA_WRITE_1;
 217        FPGA_WRITE_1;
 218        FPGA_WRITE_0;
 219        FPGA_WRITE_0;
 220        FPGA_WRITE_1;
 221        FPGA_WRITE_0;
 222        FPGA_WRITE_0;
 223        FPGA_WRITE_0;
 224        FPGA_WRITE_0;
 225        FPGA_WRITE_0;
 226
 227        /*
 228         ** Bit_DeCompression
 229         **   Code 1           .. maxOnes     : n                 '1's followed by '0'
 230         **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0'
 231         **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1'
 232         **        255                        :                   '1'
 233         */
 234
 235        for (i = index; i < size; i++) {
 236                b = fpgadata[i];
 237                if ((b >= 1) && (b <= MAX_ONES)) {
 238                        for (bit = 0; bit < b; bit++) {
 239                                FPGA_WRITE_1;
 240                        }
 241                        FPGA_WRITE_0;
 242                } else if (b == (MAX_ONES + 1)) {
 243                        for (bit = 1; bit < b; bit++) {
 244                                FPGA_WRITE_1;
 245                        }
 246                } else if ((b >= (MAX_ONES + 2)) && (b <= 254)) {
 247                        for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) {
 248                                FPGA_WRITE_0;
 249                        }
 250                        FPGA_WRITE_1;
 251                } else if (b == 255) {
 252                        FPGA_WRITE_1;
 253                }
 254        }
 255#endif
 256
 257        DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
 258        DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
 259
 260        /*
 261         * Check if fpga's DONE signal - correctly booted ?
 262         */
 263
 264        /* Wait for FPGA end of programming period .  */
 265        count = 0;
 266        while (!(FPGA_DONE_STATE)) {
 267                udelay (1000);  /* wait 1ms */
 268                /* Check for timeout */
 269                if (count++ > 3) {
 270                        DBG ("FPGA: Booting failed!\n");
 271                        return ERROR_FPGA_PRG_DONE;
 272                }
 273        }
 274
 275        DBG ("FPGA: Booting successful!\n");
 276        return 0;
 277}
 278