1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Common parts of the Xilinx Spartan6 and 7 Series FPGA manager drivers. 4 * 5 * Copyright (C) 2017 DENX Software Engineering 6 * 7 * Anatolij Gustschin <agust@denx.de> 8 */ 9 10 #include "xilinx-core.h" 11 12 #include <linux/delay.h> 13 #include <linux/fpga/fpga-mgr.h> 14 #include <linux/gpio/consumer.h> 15 #include <linux/of.h> 16 17 static int get_done_gpio(struct fpga_manager *mgr) 18 { 19 struct xilinx_fpga_core *core = mgr->priv; 20 int ret; 21 22 ret = gpiod_get_value(core->done); 23 if (ret < 0) 24 dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret); 25 26 return ret; 27 } 28 29 static enum fpga_mgr_states xilinx_core_state(struct fpga_manager *mgr) 30 { 31 if (!get_done_gpio(mgr)) 32 return FPGA_MGR_STATE_RESET; 33 34 return FPGA_MGR_STATE_UNKNOWN; 35 } 36 37 /** 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 40 * 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 44 * 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. 48 */ 49 static int wait_for_init_b(struct fpga_manager *mgr, int value, 50 unsigned long alt_udelay) 51 { 52 struct xilinx_fpga_core *core = mgr->priv; 53 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 54 55 if (core->init_b) { 56 while (time_before(jiffies, timeout)) { 57 int ret = gpiod_get_value(core->init_b); 58 59 if (ret == value) 60 return 0; 61 62 if (ret < 0) { 63 dev_err(&mgr->dev, 64 "Error reading INIT_B (%d)\n", ret); 65 return ret; 66 } 67 68 usleep_range(100, 400); 69 } 70 71 dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n", 72 value ? "assert" : "deassert"); 73 return -ETIMEDOUT; 74 } 75 76 udelay(alt_udelay); 77 78 return 0; 79 } 80 81 static int xilinx_core_write_init(struct fpga_manager *mgr, 82 struct fpga_image_info *info, const char *buf, 83 size_t count) 84 { 85 struct xilinx_fpga_core *core = mgr->priv; 86 int err; 87 88 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { 89 dev_err(&mgr->dev, "Partial reconfiguration not supported\n"); 90 return -EINVAL; 91 } 92 93 gpiod_set_value(core->prog_b, 1); 94 95 err = wait_for_init_b(mgr, 1, 1); /* min is 500 ns */ 96 if (err) { 97 gpiod_set_value(core->prog_b, 0); 98 return err; 99 } 100 101 gpiod_set_value(core->prog_b, 0); 102 103 err = wait_for_init_b(mgr, 0, 0); 104 if (err) 105 return err; 106 107 if (get_done_gpio(mgr)) { 108 dev_err(&mgr->dev, "Unexpected DONE pin state...\n"); 109 return -EIO; 110 } 111 112 /* program latency */ 113 usleep_range(7500, 7600); 114 return 0; 115 } 116 117 static int xilinx_core_write(struct fpga_manager *mgr, const char *buf, 118 size_t count) 119 { 120 struct xilinx_fpga_core *core = mgr->priv; 121 122 return core->write(core, buf, count); 123 } 124 125 static int xilinx_core_write_complete(struct fpga_manager *mgr, 126 struct fpga_image_info *info) 127 { 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; 132 int done; 133 int ret; 134 const char padding[1] = { 0xff }; 135 136 /* 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. 140 */ 141 while (!expired) { 142 expired = time_after(jiffies, timeout); 143 144 done = get_done_gpio(mgr); 145 if (done < 0) 146 return done; 147 148 ret = core->write(core, padding, sizeof(padding)); 149 if (ret) 150 return ret; 151 152 if (done) 153 return 0; 154 } 155 156 if (core->init_b) { 157 ret = gpiod_get_value(core->init_b); 158 159 if (ret < 0) { 160 dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret); 161 return ret; 162 } 163 164 dev_err(&mgr->dev, 165 ret ? "CRC error or invalid device\n" : 166 "Missing sync word or incomplete bitstream\n"); 167 } else { 168 dev_err(&mgr->dev, "Timeout after config data transfer\n"); 169 } 170 171 return -ETIMEDOUT; 172 } 173 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) 177 { 178 struct gpio_desc *desc; 179 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); 184 185 return desc; 186 } 187 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, 193 }; 194 195 int xilinx_core_probe(struct xilinx_fpga_core *core) 196 { 197 struct fpga_manager *mgr; 198 199 if (!core || !core->dev || !core->write) 200 return -EINVAL; 201 202 /* PROGRAM_B is active low */ 203 core->prog_b = xilinx_core_devm_gpiod_get(core->dev, "prog", "prog_b", 204 GPIOD_OUT_LOW); 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"); 208 209 core->init_b = xilinx_core_devm_gpiod_get(core->dev, "init", "init-b", 210 GPIOD_IN); 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"); 214 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"); 219 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); 224 } 225 EXPORT_SYMBOL_GPL(xilinx_core_probe); 226 227 MODULE_LICENSE("GPL"); 228 MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); 229 MODULE_DESCRIPTION("Xilinx 7 Series FPGA manager core"); 230