]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/raw/ifpga_rawdev/base/opae_spi.c
bump version to 15.2.11-pve1
[ceph.git] / ceph / src / spdk / dpdk / drivers / raw / ifpga_rawdev / base / opae_spi.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2019 Intel Corporation
3 */
4
5 #include "opae_osdep.h"
6 #include "opae_spi.h"
7
8 static int nios_spi_indirect_read(struct altera_spi_device *dev, u32 reg,
9 u32 *val)
10 {
11 u64 ctrl = 0;
12 u64 stat = 0;
13 int loops = SPI_MAX_RETRY;
14
15 ctrl = NIOS_SPI_RD | ((u64)reg << 32);
16 opae_writeq(ctrl, dev->regs + NIOS_SPI_CTRL);
17
18 stat = opae_readq(dev->regs + NIOS_SPI_STAT);
19 while (!(stat & NIOS_SPI_VALID) && --loops)
20 stat = opae_readq(dev->regs + NIOS_SPI_STAT);
21
22 *val = stat & NIOS_SPI_READ_DATA;
23
24 return loops ? 0 : -ETIMEDOUT;
25 }
26
27 static int nios_spi_indirect_write(struct altera_spi_device *dev, u32 reg,
28 u32 value)
29 {
30
31 u64 ctrl = 0;
32 u64 stat = 0;
33 int loops = SPI_MAX_RETRY;
34
35 ctrl |= NIOS_SPI_WR | (u64)reg << 32;
36 ctrl |= value & NIOS_SPI_WRITE_DATA;
37
38 opae_writeq(ctrl, dev->regs + NIOS_SPI_CTRL);
39
40 stat = opae_readq(dev->regs + NIOS_SPI_STAT);
41 while (!(stat & NIOS_SPI_VALID) && --loops)
42 stat = opae_readq(dev->regs + NIOS_SPI_STAT);
43
44 return loops ? 0 : -ETIMEDOUT;
45 }
46
47 static int spi_indirect_write(struct altera_spi_device *dev, u32 reg,
48 u32 value)
49 {
50 u64 ctrl;
51
52 opae_writeq(value & WRITE_DATA_MASK, dev->regs + SPI_WRITE);
53
54 ctrl = CTRL_W | (reg >> 2);
55 opae_writeq(ctrl, dev->regs + SPI_CTRL);
56
57 return 0;
58 }
59
60 static int spi_indirect_read(struct altera_spi_device *dev, u32 reg,
61 u32 *val)
62 {
63 u64 tmp;
64 u64 ctrl;
65
66 ctrl = CTRL_R | (reg >> 2);
67 opae_writeq(ctrl, dev->regs + SPI_CTRL);
68
69 /**
70 * FIXME: Read one more time to avoid HW timing issue. This is
71 * a short term workaround solution, and must be removed once
72 * hardware fixing is done.
73 */
74 tmp = opae_readq(dev->regs + SPI_READ);
75
76 *val = (u32)tmp;
77
78 return 0;
79 }
80
81 int spi_reg_write(struct altera_spi_device *dev, u32 reg,
82 u32 value)
83 {
84 return dev->reg_write(dev, reg, value);
85 }
86
87 int spi_reg_read(struct altera_spi_device *dev, u32 reg,
88 u32 *val)
89 {
90 return dev->reg_read(dev, reg, val);
91 }
92
93 void spi_cs_activate(struct altera_spi_device *dev, unsigned int chip_select)
94 {
95 spi_reg_write(dev, ALTERA_SPI_SLAVE_SEL, 1 << chip_select);
96 spi_reg_write(dev, ALTERA_SPI_CONTROL, ALTERA_SPI_CONTROL_SSO_MSK);
97 }
98
99 void spi_cs_deactivate(struct altera_spi_device *dev)
100 {
101 spi_reg_write(dev, ALTERA_SPI_CONTROL, 0);
102 }
103
104 static int spi_flush_rx(struct altera_spi_device *dev)
105 {
106 u32 val = 0;
107 int ret;
108
109 ret = spi_reg_read(dev, ALTERA_SPI_STATUS, &val);
110 if (ret)
111 return ret;
112
113 if (val & ALTERA_SPI_STATUS_RRDY_MSK) {
114 ret = spi_reg_read(dev, ALTERA_SPI_RXDATA, &val);
115 if (ret)
116 return ret;
117 }
118
119 return 0;
120 }
121
122 static unsigned int spi_write_bytes(struct altera_spi_device *dev, int count)
123 {
124 unsigned int val = 0;
125 u16 *p16;
126 u32 *p32;
127
128 if (dev->txbuf) {
129 switch (dev->data_width) {
130 case 1:
131 val = dev->txbuf[count];
132 break;
133 case 2:
134 p16 = (u16 *)(dev->txbuf + 2*count);
135 val = *p16;
136 if (dev->endian == SPI_BIG_ENDIAN)
137 val = cpu_to_be16(val);
138 break;
139 case 4:
140 p32 = (u32 *)(dev->txbuf + 4*count);
141 val = *p32;
142 break;
143 }
144 }
145
146 return val;
147 }
148
149 static void spi_fill_readbuffer(struct altera_spi_device *dev,
150 unsigned int value, int count)
151 {
152 u16 *p16;
153 u32 *p32;
154
155 if (dev->rxbuf) {
156 switch (dev->data_width) {
157 case 1:
158 dev->rxbuf[count] = value;
159 break;
160 case 2:
161 p16 = (u16 *)(dev->rxbuf + 2*count);
162 if (dev->endian == SPI_BIG_ENDIAN)
163 *p16 = cpu_to_be16((u16)value);
164 else
165 *p16 = (u16)value;
166 break;
167 case 4:
168 p32 = (u32 *)(dev->rxbuf + 4*count);
169 if (dev->endian == SPI_BIG_ENDIAN)
170 *p32 = cpu_to_be32(value);
171 else
172 *p32 = value;
173 break;
174 }
175 }
176 }
177
178 static int spi_txrx(struct altera_spi_device *dev)
179 {
180 unsigned int count = 0;
181 u32 rxd;
182 unsigned int tx_data;
183 u32 status;
184 int retry = 0;
185 int ret;
186
187 while (count < dev->len) {
188 tx_data = spi_write_bytes(dev, count);
189 spi_reg_write(dev, ALTERA_SPI_TXDATA, tx_data);
190
191 while (1) {
192 ret = spi_reg_read(dev, ALTERA_SPI_STATUS, &status);
193 if (ret)
194 return -EIO;
195 if (status & ALTERA_SPI_STATUS_RRDY_MSK)
196 break;
197 if (retry++ > SPI_MAX_RETRY) {
198 dev_err(dev, "%s, read timeout\n", __func__);
199 return -EBUSY;
200 }
201 }
202
203 ret = spi_reg_read(dev, ALTERA_SPI_RXDATA, &rxd);
204 if (ret)
205 return -EIO;
206
207 spi_fill_readbuffer(dev, rxd, count);
208
209 count++;
210 }
211
212 return 0;
213 }
214
215 int spi_command(struct altera_spi_device *dev, unsigned int chip_select,
216 unsigned int wlen, void *wdata,
217 unsigned int rlen, void *rdata)
218 {
219 if (((wlen > 0) && !wdata) || ((rlen > 0) && !rdata)) {
220 dev_err(dev, "error on spi command checking\n");
221 return -EINVAL;
222 }
223
224 wlen = wlen / dev->data_width;
225 rlen = rlen / dev->data_width;
226
227 /* flush rx buffer */
228 spi_flush_rx(dev);
229
230 spi_cs_activate(dev, chip_select);
231 if (wlen) {
232 dev->txbuf = wdata;
233 dev->rxbuf = rdata;
234 dev->len = wlen;
235 spi_txrx(dev);
236 }
237 if (rlen) {
238 dev->rxbuf = rdata;
239 dev->txbuf = NULL;
240 dev->len = rlen;
241 spi_txrx(dev);
242 }
243 spi_cs_deactivate(dev);
244 return 0;
245 }
246
247 struct altera_spi_device *altera_spi_alloc(void *base, int type)
248 {
249 struct altera_spi_device *spi_dev =
250 opae_malloc(sizeof(struct altera_spi_device));
251
252 if (!spi_dev)
253 return NULL;
254
255 spi_dev->regs = base;
256
257 switch (type) {
258 case TYPE_SPI:
259 spi_dev->reg_read = spi_indirect_read;
260 spi_dev->reg_write = spi_indirect_write;
261 break;
262 case TYPE_NIOS_SPI:
263 spi_dev->reg_read = nios_spi_indirect_read;
264 spi_dev->reg_write = nios_spi_indirect_write;
265 break;
266 default:
267 dev_err(dev, "%s: invalid SPI type\n", __func__);
268 goto error;
269 }
270
271 return spi_dev;
272
273 error:
274 altera_spi_release(spi_dev);
275 return NULL;
276 }
277
278 void altera_spi_init(struct altera_spi_device *spi_dev)
279 {
280 spi_dev->spi_param.info = opae_readq(spi_dev->regs + SPI_CORE_PARAM);
281
282 spi_dev->data_width = spi_dev->spi_param.data_width / 8;
283 spi_dev->endian = spi_dev->spi_param.endian;
284 spi_dev->num_chipselect = spi_dev->spi_param.num_chipselect;
285 dev_info(spi_dev, "spi param: type=%d, data width:%d, endian:%d, clock_polarity=%d, clock=%dMHz, chips=%d, cpha=%d\n",
286 spi_dev->spi_param.type,
287 spi_dev->data_width, spi_dev->endian,
288 spi_dev->spi_param.clock_polarity,
289 spi_dev->spi_param.clock,
290 spi_dev->num_chipselect,
291 spi_dev->spi_param.clock_phase);
292
293 /* clear */
294 spi_reg_write(spi_dev, ALTERA_SPI_CONTROL, 0);
295 spi_reg_write(spi_dev, ALTERA_SPI_STATUS, 0);
296 /* flush rxdata */
297 spi_flush_rx(spi_dev);
298 }
299
300 void altera_spi_release(struct altera_spi_device *dev)
301 {
302 if (dev)
303 opae_free(dev);
304 }