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