xref: /linux/drivers/fpga/lattice-sysconfig-spi.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Lattice FPGA programming over slave SPI sysCONFIG interface.
4  */
5 
6 #include <linux/of.h>
7 #include <linux/spi/spi.h>
8 
9 #include "lattice-sysconfig.h"
10 
11 static const u32 ecp5_spi_max_speed_hz = 60000000;
12 
sysconfig_spi_cmd_transfer(struct sysconfig_priv * priv,const void * tx_buf,size_t tx_len,void * rx_buf,size_t rx_len)13 static int sysconfig_spi_cmd_transfer(struct sysconfig_priv *priv,
14 				      const void *tx_buf, size_t tx_len,
15 				      void *rx_buf, size_t rx_len)
16 {
17 	struct spi_device *spi = to_spi_device(priv->dev);
18 
19 	return spi_write_then_read(spi, tx_buf, tx_len, rx_buf, rx_len);
20 }
21 
sysconfig_spi_bitstream_burst_init(struct sysconfig_priv * priv)22 static int sysconfig_spi_bitstream_burst_init(struct sysconfig_priv *priv)
23 {
24 	const u8 lsc_bitstream_burst[] = SYSCONFIG_LSC_BITSTREAM_BURST;
25 	struct spi_device *spi = to_spi_device(priv->dev);
26 	struct spi_transfer xfer = {};
27 	struct spi_message msg;
28 	size_t buf_len;
29 	void *buf;
30 	int ret;
31 
32 	buf_len = sizeof(lsc_bitstream_burst);
33 
34 	buf = kmemdup(lsc_bitstream_burst, buf_len, GFP_KERNEL);
35 	if (!buf)
36 		return -ENOMEM;
37 
38 	xfer.len = buf_len;
39 	xfer.tx_buf = buf;
40 	xfer.cs_change = 1;
41 
42 	spi_message_init_with_transfers(&msg, &xfer, 1);
43 
44 	/*
45 	 * Lock SPI bus for exclusive usage until FPGA programming is done.
46 	 * SPI bus will be released in sysconfig_spi_bitstream_burst_complete().
47 	 */
48 	spi_bus_lock(spi->controller);
49 
50 	ret = spi_sync_locked(spi, &msg);
51 	if (ret)
52 		spi_bus_unlock(spi->controller);
53 
54 	kfree(buf);
55 
56 	return ret;
57 }
58 
sysconfig_spi_bitstream_burst_write(struct sysconfig_priv * priv,const char * buf,size_t len)59 static int sysconfig_spi_bitstream_burst_write(struct sysconfig_priv *priv,
60 					       const char *buf, size_t len)
61 {
62 	struct spi_device *spi = to_spi_device(priv->dev);
63 	struct spi_transfer xfer = {
64 		.tx_buf = buf,
65 		.len = len,
66 		.cs_change = 1,
67 	};
68 	struct spi_message msg;
69 
70 	spi_message_init_with_transfers(&msg, &xfer, 1);
71 
72 	return spi_sync_locked(spi, &msg);
73 }
74 
sysconfig_spi_bitstream_burst_complete(struct sysconfig_priv * priv)75 static int sysconfig_spi_bitstream_burst_complete(struct sysconfig_priv *priv)
76 {
77 	struct spi_device *spi = to_spi_device(priv->dev);
78 
79 	/* Bitstream burst write is done, release SPI bus */
80 	spi_bus_unlock(spi->controller);
81 
82 	/* Toggle CS to finish bitstream write */
83 	return spi_write(spi, NULL, 0);
84 }
85 
sysconfig_spi_probe(struct spi_device * spi)86 static int sysconfig_spi_probe(struct spi_device *spi)
87 {
88 	const struct spi_device_id *dev_id;
89 	struct device *dev = &spi->dev;
90 	struct sysconfig_priv *priv;
91 	const u32 *spi_max_speed;
92 
93 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
94 	if (!priv)
95 		return -ENOMEM;
96 
97 	spi_max_speed = device_get_match_data(dev);
98 	if (!spi_max_speed) {
99 		dev_id = spi_get_device_id(spi);
100 		if (!dev_id)
101 			return -ENODEV;
102 
103 		spi_max_speed = (const u32 *)dev_id->driver_data;
104 	}
105 
106 	if (!spi_max_speed)
107 		return -EINVAL;
108 
109 	if (spi->max_speed_hz > *spi_max_speed) {
110 		dev_err(dev, "SPI speed %u is too high, maximum speed is %u\n",
111 			spi->max_speed_hz, *spi_max_speed);
112 		return -EINVAL;
113 	}
114 
115 	priv->dev = dev;
116 	priv->command_transfer = sysconfig_spi_cmd_transfer;
117 	priv->bitstream_burst_write_init = sysconfig_spi_bitstream_burst_init;
118 	priv->bitstream_burst_write = sysconfig_spi_bitstream_burst_write;
119 	priv->bitstream_burst_write_complete = sysconfig_spi_bitstream_burst_complete;
120 
121 	return sysconfig_probe(priv);
122 }
123 
124 static const struct spi_device_id sysconfig_spi_ids[] = {
125 	{
126 		.name = "sysconfig-ecp5",
127 		.driver_data = (kernel_ulong_t)&ecp5_spi_max_speed_hz,
128 	}, {},
129 };
130 MODULE_DEVICE_TABLE(spi, sysconfig_spi_ids);
131 
132 #if IS_ENABLED(CONFIG_OF)
133 static const struct of_device_id sysconfig_of_ids[] = {
134 	{
135 		.compatible = "lattice,sysconfig-ecp5",
136 		.data = &ecp5_spi_max_speed_hz,
137 	}, {},
138 };
139 MODULE_DEVICE_TABLE(of, sysconfig_of_ids);
140 #endif /* IS_ENABLED(CONFIG_OF) */
141 
142 static struct spi_driver lattice_sysconfig_driver = {
143 	.probe = sysconfig_spi_probe,
144 	.id_table = sysconfig_spi_ids,
145 	.driver = {
146 		.name = "lattice_sysconfig_spi_fpga_mgr",
147 		.of_match_table = of_match_ptr(sysconfig_of_ids),
148 	},
149 };
150 module_spi_driver(lattice_sysconfig_driver);
151 
152 MODULE_DESCRIPTION("Lattice sysCONFIG Slave SPI FPGA Manager");
153 MODULE_LICENSE("GPL");
154