1 // SPDX-License-Identifier: GPL-2.0-only
3 * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers.
5 * Copyright (C) 2017 DENX Software Engineering
7 * Anatolij Gustschin <agust@denx.de>
10 #include "xilinx-core.h"
12 #include <linux/delay.h>
13 #include <linux/fpga/fpga-mgr.h>
14 #include <linux/gpio/consumer.h>
17 static int get_done_gpio(struct fpga_manager
*mgr
)
19 struct xilinx_fpga_core
*core
= mgr
->priv
;
22 ret
= gpiod_get_value(core
->done
);
24 dev_err(&mgr
->dev
, "Error reading DONE (%d)\n", ret
);
29 static enum fpga_mgr_states
xilinx_core_state(struct fpga_manager
*mgr
)
31 if (!get_done_gpio(mgr
))
32 return FPGA_MGR_STATE_RESET
;
34 return FPGA_MGR_STATE_UNKNOWN
;
38 * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
39 * a given delay if the pin is unavailable
41 * @mgr: The FPGA manager object
42 * @value: Value INIT_B to wait for (1 = asserted = low)
43 * @alt_udelay: Delay to wait if the INIT_B GPIO is not available
45 * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
46 * too much time passed waiting for that. If no INIT_B GPIO is available
47 * then always return 0.
49 static int wait_for_init_b(struct fpga_manager
*mgr
, int value
,
50 unsigned long alt_udelay
)
52 struct xilinx_fpga_core
*core
= mgr
->priv
;
53 unsigned long timeout
= jiffies
+ msecs_to_jiffies(1000);
56 while (time_before(jiffies
, timeout
)) {
57 int ret
= gpiod_get_value(core
->init_b
);
64 "Error reading INIT_B (%d)\n", ret
);
68 usleep_range(100, 400);
71 dev_err(&mgr
->dev
, "Timeout waiting for INIT_B to %s\n",
72 value
? "assert" : "deassert");
81 static int xilinx_core_write_init(struct fpga_manager
*mgr
,
82 struct fpga_image_info
*info
, const char *buf
,
85 struct xilinx_fpga_core
*core
= mgr
->priv
;
88 if (info
->flags
& FPGA_MGR_PARTIAL_RECONFIG
) {
89 dev_err(&mgr
->dev
, "Partial reconfiguration not supported\n");
93 gpiod_set_value(core
->prog_b
, 1);
95 err
= wait_for_init_b(mgr
, 1, 1); /* min is 500 ns */
97 gpiod_set_value(core
->prog_b
, 0);
101 gpiod_set_value(core
->prog_b
, 0);
103 err
= wait_for_init_b(mgr
, 0, 0);
107 if (get_done_gpio(mgr
)) {
108 dev_err(&mgr
->dev
, "Unexpected DONE pin state...\n");
112 /* program latency */
113 usleep_range(7500, 7600);
117 static int xilinx_core_write(struct fpga_manager
*mgr
, const char *buf
,
120 struct xilinx_fpga_core
*core
= mgr
->priv
;
122 return core
->write(core
, buf
, count
);
125 static int xilinx_core_write_complete(struct fpga_manager
*mgr
,
126 struct fpga_image_info
*info
)
128 struct xilinx_fpga_core
*core
= mgr
->priv
;
129 unsigned long timeout
=
130 jiffies
+ usecs_to_jiffies(info
->config_complete_timeout_us
);
131 bool expired
= false;
134 const char padding
[1] = { 0xff };
137 * This loop is carefully written such that if the driver is
138 * scheduled out for more than 'timeout', we still check for DONE
139 * before giving up and we apply 8 extra CCLK cycles in all cases.
142 expired
= time_after(jiffies
, timeout
);
144 done
= get_done_gpio(mgr
);
148 ret
= core
->write(core
, padding
, sizeof(padding
));
157 ret
= gpiod_get_value(core
->init_b
);
160 dev_err(&mgr
->dev
, "Error reading INIT_B (%d)\n", ret
);
165 ret
? "CRC error or invalid device\n" :
166 "Missing sync word or incomplete bitstream\n");
168 dev_err(&mgr
->dev
, "Timeout after config data transfer\n");
174 static inline struct gpio_desc
*
175 xilinx_core_devm_gpiod_get(struct device
*dev
, const char *con_id
,
176 const char *legacy_con_id
, enum gpiod_flags flags
)
178 struct gpio_desc
*desc
;
180 desc
= devm_gpiod_get(dev
, con_id
, flags
);
181 if (IS_ERR(desc
) && PTR_ERR(desc
) == -ENOENT
&&
182 of_device_is_compatible(dev
->of_node
, "xlnx,fpga-slave-serial"))
183 desc
= devm_gpiod_get(dev
, legacy_con_id
, flags
);
188 static const struct fpga_manager_ops xilinx_core_ops
= {
189 .state
= xilinx_core_state
,
190 .write_init
= xilinx_core_write_init
,
191 .write
= xilinx_core_write
,
192 .write_complete
= xilinx_core_write_complete
,
195 int xilinx_core_probe(struct xilinx_fpga_core
*core
)
197 struct fpga_manager
*mgr
;
199 if (!core
|| !core
->dev
|| !core
->write
)
202 /* PROGRAM_B is active low */
203 core
->prog_b
= xilinx_core_devm_gpiod_get(core
->dev
, "prog", "prog_b",
205 if (IS_ERR(core
->prog_b
))
206 return dev_err_probe(core
->dev
, PTR_ERR(core
->prog_b
),
207 "Failed to get PROGRAM_B gpio\n");
209 core
->init_b
= xilinx_core_devm_gpiod_get(core
->dev
, "init", "init-b",
211 if (IS_ERR(core
->init_b
))
212 return dev_err_probe(core
->dev
, PTR_ERR(core
->init_b
),
213 "Failed to get INIT_B gpio\n");
215 core
->done
= devm_gpiod_get(core
->dev
, "done", GPIOD_IN
);
216 if (IS_ERR(core
->done
))
217 return dev_err_probe(core
->dev
, PTR_ERR(core
->done
),
218 "Failed to get DONE gpio\n");
220 mgr
= devm_fpga_mgr_register(core
->dev
,
221 "Xilinx Slave Serial FPGA Manager",
222 &xilinx_core_ops
, core
);
223 return PTR_ERR_OR_ZERO(mgr
);
225 EXPORT_SYMBOL_GPL(xilinx_core_probe
);
227 MODULE_LICENSE("GPL");
228 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
229 MODULE_DESCRIPTION("Xilinx 7 Series FPGA manager core");