Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Altera Passive Serial SPI Driver
0004  *
0005  *  Copyright (c) 2017 United Western Technologies, Corporation
0006  *
0007  *  Joshua Clayton <stillcompiling@gmail.com>
0008  *
0009  * Manage Altera FPGA firmware that is loaded over SPI using the passive
0010  * serial configuration method.
0011  * Firmware must be in binary "rbf" format.
0012  * Works on Arria 10, Cyclone V and Stratix V. Should work on Cyclone series.
0013  * May work on other Altera FPGAs.
0014  */
0015 
0016 #include <linux/bitrev.h>
0017 #include <linux/delay.h>
0018 #include <linux/fpga/fpga-mgr.h>
0019 #include <linux/gpio/consumer.h>
0020 #include <linux/module.h>
0021 #include <linux/of_gpio.h>
0022 #include <linux/of_device.h>
0023 #include <linux/spi/spi.h>
0024 #include <linux/sizes.h>
0025 
0026 enum altera_ps_devtype {
0027     CYCLONE5,
0028     ARRIA10,
0029 };
0030 
0031 struct altera_ps_data {
0032     enum altera_ps_devtype devtype;
0033     int status_wait_min_us;
0034     int status_wait_max_us;
0035     int t_cfg_us;
0036     int t_st2ck_us;
0037 };
0038 
0039 struct altera_ps_conf {
0040     struct gpio_desc *config;
0041     struct gpio_desc *confd;
0042     struct gpio_desc *status;
0043     struct spi_device *spi;
0044     const struct altera_ps_data *data;
0045     u32 info_flags;
0046     char mgr_name[64];
0047 };
0048 
0049 /*          |   Arria 10  |   Cyclone5  |   Stratix5  |
0050  * t_CF2ST0 |     [; 600] |     [; 600] |     [; 600] |ns
0051  * t_CFG    |        [2;] |        [2;] |        [2;] |µs
0052  * t_STATUS | [268; 3000] | [268; 1506] | [268; 1506] |µs
0053  * t_CF2ST1 |    [; 3000] |    [; 1506] |    [; 1506] |µs
0054  * t_CF2CK  |     [3010;] |     [1506;] |     [1506;] |µs
0055  * t_ST2CK  |       [10;] |        [2;] |        [2;] |µs
0056  * t_CD2UM  |  [175; 830] |  [175; 437] |  [175; 437] |µs
0057  */
0058 static struct altera_ps_data c5_data = {
0059     /* these values for Cyclone5 are compatible with Stratix5 */
0060     .devtype = CYCLONE5,
0061     .status_wait_min_us = 268,
0062     .status_wait_max_us = 1506,
0063     .t_cfg_us = 2,
0064     .t_st2ck_us = 2,
0065 };
0066 
0067 static struct altera_ps_data a10_data = {
0068     .devtype = ARRIA10,
0069     .status_wait_min_us = 268,  /* min(t_STATUS) */
0070     .status_wait_max_us = 3000, /* max(t_CF2ST1) */
0071     .t_cfg_us = 2,    /* max { min(t_CFG), max(tCF2ST0) } */
0072     .t_st2ck_us = 10, /* min(t_ST2CK) */
0073 };
0074 
0075 /* Array index is enum altera_ps_devtype */
0076 static const struct altera_ps_data *altera_ps_data_map[] = {
0077     &c5_data,
0078     &a10_data,
0079 };
0080 
0081 static const struct of_device_id of_ef_match[] = {
0082     { .compatible = "altr,fpga-passive-serial", .data = &c5_data },
0083     { .compatible = "altr,fpga-arria10-passive-serial", .data = &a10_data },
0084     {}
0085 };
0086 MODULE_DEVICE_TABLE(of, of_ef_match);
0087 
0088 static enum fpga_mgr_states altera_ps_state(struct fpga_manager *mgr)
0089 {
0090     struct altera_ps_conf *conf = mgr->priv;
0091 
0092     if (gpiod_get_value_cansleep(conf->status))
0093         return FPGA_MGR_STATE_RESET;
0094 
0095     return FPGA_MGR_STATE_UNKNOWN;
0096 }
0097 
0098 static inline void altera_ps_delay(int delay_us)
0099 {
0100     if (delay_us > 10)
0101         usleep_range(delay_us, delay_us + 5);
0102     else
0103         udelay(delay_us);
0104 }
0105 
0106 static int altera_ps_write_init(struct fpga_manager *mgr,
0107                 struct fpga_image_info *info,
0108                 const char *buf, size_t count)
0109 {
0110     struct altera_ps_conf *conf = mgr->priv;
0111     int min, max, waits;
0112     int i;
0113 
0114     conf->info_flags = info->flags;
0115 
0116     if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
0117         dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
0118         return -EINVAL;
0119     }
0120 
0121     gpiod_set_value_cansleep(conf->config, 1);
0122 
0123     /* wait min reset pulse time */
0124     altera_ps_delay(conf->data->t_cfg_us);
0125 
0126     if (!gpiod_get_value_cansleep(conf->status)) {
0127         dev_err(&mgr->dev, "Status pin failed to show a reset\n");
0128         return -EIO;
0129     }
0130 
0131     gpiod_set_value_cansleep(conf->config, 0);
0132 
0133     min = conf->data->status_wait_min_us;
0134     max = conf->data->status_wait_max_us;
0135     waits = max / min;
0136     if (max % min)
0137         waits++;
0138 
0139     /* wait for max { max(t_STATUS), max(t_CF2ST1) } */
0140     for (i = 0; i < waits; i++) {
0141         usleep_range(min, min + 10);
0142         if (!gpiod_get_value_cansleep(conf->status)) {
0143             /* wait for min(t_ST2CK)*/
0144             altera_ps_delay(conf->data->t_st2ck_us);
0145             return 0;
0146         }
0147     }
0148 
0149     dev_err(&mgr->dev, "Status pin not ready.\n");
0150     return -EIO;
0151 }
0152 
0153 static void rev_buf(char *buf, size_t len)
0154 {
0155     u32 *fw32 = (u32 *)buf;
0156     size_t extra_bytes = (len & 0x03);
0157     const u32 *fw_end = (u32 *)(buf + len - extra_bytes);
0158 
0159     /* set buffer to lsb first */
0160     while (fw32 < fw_end) {
0161         *fw32 = bitrev8x4(*fw32);
0162         fw32++;
0163     }
0164 
0165     if (extra_bytes) {
0166         buf = (char *)fw_end;
0167         while (extra_bytes) {
0168             *buf = bitrev8(*buf);
0169             buf++;
0170             extra_bytes--;
0171         }
0172     }
0173 }
0174 
0175 static int altera_ps_write(struct fpga_manager *mgr, const char *buf,
0176                size_t count)
0177 {
0178     struct altera_ps_conf *conf = mgr->priv;
0179     const char *fw_data = buf;
0180     const char *fw_data_end = fw_data + count;
0181 
0182     while (fw_data < fw_data_end) {
0183         int ret;
0184         size_t stride = min_t(size_t, fw_data_end - fw_data, SZ_4K);
0185 
0186         if (!(conf->info_flags & FPGA_MGR_BITSTREAM_LSB_FIRST))
0187             rev_buf((char *)fw_data, stride);
0188 
0189         ret = spi_write(conf->spi, fw_data, stride);
0190         if (ret) {
0191             dev_err(&mgr->dev, "spi error in firmware write: %d\n",
0192                 ret);
0193             return ret;
0194         }
0195         fw_data += stride;
0196     }
0197 
0198     return 0;
0199 }
0200 
0201 static int altera_ps_write_complete(struct fpga_manager *mgr,
0202                     struct fpga_image_info *info)
0203 {
0204     struct altera_ps_conf *conf = mgr->priv;
0205     static const char dummy[] = {0};
0206     int ret;
0207 
0208     if (gpiod_get_value_cansleep(conf->status)) {
0209         dev_err(&mgr->dev, "Error during configuration.\n");
0210         return -EIO;
0211     }
0212 
0213     if (conf->confd) {
0214         if (!gpiod_get_raw_value_cansleep(conf->confd)) {
0215             dev_err(&mgr->dev, "CONF_DONE is inactive!\n");
0216             return -EIO;
0217         }
0218     }
0219 
0220     /*
0221      * After CONF_DONE goes high, send two additional falling edges on DCLK
0222      * to begin initialization and enter user mode
0223      */
0224     ret = spi_write(conf->spi, dummy, 1);
0225     if (ret) {
0226         dev_err(&mgr->dev, "spi error during end sequence: %d\n", ret);
0227         return ret;
0228     }
0229 
0230     return 0;
0231 }
0232 
0233 static const struct fpga_manager_ops altera_ps_ops = {
0234     .state = altera_ps_state,
0235     .write_init = altera_ps_write_init,
0236     .write = altera_ps_write,
0237     .write_complete = altera_ps_write_complete,
0238 };
0239 
0240 static const struct altera_ps_data *id_to_data(const struct spi_device_id *id)
0241 {
0242     kernel_ulong_t devtype = id->driver_data;
0243     const struct altera_ps_data *data;
0244 
0245     /* someone added a altera_ps_devtype without adding to the map array */
0246     if (devtype >= ARRAY_SIZE(altera_ps_data_map))
0247         return NULL;
0248 
0249     data = altera_ps_data_map[devtype];
0250     if (!data || data->devtype != devtype)
0251         return NULL;
0252 
0253     return data;
0254 }
0255 
0256 static int altera_ps_probe(struct spi_device *spi)
0257 {
0258     struct altera_ps_conf *conf;
0259     const struct of_device_id *of_id;
0260     struct fpga_manager *mgr;
0261 
0262     conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
0263     if (!conf)
0264         return -ENOMEM;
0265 
0266     if (spi->dev.of_node) {
0267         of_id = of_match_device(of_ef_match, &spi->dev);
0268         if (!of_id)
0269             return -ENODEV;
0270         conf->data = of_id->data;
0271     } else {
0272         conf->data = id_to_data(spi_get_device_id(spi));
0273         if (!conf->data)
0274             return -ENODEV;
0275     }
0276 
0277     conf->spi = spi;
0278     conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_LOW);
0279     if (IS_ERR(conf->config)) {
0280         dev_err(&spi->dev, "Failed to get config gpio: %ld\n",
0281             PTR_ERR(conf->config));
0282         return PTR_ERR(conf->config);
0283     }
0284 
0285     conf->status = devm_gpiod_get(&spi->dev, "nstat", GPIOD_IN);
0286     if (IS_ERR(conf->status)) {
0287         dev_err(&spi->dev, "Failed to get status gpio: %ld\n",
0288             PTR_ERR(conf->status));
0289         return PTR_ERR(conf->status);
0290     }
0291 
0292     conf->confd = devm_gpiod_get_optional(&spi->dev, "confd", GPIOD_IN);
0293     if (IS_ERR(conf->confd)) {
0294         dev_err(&spi->dev, "Failed to get confd gpio: %ld\n",
0295             PTR_ERR(conf->confd));
0296         return PTR_ERR(conf->confd);
0297     } else if (!conf->confd) {
0298         dev_warn(&spi->dev, "Not using confd gpio");
0299     }
0300 
0301     /* Register manager with unique name */
0302     snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s",
0303          dev_driver_string(&spi->dev), dev_name(&spi->dev));
0304 
0305     mgr = devm_fpga_mgr_register(&spi->dev, conf->mgr_name,
0306                      &altera_ps_ops, conf);
0307     return PTR_ERR_OR_ZERO(mgr);
0308 }
0309 
0310 static const struct spi_device_id altera_ps_spi_ids[] = {
0311     { "cyclone-ps-spi", CYCLONE5 },
0312     { "fpga-passive-serial", CYCLONE5 },
0313     { "fpga-arria10-passive-serial", ARRIA10 },
0314     {}
0315 };
0316 MODULE_DEVICE_TABLE(spi, altera_ps_spi_ids);
0317 
0318 static struct spi_driver altera_ps_driver = {
0319     .driver = {
0320         .name = "altera-ps-spi",
0321         .owner = THIS_MODULE,
0322         .of_match_table = of_match_ptr(of_ef_match),
0323     },
0324     .id_table = altera_ps_spi_ids,
0325     .probe = altera_ps_probe,
0326 };
0327 
0328 module_spi_driver(altera_ps_driver)
0329 
0330 MODULE_LICENSE("GPL v2");
0331 MODULE_AUTHOR("Joshua Clayton <stillcompiling@gmail.com>");
0332 MODULE_DESCRIPTION("Module to load Altera FPGA firmware over SPI");