uboot/drivers/fpga/fpga.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2002
   4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
   5 */
   6
   7/* Generic FPGA support */
   8#include <common.h>             /* core U-Boot definitions */
   9#include <init.h>
  10#include <log.h>
  11#include <xilinx.h>             /* xilinx specific definitions */
  12#include <altera.h>             /* altera specific definitions */
  13#include <lattice.h>
  14#include <dm/device_compat.h>
  15
  16/* Local definitions */
  17#ifndef CONFIG_MAX_FPGA_DEVICES
  18#define CONFIG_MAX_FPGA_DEVICES         5
  19#endif
  20
  21/* Local static data */
  22static int next_desc = FPGA_INVALID_DEVICE;
  23static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
  24
  25/*
  26 * fpga_no_sup
  27 * 'no support' message function
  28 */
  29static void fpga_no_sup(char *fn, char *msg)
  30{
  31        if (fn && msg)
  32                printf("%s: No support for %s.\n", fn, msg);
  33        else if (msg)
  34                printf("No support for %s.\n", msg);
  35        else
  36                printf("No FPGA support!\n");
  37}
  38
  39
  40/* fpga_get_desc
  41 *      map a device number to a descriptor
  42 */
  43const fpga_desc *const fpga_get_desc(int devnum)
  44{
  45        fpga_desc *desc = (fpga_desc *)NULL;
  46
  47        if ((devnum >= 0) && (devnum < next_desc)) {
  48                desc = &desc_table[devnum];
  49                debug("%s: found fpga descriptor #%d @ 0x%p\n",
  50                      __func__, devnum, desc);
  51        }
  52
  53        return desc;
  54}
  55
  56/*
  57 * fpga_validate
  58 *      generic parameter checking code
  59 */
  60const fpga_desc *const fpga_validate(int devnum, const void *buf,
  61                                     size_t bsize, char *fn)
  62{
  63        const fpga_desc *desc = fpga_get_desc(devnum);
  64
  65        if (!desc)
  66                printf("%s: Invalid device number %d\n", fn, devnum);
  67
  68        if (!buf) {
  69                printf("%s: Null buffer.\n", fn);
  70                return (fpga_desc * const)NULL;
  71        }
  72        return desc;
  73}
  74
  75/*
  76 * fpga_dev_info
  77 *      generic multiplexing code
  78 */
  79static int fpga_dev_info(int devnum)
  80{
  81        int ret_val = FPGA_FAIL; /* assume failure */
  82        const fpga_desc * const desc = fpga_get_desc(devnum);
  83
  84        if (desc) {
  85                debug("%s: Device Descriptor @ 0x%p\n",
  86                      __func__, desc->devdesc);
  87
  88                switch (desc->devtype) {
  89                case fpga_xilinx:
  90#if defined(CONFIG_FPGA_XILINX)
  91                        printf("Xilinx Device\nDescriptor @ 0x%p\n", desc);
  92                        ret_val = xilinx_info(desc->devdesc);
  93#else
  94                        fpga_no_sup((char *)__func__, "Xilinx devices");
  95#endif
  96                        break;
  97                case fpga_altera:
  98#if defined(CONFIG_FPGA_ALTERA)
  99                        printf("Altera Device\nDescriptor @ 0x%p\n", desc);
 100                        ret_val = altera_info(desc->devdesc);
 101#else
 102                        fpga_no_sup((char *)__func__, "Altera devices");
 103#endif
 104                        break;
 105                case fpga_lattice:
 106#if defined(CONFIG_FPGA_LATTICE)
 107                        printf("Lattice Device\nDescriptor @ 0x%p\n", desc);
 108                        ret_val = lattice_info(desc->devdesc);
 109#else
 110                        fpga_no_sup((char *)__func__, "Lattice devices");
 111#endif
 112                        break;
 113                default:
 114                        printf("%s: Invalid or unsupported device type %d\n",
 115                               __func__, desc->devtype);
 116                }
 117        } else {
 118                printf("%s: Invalid device number %d\n", __func__, devnum);
 119        }
 120
 121        return ret_val;
 122}
 123
 124/*
 125 * fpga_init is usually called from misc_init_r() and MUST be called
 126 * before any of the other fpga functions are used.
 127 */
 128void fpga_init(void)
 129{
 130        next_desc = 0;
 131        memset(desc_table, 0, sizeof(desc_table));
 132
 133        debug("%s\n", __func__);
 134}
 135
 136/*
 137 * fpga_count
 138 * Basic interface function to get the current number of devices available.
 139 */
 140int fpga_count(void)
 141{
 142        return next_desc;
 143}
 144
 145/*
 146 * fpga_add
 147 *      Add the device descriptor to the device table.
 148 */
 149int fpga_add(fpga_type devtype, void *desc)
 150{
 151        int devnum = FPGA_INVALID_DEVICE;
 152
 153        if (!desc) {
 154                printf("%s: NULL device descriptor\n", __func__);
 155                return devnum;
 156        }
 157
 158        if (next_desc < 0) {
 159                printf("%s: FPGA support not initialized!\n", __func__);
 160        } else if ((devtype > fpga_min_type) && (devtype < fpga_undefined)) {
 161                if (next_desc < CONFIG_MAX_FPGA_DEVICES) {
 162                        devnum = next_desc;
 163                        desc_table[next_desc].devtype = devtype;
 164                        desc_table[next_desc++].devdesc = desc;
 165                } else {
 166                        printf("%s: Exceeded Max FPGA device count\n",
 167                               __func__);
 168                }
 169        } else {
 170                printf("%s: Unsupported FPGA type %d\n", __func__, devtype);
 171        }
 172
 173        return devnum;
 174}
 175
 176/*
 177 * Return 1 if the fpga data is partial.
 178 * This is only required for fpga drivers that support bitstream_type.
 179 */
 180int __weak fpga_is_partial_data(int devnum, size_t img_len)
 181{
 182        return 0;
 183}
 184
 185/*
 186 * Convert bitstream data and load into the fpga
 187 */
 188int __weak fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
 189                              bitstream_type bstype)
 190{
 191        printf("Bitstream support not implemented for this FPGA device\n");
 192        return FPGA_FAIL;
 193}
 194
 195#if defined(CONFIG_CMD_FPGA_LOADFS)
 196int fpga_fsload(int devnum, const void *buf, size_t size,
 197                 fpga_fs_info *fpga_fsinfo)
 198{
 199        int ret_val = FPGA_FAIL;           /* assume failure */
 200        const fpga_desc *desc = fpga_validate(devnum, buf, size,
 201                                              (char *)__func__);
 202
 203        if (desc) {
 204                switch (desc->devtype) {
 205                case fpga_xilinx:
 206#if defined(CONFIG_FPGA_XILINX)
 207                        ret_val = xilinx_loadfs(desc->devdesc, buf, size,
 208                                                fpga_fsinfo);
 209#else
 210                        fpga_no_sup((char *)__func__, "Xilinx devices");
 211#endif
 212                        break;
 213                default:
 214                        printf("%s: Invalid or unsupported device type %d\n",
 215                               __func__, desc->devtype);
 216                }
 217        }
 218
 219        return ret_val;
 220}
 221#endif
 222
 223#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
 224int fpga_loads(int devnum, const void *buf, size_t size,
 225               struct fpga_secure_info *fpga_sec_info)
 226{
 227        int ret_val = FPGA_FAIL;
 228
 229        const fpga_desc *desc = fpga_validate(devnum, buf, size,
 230                                              (char *)__func__);
 231
 232        if (desc) {
 233                switch (desc->devtype) {
 234                case fpga_xilinx:
 235#if defined(CONFIG_FPGA_XILINX)
 236                        ret_val = xilinx_loads(desc->devdesc, buf, size,
 237                                               fpga_sec_info);
 238#else
 239                        fpga_no_sup((char *)__func__, "Xilinx devices");
 240#endif
 241                        break;
 242                default:
 243                        printf("%s: Invalid or unsupported device type %d\n",
 244                               __func__, desc->devtype);
 245                }
 246        }
 247
 248        return ret_val;
 249}
 250#endif
 251
 252/*
 253 * Generic multiplexing code
 254 */
 255int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype)
 256{
 257        int ret_val = FPGA_FAIL;           /* assume failure */
 258        const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
 259                                              (char *)__func__);
 260
 261        if (desc) {
 262                switch (desc->devtype) {
 263                case fpga_xilinx:
 264#if defined(CONFIG_FPGA_XILINX)
 265                        ret_val = xilinx_load(desc->devdesc, buf, bsize,
 266                                              bstype);
 267#else
 268                        fpga_no_sup((char *)__func__, "Xilinx devices");
 269#endif
 270                        break;
 271                case fpga_altera:
 272#if defined(CONFIG_FPGA_ALTERA)
 273                        ret_val = altera_load(desc->devdesc, buf, bsize);
 274#else
 275                        fpga_no_sup((char *)__func__, "Altera devices");
 276#endif
 277                        break;
 278                case fpga_lattice:
 279#if defined(CONFIG_FPGA_LATTICE)
 280                        ret_val = lattice_load(desc->devdesc, buf, bsize);
 281#else
 282                        fpga_no_sup((char *)__func__, "Lattice devices");
 283#endif
 284                        break;
 285                default:
 286                        printf("%s: Invalid or unsupported device type %d\n",
 287                               __func__, desc->devtype);
 288                }
 289        }
 290
 291        return ret_val;
 292}
 293
 294/*
 295 * fpga_dump
 296 *      generic multiplexing code
 297 */
 298int fpga_dump(int devnum, const void *buf, size_t bsize)
 299{
 300        int ret_val = FPGA_FAIL;           /* assume failure */
 301        const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
 302                                              (char *)__func__);
 303
 304        if (desc) {
 305                switch (desc->devtype) {
 306                case fpga_xilinx:
 307#if defined(CONFIG_FPGA_XILINX)
 308                        ret_val = xilinx_dump(desc->devdesc, buf, bsize);
 309#else
 310                        fpga_no_sup((char *)__func__, "Xilinx devices");
 311#endif
 312                        break;
 313                case fpga_altera:
 314#if defined(CONFIG_FPGA_ALTERA)
 315                        ret_val = altera_dump(desc->devdesc, buf, bsize);
 316#else
 317                        fpga_no_sup((char *)__func__, "Altera devices");
 318#endif
 319                        break;
 320                case fpga_lattice:
 321#if defined(CONFIG_FPGA_LATTICE)
 322                        ret_val = lattice_dump(desc->devdesc, buf, bsize);
 323#else
 324                        fpga_no_sup((char *)__func__, "Lattice devices");
 325#endif
 326                        break;
 327                default:
 328                        printf("%s: Invalid or unsupported device type %d\n",
 329                               __func__, desc->devtype);
 330                }
 331        }
 332
 333        return ret_val;
 334}
 335
 336/*
 337 * fpga_info
 338 *      front end to fpga_dev_info.  If devnum is invalid, report on all
 339 *      available devices.
 340 */
 341int fpga_info(int devnum)
 342{
 343        if (devnum == FPGA_INVALID_DEVICE) {
 344                if (next_desc > 0) {
 345                        int dev;
 346
 347                        for (dev = 0; dev < next_desc; dev++)
 348                                fpga_dev_info(dev);
 349
 350                        return FPGA_SUCCESS;
 351                } else {
 352                        printf("%s: No FPGA devices available.\n", __func__);
 353                        return FPGA_FAIL;
 354                }
 355        }
 356
 357        return fpga_dev_info(devnum);
 358}
 359