summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndrey Smirnov <andrew.smirnov@gmail.com>2015-02-17 20:54:40 -0800
committerSascha Hauer <s.hauer@pengutronix.de>2015-02-19 20:50:19 +0100
commit79b40a630d6e28a7453eedbe7a0b96084d678e29 (patch)
treed28614abbba8cd3993dbb101f1c0b8fcf63c24a1 /drivers
parentacc69bdddc50262b8f91034c248279d8dc734284 (diff)
downloadbarebox-79b40a630d6e28a7453eedbe7a0b96084d678e29.tar.gz
barebox-79b40a630d6e28a7453eedbe7a0b96084d678e29.tar.xz
firmware: altera: Make nSTAT GPIO optional
By taking parts of the programming handshaking protocol on faith it is possible to make due with only two GPIO for programming Altera FPGAs. This is not a very advisable practice, but sometime unavoidable in GPIO constrained designs. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firmware/altera_serial.c59
1 files changed, 44 insertions, 15 deletions
diff --git a/drivers/firmware/altera_serial.c b/drivers/firmware/altera_serial.c
index c5ffbb6393..4527d27c5c 100644
--- a/drivers/firmware/altera_serial.c
+++ b/drivers/firmware/altera_serial.c
@@ -25,6 +25,7 @@
#include <fcntl.h>
#include <fs.h>
+
/*
* Physical requirements:
* - three free GPIOs for the signals nCONFIG, CONFIGURE_DONE, nSTATUS
@@ -67,13 +68,19 @@ static int altera_spi_open(struct firmware_handler *fh)
* after about 2 µs the FPGA must acknowledge with
* STATUS and CONFIG DONE lines at low level
*/
- ret = wait_on_timeout(2 * USECOND,
+ if (gpio_is_valid(this->nstat_gpio)) {
+ ret = wait_on_timeout(2 * USECOND,
(gpio_get_value(this->nstat_gpio) == 0) &&
(gpio_get_value(this->confd_gpio) == 0));
+ } else {
+ ret = wait_on_timeout(2 * USECOND,
+ (gpio_get_value(this->confd_gpio) == 0));
+ }
+
if (ret != 0) {
dev_err(dev, "FPGA does not acknowledge the programming initiation\n");
- if (gpio_get_value(this->nstat_gpio))
+ if (gpio_is_valid(this->nstat_gpio) && gpio_get_value(this->nstat_gpio))
dev_err(dev, "STATUS is still high!\n");
if (gpio_get_value(this->confd_gpio))
dev_err(dev, "CONFIG DONE is still high!\n");
@@ -90,11 +97,16 @@ static int altera_spi_open(struct firmware_handler *fh)
* after about 1506 µs the FPGA must acknowledge this step
* with the STATUS line at high level
*/
- ret = wait_on_timeout(1600 * USECOND,
+
+ if (gpio_is_valid(this->nstat_gpio)) {
+ ret = wait_on_timeout(1600 * USECOND,
gpio_get_value(this->nstat_gpio) == 1);
- if (ret != 0) {
- dev_err(dev, "FPGA does not acknowledge the programming start\n");
- return ret;
+ if (ret != 0) {
+ dev_err(dev, "FPGA does not acknowledge the programming start\n");
+ return ret;
+ }
+ } else {
+ udelay(1600);
}
dev_dbg(dev, "Initiating passed\n");
@@ -177,16 +189,24 @@ static int altera_spi_close(struct firmware_handler *fh)
* when programming was successful,
* both status lines should be at high level
*/
- ret = wait_on_timeout(10 * USECOND,
+ if (gpio_is_valid(this->nstat_gpio)) {
+ ret = wait_on_timeout(10 * USECOND,
(gpio_get_value(this->nstat_gpio) == 1) &&
(gpio_get_value(this->confd_gpio) == 1));
+ } else {
+ ret = wait_on_timeout(10 * USECOND,
+ (gpio_get_value(this->confd_gpio) == 1));
+
+ }
+
if (ret == 0) {
dev_dbg(dev, "Programming successful\n");
return ret;
}
dev_err(dev, "Programming failed due to time out\n");
- if (gpio_get_value(this->nstat_gpio) == 0)
+ if (gpio_is_valid(this->nstat_gpio) &&
+ gpio_get_value(this->nstat_gpio) == 0)
dev_err(dev, "STATUS is still low!\n");
if (gpio_get_value(this->confd_gpio) == 0)
dev_err(dev, "CONFIG DONE is still low!\n");
@@ -201,10 +221,15 @@ static int altera_spi_of(struct device_d *dev, struct fpga_spi *this)
int ret;
name = "nstat-gpio";
- this->nstat_gpio = of_get_named_gpio(n, name, 0);
- if (this->nstat_gpio < 0) {
- ret = this->nstat_gpio;
- goto out;
+ if (!of_get_property(n, name, NULL)) {
+ dev_info(dev, "nstat-gpio is not specified, assuming it is not connected\n");
+ this->nstat_gpio = -1;
+ } else {
+ this->nstat_gpio = of_get_named_gpio(n, name, 0);
+ if (this->nstat_gpio < 0) {
+ ret = this->nstat_gpio;
+ goto out;
+ }
}
name = "confd-gpio";
@@ -225,9 +250,13 @@ static int altera_spi_of(struct device_d *dev, struct fpga_spi *this)
ret = gpio_direction_output(this->nconfig_gpio, 1);
if (ret)
return ret;
- ret = gpio_direction_input(this->nstat_gpio);
- if (ret)
- return ret;
+
+ if (gpio_is_valid(this->nstat_gpio)) {
+ ret = gpio_direction_input(this->nstat_gpio);
+ if (ret)
+ return ret;
+ }
+
ret = gpio_direction_input(this->confd_gpio);
if (ret)
return ret;