mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-21 17:38:51 +09:00
![Tom Rini](/assets/img/avatar_default.png)
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
179 lines
4.0 KiB
C
179 lines
4.0 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2016 Stefan Roese <sr@denx.de>
|
|
*/
|
|
|
|
#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\n",
|
|
__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\n",
|
|
__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\n",
|
|
__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\n",
|
|
__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]);
|
|
}
|