uboot/post/board/lwmon5/fpga.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
   3 *
   4 * Developed for DENX Software Engineering GmbH
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8#include <common.h>
   9
  10/* This test performs testing of FPGA SCRATCH register,
  11 * gets FPGA version and run get_ram_size() on FPGA memory
  12 */
  13
  14#include <post.h>
  15#include <watchdog.h>
  16#include <asm/io.h>
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20#define FPGA_SCRATCH_REG        0xC4000050
  21#define FPGA_VERSION_REG        0xC4000040
  22#define FPGA_RAM_START          0xC4200000
  23#define FPGA_RAM_END            0xC4203FFF
  24#define FPGA_STAT               0xC400000C
  25#define FPGA_BUFFER             0x00800000
  26#define FPGA_RAM_SIZE           (FPGA_RAM_END - FPGA_RAM_START + 1)
  27
  28#if CONFIG_POST & CONFIG_SYS_POST_BSPEC3
  29
  30const static unsigned long pattern[] = {
  31        0xffffffff,
  32        0xaaaaaaaa,
  33        0xcccccccc,
  34        0xf0f0f0f0,
  35        0xff00ff00,
  36        0xffff0000,
  37        0x0000ffff,
  38        0x00ff00ff,
  39        0x0f0f0f0f,
  40        0x33333333,
  41        0x55555555,
  42        0x00000000,
  43};
  44
  45const static unsigned long otherpattern = 0x01234567;
  46
  47static int one_scratch_test(uint value)
  48{
  49        uint read_value;
  50        int ret = 0;
  51
  52        out_be32((void *)FPGA_SCRATCH_REG, value);
  53        /* read other location (protect against data lines capacity) */
  54        ret = in_be16((void *)FPGA_VERSION_REG);
  55        /* verify test pattern */
  56        read_value = in_be32((void *)FPGA_SCRATCH_REG);
  57        if (read_value != value) {
  58                post_log("FPGA SCRATCH test failed write %08X, read %08X\n",
  59                         value, read_value);
  60                ret = -1;
  61        }
  62
  63        return ret;
  64}
  65
  66static int fpga_post_test1(ulong *start, ulong size, ulong val)
  67{
  68        int ret = 0;
  69        ulong i = 0;
  70        ulong *mem = start;
  71        ulong readback;
  72
  73        for (i = 0; i < size / sizeof(ulong); i++) {
  74                mem[i] = val;
  75                if (i % 1024 == 0)
  76                        WATCHDOG_RESET();
  77        }
  78
  79        for (i = 0; i < size / sizeof(ulong); i++) {
  80                readback = mem[i];
  81                if (readback != val) {
  82                        post_log("FPGA Memory error at %08x, "
  83                                 "wrote %08x, read %08x !\n",
  84                                 mem + i, val, readback);
  85                        ret = -1;
  86                        break;
  87                }
  88                if (i % 1024 == 0)
  89                        WATCHDOG_RESET();
  90        }
  91        return ret;
  92}
  93
  94static int fpga_post_test2(ulong *start, ulong size)
  95{
  96        int ret = 0;
  97        ulong i = 0;
  98        ulong *mem = start;
  99        ulong readback;
 100
 101        for (i = 0; i < size / sizeof(ulong); i++) {
 102                mem[i] = 1 << (i % 32);
 103                if (i % 1024 == 0)
 104                        WATCHDOG_RESET();
 105        }
 106
 107        for (i = 0; i < size / sizeof(ulong); i++) {
 108                readback = mem[i];
 109                if (readback != 1 << (i % 32)) {
 110                        post_log("FPGA Memory error at %08x, "
 111                                 "wrote %08x, read %08x !\n",
 112                                 mem + i, 1 << (i % 32), readback);
 113                        ret = -1;
 114                        break;
 115                }
 116                if (i % 1024 == 0)
 117                        WATCHDOG_RESET();
 118        }
 119
 120        return ret;
 121}
 122
 123static int fpga_post_test3(ulong *start, ulong size)
 124{
 125        int ret = 0;
 126        ulong i = 0;
 127        ulong *mem = start;
 128        ulong readback;
 129
 130        for (i = 0; i < size / sizeof(ulong); i++) {
 131                mem[i] = i;
 132                if (i % 1024 == 0)
 133                        WATCHDOG_RESET();
 134        }
 135
 136        for (i = 0; i < size / sizeof(ulong); i++) {
 137                readback = mem[i];
 138                if (readback != i) {
 139                        post_log("FPGA Memory error at %08x, "
 140                                 "wrote %08x, read %08x !\n",
 141                                 mem + i, i, readback);
 142                        ret = -1;
 143                        break;
 144                }
 145                if (i % 1024 == 0)
 146                        WATCHDOG_RESET();
 147        }
 148
 149        return ret;
 150}
 151
 152static int fpga_post_test4(ulong *start, ulong size)
 153{
 154        int ret = 0;
 155        ulong i = 0;
 156        ulong *mem = start;
 157        ulong readback;
 158
 159        for (i = 0; i < size / sizeof(ulong); i++) {
 160                mem[i] = ~i;
 161                if (i % 1024 == 0)
 162                        WATCHDOG_RESET();
 163        }
 164
 165        for (i = 0; i < size / sizeof(ulong); i++) {
 166                readback = mem[i];
 167                if (readback != ~i) {
 168                        post_log("FPGA Memory error at %08x, "
 169                                 "wrote %08x, read %08x !\n",
 170                                 mem + i, ~i, readback);
 171                        ret = -1;
 172                        break;
 173                }
 174                if (i % 1024 == 0)
 175                        WATCHDOG_RESET();
 176        }
 177
 178        return ret;
 179}
 180
 181/* FPGA Memory-pattern-test */
 182static int fpga_mem_test(void)
 183{
 184        int ret = 0;
 185        ulong* start = (ulong *)FPGA_RAM_START;
 186        ulong  size  = FPGA_RAM_SIZE;
 187
 188        if (ret == 0)
 189                ret = fpga_post_test1(start, size, 0x00000000);
 190
 191        if (ret == 0)
 192                ret = fpga_post_test1(start, size, 0xffffffff);
 193
 194        if (ret == 0)
 195                ret = fpga_post_test1(start, size, 0x55555555);
 196
 197        if (ret == 0)
 198                ret = fpga_post_test1(start, size, 0xaaaaaaaa);
 199
 200        WATCHDOG_RESET();
 201
 202        if (ret == 0)
 203                ret = fpga_post_test2(start, size);
 204
 205        if (ret == 0)
 206                ret = fpga_post_test3(start, size);
 207
 208        if (ret == 0)
 209                ret = fpga_post_test4(start, size);
 210
 211        return ret;
 212}
 213
 214/* Verify FPGA addresslines */
 215static int fpga_post_addrline(ulong *address, ulong *base, ulong size)
 216{
 217        unsigned long *target;
 218        unsigned long *end;
 219        unsigned long readback;
 220        unsigned long xor;
 221        int ret = 0;
 222
 223        end = (ulong *)((ulong)base + size);
 224        xor = 0;
 225
 226        for (xor = sizeof(ulong); xor > 0; xor <<= 1) {
 227                target = (ulong*)((ulong)address ^ xor);
 228                if ((target >= base) && (target < end)) {
 229                        *address = ~*target;
 230                        readback = *target;
 231
 232                        if (readback == *address) {
 233                                post_log("Memory (address line) error at %08x"
 234                                         "XOR value %08x !\n",
 235                                         address, target, xor);
 236                                ret = -1;
 237                                break;
 238                        }
 239                }
 240        }
 241
 242        return ret;
 243}
 244
 245/* Verify FPGA addresslines */
 246static int fpga_post_dataline(ulong *address)
 247{
 248        unsigned long temp32 = 0;
 249        int i = 0;
 250        int ret = 0;
 251
 252        for (i = 0; i < ARRAY_SIZE(pattern); i++) {
 253                *address = pattern[i];
 254                /*
 255                 * Put a different pattern on the data lines: otherwise they
 256                 * may float long enough to read back what we wrote.
 257                 */
 258                *(address + 1) = otherpattern;
 259                temp32 = *address;
 260
 261                if (temp32 != pattern[i]){
 262                        post_log("Memory (date line) error at %08x, "
 263                                 "wrote %08x, read %08x !\n",
 264                                 address, pattern[i], temp32);
 265                        ret = 1;
 266                }
 267        }
 268
 269        return ret;
 270}
 271
 272/* Verify FPGA, get version & memory size */
 273int fpga_post_test(int flags)
 274{
 275        uint   old_value;
 276        uint   version;
 277        uint   read_value;
 278        int    ret = 0;
 279
 280        post_log("\n");
 281        old_value = in_be32((void *)FPGA_SCRATCH_REG);
 282
 283        if (one_scratch_test(0x55555555))
 284                ret = 1;
 285        if (one_scratch_test(0xAAAAAAAA))
 286                ret = 1;
 287
 288        out_be32((void *)FPGA_SCRATCH_REG, old_value);
 289
 290        version = in_be32((void *)FPGA_VERSION_REG);
 291        post_log("FPGA version %u.%u\n",
 292                 (version >> 8) & 0xFF, version & 0xFF);
 293
 294        /* Enable write to FPGA RAM */
 295        out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000);
 296
 297        /* get RAM size */
 298        read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE);
 299        post_log("FPGA RAM size %d bytes\n", read_value);
 300        WATCHDOG_RESET();
 301
 302        /* copy fpga memory to DDR2 RAM*/
 303        memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE);
 304        WATCHDOG_RESET();
 305
 306        /* Test datalines */
 307        if (fpga_post_dataline((ulong *)FPGA_RAM_START)) {
 308                ret = 1;
 309                goto out;
 310        }
 311        WATCHDOG_RESET();
 312
 313        /* Test addresslines */
 314        if (fpga_post_addrline((ulong *)FPGA_RAM_START,
 315                               (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
 316                ret = 1;
 317                goto out;
 318        }
 319        WATCHDOG_RESET();
 320        if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long),
 321                               (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
 322                ret = 1;
 323                goto out;
 324        }
 325        WATCHDOG_RESET();
 326
 327        /* Memory Pattern Test */
 328        if (fpga_mem_test()) {
 329                ret = 1;
 330                goto out;
 331        }
 332        WATCHDOG_RESET();
 333
 334        /* restore memory */
 335        memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE);
 336        WATCHDOG_RESET();
 337
 338out:
 339        /* Disable write to RAM */
 340        out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);
 341        return ret;
 342}
 343
 344#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC3 */
 345