Blame view
board/theadorable/fpga.c
4.03 KB
d41ce506b Initial Release, ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
/* * Copyright (C) 2016 Stefan Roese <sr@denx.de> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <altera.h> #include <errno.h> #include <asm/gpio.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/soc.h> #include <asm/arch-mvebu/spi.h> #include "theadorable.h" /* * FPGA programming support */ static int fpga_pre_fn(int cookie) { int gpio_config = COOKIE2CONFIG(cookie); int gpio_done = COOKIE2DONE(cookie); int ret; debug("%s (%d): cookie=%08x gpio_config=%d gpio_done=%d ", __func__, __LINE__, cookie, gpio_config, gpio_done); /* Configure config pin */ /* Set to output */ ret = gpio_request(gpio_config, "CONFIG"); if (ret < 0) return ret; gpio_direction_output(gpio_config, 1); /* Configure done pin */ /* Set to input */ ret = gpio_request(gpio_done, "DONE"); if (ret < 0) return ret; gpio_direction_input(gpio_done); return 0; } static int fpga_config_fn(int assert, int flush, int cookie) { int gpio_config = COOKIE2CONFIG(cookie); debug("%s (%d): cookie=%08x gpio_config=%d ", __func__, __LINE__, cookie, gpio_config); if (assert) gpio_set_value(gpio_config, 1); else gpio_set_value(gpio_config, 0); return 0; } static int fpga_write_fn(const void *buf, size_t len, int flush, int cookie) { int spi_bus = COOKIE2SPI_BUS(cookie); int spi_dev = COOKIE2SPI_DEV(cookie); struct kwspi_registers *reg; u32 control_reg; u32 config_reg; void *dst; /* * Write data to FPGA attached to SPI bus via SPI direct write. * This results in the fastest and easiest way to program the * bitstream into the FPGA. */ debug("%s (%d): cookie=%08x spi_bus=%d spi_dev=%d ", __func__, __LINE__, cookie, spi_bus, spi_dev); if (spi_bus == 0) { reg = (struct kwspi_registers *)MVEBU_REGISTER(0x10600); dst = (void *)SPI_BUS0_DEV1_BASE; } else { reg = (struct kwspi_registers *)MVEBU_REGISTER(0x10680); dst = (void *)SPI_BUS1_DEV2_BASE; } /* Configure SPI controller for direct access mode */ control_reg = readl(®->ctrl); config_reg = readl(®->cfg); writel(0x00000214, ®->cfg); /* 27MHz clock */ writel(0x00000000, ®->dw_cfg); /* don't de-asset CS */ writel(KWSPI_CSN_ACT, ®->ctrl); /* activate CS */ /* Copy data to the SPI direct mapped window */ memcpy(dst, buf, len); /* Restore original register values */ writel(control_reg, ®->ctrl); writel(config_reg, ®->cfg); return 0; } /* Returns the state of CONF_DONE Pin */ static int fpga_done_fn(int cookie) { int gpio_done = COOKIE2DONE(cookie); unsigned long ts; debug("%s (%d): cookie=%08x gpio_done=%d ", __func__, __LINE__, cookie, gpio_done); ts = get_timer(0); do { if (gpio_get_value(gpio_done)) return 0; } while (get_timer(ts) < 1000); /* timeout so return error */ return -ENODEV; } static altera_board_specific_func stratixv_fns = { .pre = fpga_pre_fn, .config = fpga_config_fn, .write = fpga_write_fn, .done = fpga_done_fn, }; static Altera_desc altera_fpga[] = { { /* Family */ Altera_StratixV, /* Interface type */ passive_serial, /* No limitation as additional data will be ignored */ -1, /* Device function table */ (void *)&stratixv_fns, /* Base interface address specified in driver */ NULL, /* Cookie implementation */ /* * In this 32bit word the following information is coded: * Bit 31 ... Bit 0 * SPI-Bus | SPI-Dev | Config-Pin | Done-Pin */ FPGA_COOKIE(0, 1, 26, 7) }, { /* Family */ Altera_StratixV, /* Interface type */ passive_serial, /* No limitation as additional data will be ignored */ -1, /* Device function table */ (void *)&stratixv_fns, /* Base interface address specified in driver */ NULL, /* Cookie implementation */ /* * In this 32bit word the following information is coded: * Bit 31 ... Bit 0 * SPI-Bus | SPI-Dev | Config-Pin | Done-Pin */ FPGA_COOKIE(1, 2, 29, 9) }, }; /* Add device descriptor to FPGA device table */ void board_fpga_add(void) { int i; fpga_init(); for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) fpga_add(fpga_altera, &altera_fpga[i]); } |