Merge tag 'phy-fixes-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/phy...
[linux-block.git] / drivers / fpga / lattice-sysconfig-spi.c
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
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
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
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
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
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");