build: create dummy Makefile
[dpdk.git] / drivers / raw / ifpga / 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 ret;
185
186         while (count < dev->len) {
187                 tx_data = spi_write_bytes(dev, count);
188                 spi_reg_write(dev, ALTERA_SPI_TXDATA, tx_data);
189
190                 while (1) {
191                         ret = spi_reg_read(dev, ALTERA_SPI_STATUS, &status);
192                         if (ret)
193                                 return -EIO;
194                         if (status & ALTERA_SPI_STATUS_RRDY_MSK)
195                                 break;
196                 }
197
198                 ret = spi_reg_read(dev, ALTERA_SPI_RXDATA, &rxd);
199                 if (ret)
200                         return -EIO;
201
202                 spi_fill_readbuffer(dev, rxd, count);
203
204                 count++;
205         }
206
207         return 0;
208 }
209
210 int spi_command(struct altera_spi_device *dev, unsigned int chip_select,
211                 unsigned int wlen, void *wdata,
212                 unsigned int rlen, void *rdata)
213 {
214         if (((wlen > 0) && !wdata) || ((rlen > 0) && !rdata)) {
215                 dev_err(dev, "error on spi command checking\n");
216                 return -EINVAL;
217         }
218
219         wlen = wlen / dev->data_width;
220         rlen = rlen / dev->data_width;
221
222         /* flush rx buffer */
223         spi_flush_rx(dev);
224
225         spi_cs_activate(dev, chip_select);
226         if (wlen) {
227                 dev->txbuf = wdata;
228                 dev->rxbuf = rdata;
229                 dev->len = wlen;
230                 spi_txrx(dev);
231         }
232         if (rlen) {
233                 dev->rxbuf = rdata;
234                 dev->txbuf = NULL;
235                 dev->len = rlen;
236                 spi_txrx(dev);
237         }
238         spi_cs_deactivate(dev);
239         return 0;
240 }
241
242 struct altera_spi_device *altera_spi_alloc(void *base, int type)
243 {
244         struct altera_spi_device *spi_dev =
245                 opae_malloc(sizeof(struct altera_spi_device));
246
247         if (!spi_dev)
248                 return NULL;
249
250         spi_dev->regs = base;
251
252         switch (type) {
253         case TYPE_SPI:
254                 spi_dev->reg_read = spi_indirect_read;
255                 spi_dev->reg_write = spi_indirect_write;
256                 break;
257         case TYPE_NIOS_SPI:
258                 spi_dev->reg_read = nios_spi_indirect_read;
259                 spi_dev->reg_write = nios_spi_indirect_write;
260                 break;
261         default:
262                 dev_err(dev, "%s: invalid SPI type\n", __func__);
263                 goto error;
264         }
265
266         return spi_dev;
267
268 error:
269         altera_spi_release(spi_dev);
270         return NULL;
271 }
272
273 void altera_spi_init(struct altera_spi_device *spi_dev)
274 {
275         spi_dev->spi_param.info = opae_readq(spi_dev->regs + SPI_CORE_PARAM);
276
277         spi_dev->data_width = spi_dev->spi_param.data_width / 8;
278         spi_dev->endian = spi_dev->spi_param.endian;
279         spi_dev->num_chipselect = spi_dev->spi_param.num_chipselect;
280         dev_info(spi_dev, "spi param: type=%d, data width:%d, endian:%d, clock_polarity=%d, clock=%dMHz, chips=%d, cpha=%d\n",
281                         spi_dev->spi_param.type,
282                         spi_dev->data_width, spi_dev->endian,
283                         spi_dev->spi_param.clock_polarity,
284                         spi_dev->spi_param.clock,
285                         spi_dev->num_chipselect,
286                         spi_dev->spi_param.clock_phase);
287
288         /* clear */
289         spi_reg_write(spi_dev, ALTERA_SPI_CONTROL, 0);
290         spi_reg_write(spi_dev, ALTERA_SPI_STATUS, 0);
291         /* flush rxdata */
292         spi_flush_rx(spi_dev);
293 }
294
295 void altera_spi_release(struct altera_spi_device *dev)
296 {
297         if (dev)
298                 opae_free(dev);
299 }