Lines Matching +full:mpf +full:- +full:spi +full:- +full:fpga +full:- +full:mgr
1 // SPDX-License-Identifier: GPL-2.0
3 * Microchip Polarfire FPGA programming over slave SPI interface.
8 #include <linux/fpga/fpga-mgr.h>
11 #include <linux/spi/spi.h>
43 struct spi_device *spi; member
47 static int mpf_read_status(struct spi_device *spi) in mpf_read_status() argument
56 * two identical SPI transfers and use result of the later one. in mpf_read_status()
66 ret = spi_sync_transfer(spi, xfers, 2); in mpf_read_status()
70 ret = -EIO; in mpf_read_status()
75 static enum fpga_mgr_states mpf_ops_state(struct fpga_manager *mgr) in mpf_ops_state() argument
77 struct mpf_priv *priv = mgr->priv; in mpf_ops_state()
78 struct spi_device *spi; in mpf_ops_state() local
82 spi = priv->spi; in mpf_ops_state()
83 program_mode = priv->program_mode; in mpf_ops_state()
84 status = mpf_read_status(spi); in mpf_ops_state()
92 static int mpf_ops_parse_header(struct fpga_manager *mgr, in mpf_ops_parse_header() argument
104 dev_err(&mgr->dev, "Image buffer is not provided\n"); in mpf_ops_parse_header()
105 return -EINVAL; in mpf_ops_parse_header()
110 info->header_size = header_size; in mpf_ops_parse_header()
111 return -EAGAIN; in mpf_ops_parse_header()
115 * Go through look-up table to find out where actual bitstream starts in mpf_ops_parse_header()
118 blocks_num = *(buf + header_size - 1); in mpf_ops_parse_header()
124 info->header_size = header_size; in mpf_ops_parse_header()
125 return -EAGAIN; in mpf_ops_parse_header()
131 while (blocks_num--) { in mpf_ops_parse_header()
138 info->header_size = block_start; in mpf_ops_parse_header()
140 return -EAGAIN; in mpf_ops_parse_header()
158 dev_err(&mgr->dev, "Failed to parse header look-up table\n"); in mpf_ops_parse_header()
159 return -EFAULT; in mpf_ops_parse_header()
164 * Sizes of components of the bitstream are 22-bits long placed next in mpf_ops_parse_header()
180 component_size &= GENMASK(MPF_BITS_PER_COMPONENT_SIZE - 1, 0); in mpf_ops_parse_header()
182 info->data_size += component_size * MPF_SPI_FRAME_SIZE; in mpf_ops_parse_header()
189 static int mpf_poll_status(struct spi_device *spi, u8 mask) in mpf_poll_status() argument
193 while (retries--) { in mpf_poll_status()
194 status = mpf_read_status(spi); in mpf_poll_status()
205 return -EBUSY; in mpf_poll_status()
208 static int mpf_spi_write(struct spi_device *spi, const void *buf, size_t buf_size) in mpf_spi_write() argument
210 int status = mpf_poll_status(spi, 0); in mpf_spi_write()
215 return spi_write(spi, buf, buf_size); in mpf_spi_write()
218 static int mpf_spi_write_then_read(struct spi_device *spi, in mpf_spi_write_then_read() argument
225 ret = mpf_spi_write(spi, txbuf, txbuf_size); in mpf_spi_write_then_read()
229 ret = mpf_poll_status(spi, MPF_STATUS_READY); in mpf_spi_write_then_read()
233 return spi_write_then_read(spi, read_command, sizeof(read_command), in mpf_spi_write_then_read()
237 static int mpf_ops_write_init(struct fpga_manager *mgr, in mpf_ops_write_init() argument
243 struct mpf_priv *priv = mgr->priv; in mpf_ops_write_init()
244 struct device *dev = &mgr->dev; in mpf_ops_write_init()
245 struct spi_device *spi; in mpf_ops_write_init() local
249 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { in mpf_ops_write_init()
251 return -EOPNOTSUPP; in mpf_ops_write_init()
254 spi = priv->spi; in mpf_ops_write_init()
256 ret = mpf_spi_write_then_read(spi, isc_en_command, sizeof(isc_en_command), in mpf_ops_write_init()
261 return -EFAULT; in mpf_ops_write_init()
264 ret = mpf_spi_write(spi, program_mode, sizeof(program_mode)); in mpf_ops_write_init()
270 priv->program_mode = true; in mpf_ops_write_init()
275 static int mpf_ops_write(struct fpga_manager *mgr, const char *buf, size_t count) in mpf_ops_write() argument
279 struct mpf_priv *priv = mgr->priv; in mpf_ops_write()
280 struct device *dev = &mgr->dev; in mpf_ops_write()
281 struct spi_device *spi; in mpf_ops_write() local
287 return -EINVAL; in mpf_ops_write()
290 spi = priv->spi; in mpf_ops_write()
299 ret = mpf_poll_status(spi, 0); in mpf_ops_write()
301 ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); in mpf_ops_write()
313 static int mpf_ops_write_complete(struct fpga_manager *mgr, in mpf_ops_write_complete() argument
318 struct mpf_priv *priv = mgr->priv; in mpf_ops_write_complete()
319 struct device *dev = &mgr->dev; in mpf_ops_write_complete()
320 struct spi_device *spi; in mpf_ops_write_complete() local
323 spi = priv->spi; in mpf_ops_write_complete()
325 ret = mpf_spi_write(spi, isc_dis_command, sizeof(isc_dis_command)); in mpf_ops_write_complete()
333 ret = mpf_spi_write(spi, release_command, sizeof(release_command)); in mpf_ops_write_complete()
339 priv->program_mode = false; in mpf_ops_write_complete()
354 static int mpf_probe(struct spi_device *spi) in mpf_probe() argument
356 struct device *dev = &spi->dev; in mpf_probe()
357 struct fpga_manager *mgr; in mpf_probe() local
362 return -ENOMEM; in mpf_probe()
364 priv->spi = spi; in mpf_probe()
366 mgr = devm_fpga_mgr_register(dev, "Microchip Polarfire SPI FPGA Manager", in mpf_probe()
369 return PTR_ERR_OR_ZERO(mgr); in mpf_probe()
373 { .name = "mpf-spi-fpga-mgr", },
376 MODULE_DEVICE_TABLE(spi, mpf_spi_ids);
380 { .compatible = "microchip,mpf-spi-fpga-mgr" },
397 MODULE_DESCRIPTION("Microchip Polarfire SPI FPGA Manager");