1 /* 2 * Altera Passive Serial SPI Driver 3 * 4 * Copyright (c) 2017 United Western Technologies, Corporation 5 * 6 * Joshua Clayton <stillcompiling@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2, as published by the Free Software Foundation. 11 * 12 * Manage Altera FPGA firmware that is loaded over SPI using the passive 13 * serial configuration method. 14 * Firmware must be in binary "rbf" format. 15 * Works on Arria 10, Cyclone V and Stratix V. Should work on Cyclone series. 16 * May work on other Altera FPGAs. 17 */ 18 19 #include <linux/bitrev.h> 20 #include <linux/delay.h> 21 #include <linux/fpga/fpga-mgr.h> 22 #include <linux/gpio/consumer.h> 23 #include <linux/module.h> 24 #include <linux/of_gpio.h> 25 #include <linux/of_device.h> 26 #include <linux/spi/spi.h> 27 #include <linux/sizes.h> 28 29 enum altera_ps_devtype { 30 CYCLONE5, 31 ARRIA10, 32 }; 33 34 struct altera_ps_data { 35 enum altera_ps_devtype devtype; 36 int status_wait_min_us; 37 int status_wait_max_us; 38 int t_cfg_us; 39 int t_st2ck_us; 40 }; 41 42 struct altera_ps_conf { 43 struct gpio_desc *config; 44 struct gpio_desc *confd; 45 struct gpio_desc *status; 46 struct spi_device *spi; 47 const struct altera_ps_data *data; 48 u32 info_flags; 49 char mgr_name[64]; 50 }; 51 52 /* | Arria 10 | Cyclone5 | Stratix5 | 53 * t_CF2ST0 | [; 600] | [; 600] | [; 600] |ns 54 * t_CFG | [2;] | [2;] | [2;] |µs 55 * t_STATUS | [268; 3000] | [268; 1506] | [268; 1506] |µs 56 * t_CF2ST1 | [; 3000] | [; 1506] | [; 1506] |µs 57 * t_CF2CK | [3010;] | [1506;] | [1506;] |µs 58 * t_ST2CK | [10;] | [2;] | [2;] |µs 59 * t_CD2UM | [175; 830] | [175; 437] | [175; 437] |µs 60 */ 61 static struct altera_ps_data c5_data = { 62 /* these values for Cyclone5 are compatible with Stratix5 */ 63 .devtype = CYCLONE5, 64 .status_wait_min_us = 268, 65 .status_wait_max_us = 1506, 66 .t_cfg_us = 2, 67 .t_st2ck_us = 2, 68 }; 69 70 static struct altera_ps_data a10_data = { 71 .devtype = ARRIA10, 72 .status_wait_min_us = 268, /* min(t_STATUS) */ 73 .status_wait_max_us = 3000, /* max(t_CF2ST1) */ 74 .t_cfg_us = 2, /* max { min(t_CFG), max(tCF2ST0) } */ 75 .t_st2ck_us = 10, /* min(t_ST2CK) */ 76 }; 77 78 /* Array index is enum altera_ps_devtype */ 79 static const struct altera_ps_data *altera_ps_data_map[] = { 80 &c5_data, 81 &a10_data, 82 }; 83 84 static const struct of_device_id of_ef_match[] = { 85 { .compatible = "altr,fpga-passive-serial", .data = &c5_data }, 86 { .compatible = "altr,fpga-arria10-passive-serial", .data = &a10_data }, 87 {} 88 }; 89 MODULE_DEVICE_TABLE(of, of_ef_match); 90 91 static enum fpga_mgr_states altera_ps_state(struct fpga_manager *mgr) 92 { 93 struct altera_ps_conf *conf = mgr->priv; 94 95 if (gpiod_get_value_cansleep(conf->status)) 96 return FPGA_MGR_STATE_RESET; 97 98 return FPGA_MGR_STATE_UNKNOWN; 99 } 100 101 static inline void altera_ps_delay(int delay_us) 102 { 103 if (delay_us > 10) 104 usleep_range(delay_us, delay_us + 5); 105 else 106 udelay(delay_us); 107 } 108 109 static int altera_ps_write_init(struct fpga_manager *mgr, 110 struct fpga_image_info *info, 111 const char *buf, size_t count) 112 { 113 struct altera_ps_conf *conf = mgr->priv; 114 int min, max, waits; 115 int i; 116 117 conf->info_flags = info->flags; 118 119 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { 120 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); 121 return -EINVAL; 122 } 123 124 gpiod_set_value_cansleep(conf->config, 1); 125 126 /* wait min reset pulse time */ 127 altera_ps_delay(conf->data->t_cfg_us); 128 129 if (!gpiod_get_value_cansleep(conf->status)) { 130 dev_err(&mgr->dev, "Status pin failed to show a reset\n"); 131 return -EIO; 132 } 133 134 gpiod_set_value_cansleep(conf->config, 0); 135 136 min = conf->data->status_wait_min_us; 137 max = conf->data->status_wait_max_us; 138 waits = max / min; 139 if (max % min) 140 waits++; 141 142 /* wait for max { max(t_STATUS), max(t_CF2ST1) } */ 143 for (i = 0; i < waits; i++) { 144 usleep_range(min, min + 10); 145 if (!gpiod_get_value_cansleep(conf->status)) { 146 /* wait for min(t_ST2CK)*/ 147 altera_ps_delay(conf->data->t_st2ck_us); 148 return 0; 149 } 150 } 151 152 dev_err(&mgr->dev, "Status pin not ready.\n"); 153 return -EIO; 154 } 155 156 static void rev_buf(char *buf, size_t len) 157 { 158 u32 *fw32 = (u32 *)buf; 159 size_t extra_bytes = (len & 0x03); 160 const u32 *fw_end = (u32 *)(buf + len - extra_bytes); 161 162 /* set buffer to lsb first */ 163 while (fw32 < fw_end) { 164 *fw32 = bitrev8x4(*fw32); 165 fw32++; 166 } 167 168 if (extra_bytes) { 169 buf = (char *)fw_end; 170 while (extra_bytes) { 171 *buf = bitrev8(*buf); 172 buf++; 173 extra_bytes--; 174 } 175 } 176 } 177 178 static int altera_ps_write(struct fpga_manager *mgr, const char *buf, 179 size_t count) 180 { 181 struct altera_ps_conf *conf = mgr->priv; 182 const char *fw_data = buf; 183 const char *fw_data_end = fw_data + count; 184 185 while (fw_data < fw_data_end) { 186 int ret; 187 size_t stride = min_t(size_t, fw_data_end - fw_data, SZ_4K); 188 189 if (!(conf->info_flags & FPGA_MGR_BITSTREAM_LSB_FIRST)) 190 rev_buf((char *)fw_data, stride); 191 192 ret = spi_write(conf->spi, fw_data, stride); 193 if (ret) { 194 dev_err(&mgr->dev, "spi error in firmware write: %d\n", 195 ret); 196 return ret; 197 } 198 fw_data += stride; 199 } 200 201 return 0; 202 } 203 204 static int altera_ps_write_complete(struct fpga_manager *mgr, 205 struct fpga_image_info *info) 206 { 207 struct altera_ps_conf *conf = mgr->priv; 208 static const char dummy[] = {0}; 209 int ret; 210 211 if (gpiod_get_value_cansleep(conf->status)) { 212 dev_err(&mgr->dev, "Error during configuration.\n"); 213 return -EIO; 214 } 215 216 if (!IS_ERR(conf->confd)) { 217 if (!gpiod_get_raw_value_cansleep(conf->confd)) { 218 dev_err(&mgr->dev, "CONF_DONE is inactive!\n"); 219 return -EIO; 220 } 221 } 222 223 /* 224 * After CONF_DONE goes high, send two additional falling edges on DCLK 225 * to begin initialization and enter user mode 226 */ 227 ret = spi_write(conf->spi, dummy, 1); 228 if (ret) { 229 dev_err(&mgr->dev, "spi error during end sequence: %d\n", ret); 230 return ret; 231 } 232 233 return 0; 234 } 235 236 static const struct fpga_manager_ops altera_ps_ops = { 237 .state = altera_ps_state, 238 .write_init = altera_ps_write_init, 239 .write = altera_ps_write, 240 .write_complete = altera_ps_write_complete, 241 }; 242 243 static const struct altera_ps_data *id_to_data(const struct spi_device_id *id) 244 { 245 kernel_ulong_t devtype = id->driver_data; 246 const struct altera_ps_data *data; 247 248 /* someone added a altera_ps_devtype without adding to the map array */ 249 if (devtype >= ARRAY_SIZE(altera_ps_data_map)) 250 return NULL; 251 252 data = altera_ps_data_map[devtype]; 253 if (!data || data->devtype != devtype) 254 return NULL; 255 256 return data; 257 } 258 259 static int altera_ps_probe(struct spi_device *spi) 260 { 261 struct altera_ps_conf *conf; 262 const struct of_device_id *of_id; 263 struct fpga_manager *mgr; 264 265 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); 266 if (!conf) 267 return -ENOMEM; 268 269 if (spi->dev.of_node) { 270 of_id = of_match_device(of_ef_match, &spi->dev); 271 if (!of_id) 272 return -ENODEV; 273 conf->data = of_id->data; 274 } else { 275 conf->data = id_to_data(spi_get_device_id(spi)); 276 if (!conf->data) 277 return -ENODEV; 278 } 279 280 conf->spi = spi; 281 conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_LOW); 282 if (IS_ERR(conf->config)) { 283 dev_err(&spi->dev, "Failed to get config gpio: %ld\n", 284 PTR_ERR(conf->config)); 285 return PTR_ERR(conf->config); 286 } 287 288 conf->status = devm_gpiod_get(&spi->dev, "nstat", GPIOD_IN); 289 if (IS_ERR(conf->status)) { 290 dev_err(&spi->dev, "Failed to get status gpio: %ld\n", 291 PTR_ERR(conf->status)); 292 return PTR_ERR(conf->status); 293 } 294 295 conf->confd = devm_gpiod_get(&spi->dev, "confd", GPIOD_IN); 296 if (IS_ERR(conf->confd)) { 297 dev_warn(&spi->dev, "Not using confd gpio: %ld\n", 298 PTR_ERR(conf->confd)); 299 } 300 301 /* Register manager with unique name */ 302 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s", 303 dev_driver_string(&spi->dev), dev_name(&spi->dev)); 304 305 mgr = devm_fpga_mgr_create(&spi->dev, conf->mgr_name, 306 &altera_ps_ops, conf); 307 if (!mgr) 308 return -ENOMEM; 309 310 spi_set_drvdata(spi, mgr); 311 312 return fpga_mgr_register(mgr); 313 } 314 315 static int altera_ps_remove(struct spi_device *spi) 316 { 317 struct fpga_manager *mgr = spi_get_drvdata(spi); 318 319 fpga_mgr_unregister(mgr); 320 321 return 0; 322 } 323 324 static const struct spi_device_id altera_ps_spi_ids[] = { 325 { "cyclone-ps-spi", CYCLONE5 }, 326 { "fpga-passive-serial", CYCLONE5 }, 327 { "fpga-arria10-passive-serial", ARRIA10 }, 328 {} 329 }; 330 MODULE_DEVICE_TABLE(spi, altera_ps_spi_ids); 331 332 static struct spi_driver altera_ps_driver = { 333 .driver = { 334 .name = "altera-ps-spi", 335 .owner = THIS_MODULE, 336 .of_match_table = of_match_ptr(of_ef_match), 337 }, 338 .id_table = altera_ps_spi_ids, 339 .probe = altera_ps_probe, 340 .remove = altera_ps_remove, 341 }; 342 343 module_spi_driver(altera_ps_driver) 344 345 MODULE_LICENSE("GPL v2"); 346 MODULE_AUTHOR("Joshua Clayton <stillcompiling@gmail.com>"); 347 MODULE_DESCRIPTION("Module to load Altera FPGA firmware over SPI"); 348