uboot/drivers/fpga/stratixv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2016 Stefan Roese <sr@denx.de>
   4 */
   5
   6#include <common.h>
   7#include <altera.h>
   8#include <spi.h>
   9#include <asm/io.h>
  10#include <linux/errno.h>
  11
  12/* Write the RBF data to FPGA via SPI */
  13static int program_write(int spi_bus, int spi_dev, const void *rbf_data,
  14                         unsigned long rbf_size)
  15{
  16        struct spi_slave *slave;
  17        int ret;
  18
  19        debug("%s (%d): data=%p size=%ld\n",
  20              __func__, __LINE__, rbf_data, rbf_size);
  21
  22        /* FIXME: How to get the max. SPI clock and SPI mode? */
  23        slave = spi_setup_slave(spi_bus, spi_dev, 27777777, SPI_MODE_3);
  24        if (!slave)
  25                return -1;
  26
  27        if (spi_claim_bus(slave))
  28                return -1;
  29
  30        ret = spi_xfer(slave, rbf_size * 8, rbf_data, (void *)rbf_data,
  31                       SPI_XFER_BEGIN | SPI_XFER_END);
  32
  33        spi_release_bus(slave);
  34
  35        return ret;
  36}
  37
  38/*
  39 * This is the interface used by FPGA driver.
  40 * Return 0 for sucess, non-zero for error.
  41 */
  42int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
  43{
  44        altera_board_specific_func *pfns = desc->iface_fns;
  45        int cookie = desc->cookie;
  46        int spi_bus;
  47        int spi_dev;
  48        int ret = 0;
  49
  50        if ((u32)rbf_data & 0x3) {
  51                puts("FPGA: Unaligned data, realign to 32bit boundary.\n");
  52                return -EINVAL;
  53        }
  54
  55        /* Run the pre configuration function if there is one */
  56        if (pfns->pre)
  57                (pfns->pre)(cookie);
  58
  59        /* Establish the initial state */
  60        if (pfns->config) {
  61                /* De-assert nCONFIG */
  62                (pfns->config)(false, true, cookie);
  63
  64                /* nConfig minimum low pulse width is 2us */
  65                udelay(200);
  66
  67                /* Assert nCONFIG */
  68                (pfns->config)(true, true, cookie);
  69
  70                /* nCONFIG high to first rising clock on DCLK min 1506 us */
  71                udelay(1600);
  72        }
  73
  74        /* Write the RBF data to FPGA */
  75        if (pfns->write) {
  76                /*
  77                 * Use board specific data function to write bitstream
  78                 * into the FPGA
  79                 */
  80                ret = (pfns->write)(rbf_data, rbf_size, true, cookie);
  81        } else {
  82                /*
  83                 * Use common SPI functions to write bitstream into the
  84                 * FPGA
  85                 */
  86                spi_bus = COOKIE2SPI_BUS(cookie);
  87                spi_dev = COOKIE2SPI_DEV(cookie);
  88                ret = program_write(spi_bus, spi_dev, rbf_data, rbf_size);
  89        }
  90        if (ret)
  91                return ret;
  92
  93        /* Check done pin */
  94        if (pfns->done) {
  95                ret = (pfns->done)(cookie);
  96
  97                if (ret)
  98                        printf("Error: DONE not set (ret=%d)!\n", ret);
  99        }
 100
 101        return ret;
 102}
 103