can: mcp251xfd: update macros describing ring, FIFO and RAM layout
[linux-2.6-block.git] / drivers / net / can / spi / mcp251xfd / mcp251xfd-ring.c
CommitLineData
55bc37c8
MKB
1// SPDX-License-Identifier: GPL-2.0
2//
3// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
4//
5// Copyright (c) 2019, 2020, 2021 Pengutronix,
6// Marc Kleine-Budde <kernel@pengutronix.de>
7//
8// Based on:
9//
10// CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
11//
12// Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
13//
14
15#include <asm/unaligned.h>
16
17#include "mcp251xfd.h"
18
19static inline u8
20mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv,
21 union mcp251xfd_write_reg_buf *write_reg_buf,
22 const u16 reg, const u32 mask, const u32 val)
23{
24 u8 first_byte, last_byte, len;
25 u8 *data;
26 __le32 val_le32;
27
28 first_byte = mcp251xfd_first_byte_set(mask);
29 last_byte = mcp251xfd_last_byte_set(mask);
30 len = last_byte - first_byte + 1;
31
32 data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte);
33 val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte);
34 memcpy(data, &val_le32, len);
35
36 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) {
37 u16 crc;
38
39 mcp251xfd_spi_cmd_crc_set_len_in_reg(&write_reg_buf->crc.cmd,
40 len);
41 /* CRC */
42 len += sizeof(write_reg_buf->crc.cmd);
43 crc = mcp251xfd_crc16_compute(&write_reg_buf->crc, len);
44 put_unaligned_be16(crc, (void *)write_reg_buf + len);
45
46 /* Total length */
47 len += sizeof(write_reg_buf->crc.crc);
48 } else {
49 len += sizeof(write_reg_buf->nocrc.cmd);
50 }
51
52 return len;
53}
54
617283b9
MKB
55static void
56mcp251xfd_ring_init_tef(struct mcp251xfd_priv *priv, u16 *base)
d2d5397f
MKB
57{
58 struct mcp251xfd_tef_ring *tef_ring;
59 struct spi_transfer *xfer;
60 u32 val;
61 u16 addr;
62 u8 len;
63 int i;
64
65 /* TEF */
66 tef_ring = priv->tef;
67 tef_ring->head = 0;
68 tef_ring->tail = 0;
69
617283b9
MKB
70 /* TEF- and TX-FIFO have same number of objects */
71 *base = mcp251xfd_get_tef_obj_addr(priv->tx->obj_num);
72
d2d5397f
MKB
73 /* FIFO increment TEF tail pointer */
74 addr = MCP251XFD_REG_TEFCON;
75 val = MCP251XFD_REG_TEFCON_UINC;
76 len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->uinc_buf,
77 addr, val, val);
78
79 for (i = 0; i < ARRAY_SIZE(tef_ring->uinc_xfer); i++) {
80 xfer = &tef_ring->uinc_xfer[i];
81 xfer->tx_buf = &tef_ring->uinc_buf;
82 xfer->len = len;
83 xfer->cs_change = 1;
84 xfer->cs_change_delay.value = 0;
85 xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
86 }
87
88 /* "cs_change == 1" on the last transfer results in an active
89 * chip select after the complete SPI message. This causes the
90 * controller to interpret the next register access as
91 * data. Set "cs_change" of the last transfer to "0" to
92 * properly deactivate the chip select at the end of the
93 * message.
94 */
95 xfer->cs_change = 0;
96}
97
55bc37c8
MKB
98static void
99mcp251xfd_tx_ring_init_tx_obj(const struct mcp251xfd_priv *priv,
100 const struct mcp251xfd_tx_ring *ring,
101 struct mcp251xfd_tx_obj *tx_obj,
102 const u8 rts_buf_len,
103 const u8 n)
104{
105 struct spi_transfer *xfer;
106 u16 addr;
107
108 /* FIFO load */
109 addr = mcp251xfd_get_tx_obj_addr(ring, n);
110 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX)
111 mcp251xfd_spi_cmd_write_crc_set_addr(&tx_obj->buf.crc.cmd,
112 addr);
113 else
114 mcp251xfd_spi_cmd_write_nocrc(&tx_obj->buf.nocrc.cmd,
115 addr);
116
117 xfer = &tx_obj->xfer[0];
118 xfer->tx_buf = &tx_obj->buf;
119 xfer->len = 0; /* actual len is assigned on the fly */
120 xfer->cs_change = 1;
121 xfer->cs_change_delay.value = 0;
122 xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
123
124 /* FIFO request to send */
125 xfer = &tx_obj->xfer[1];
126 xfer->tx_buf = &ring->rts_buf;
127 xfer->len = rts_buf_len;
128
129 /* SPI message */
130 spi_message_init_with_transfers(&tx_obj->msg, tx_obj->xfer,
131 ARRAY_SIZE(tx_obj->xfer));
132}
133
617283b9
MKB
134static void
135mcp251xfd_ring_init_tx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
55bc37c8 136{
55bc37c8 137 struct mcp251xfd_tx_ring *tx_ring;
55bc37c8 138 struct mcp251xfd_tx_obj *tx_obj;
55bc37c8
MKB
139 u32 val;
140 u16 addr;
141 u8 len;
d2d5397f 142 int i;
55bc37c8 143
55bc37c8
MKB
144 tx_ring = priv->tx;
145 tx_ring->head = 0;
146 tx_ring->tail = 0;
617283b9 147 tx_ring->base = *base;
c912f19e 148 tx_ring->nr = 0;
617283b9
MKB
149 tx_ring->fifo_nr = *fifo_nr;
150
151 *base = mcp251xfd_get_tx_obj_addr(tx_ring, tx_ring->obj_num);
152 *fifo_nr += 1;
55bc37c8
MKB
153
154 /* FIFO request to send */
c912f19e 155 addr = MCP251XFD_REG_FIFOCON(tx_ring->fifo_nr);
55bc37c8
MKB
156 val = MCP251XFD_REG_FIFOCON_TXREQ | MCP251XFD_REG_FIFOCON_UINC;
157 len = mcp251xfd_cmd_prepare_write_reg(priv, &tx_ring->rts_buf,
158 addr, val, val);
159
160 mcp251xfd_for_each_tx_obj(tx_ring, tx_obj, i)
161 mcp251xfd_tx_ring_init_tx_obj(priv, tx_ring, tx_obj, len, i);
d2d5397f
MKB
162}
163
617283b9
MKB
164static void
165mcp251xfd_ring_init_rx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
d2d5397f 166{
617283b9 167 struct mcp251xfd_rx_ring *rx_ring;
d2d5397f
MKB
168 struct spi_transfer *xfer;
169 u32 val;
170 u16 addr;
171 u8 len;
172 int i, j;
55bc37c8 173
55bc37c8
MKB
174 mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
175 rx_ring->head = 0;
176 rx_ring->tail = 0;
617283b9 177 rx_ring->base = *base;
55bc37c8 178 rx_ring->nr = i;
617283b9 179 rx_ring->fifo_nr = *fifo_nr;
55bc37c8 180
617283b9
MKB
181 *base = mcp251xfd_get_rx_obj_addr(rx_ring, rx_ring->obj_num);
182 *fifo_nr += 1;
55bc37c8
MKB
183
184 /* FIFO increment RX tail pointer */
185 addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr);
186 val = MCP251XFD_REG_FIFOCON_UINC;
187 len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf,
188 addr, val, val);
189
190 for (j = 0; j < ARRAY_SIZE(rx_ring->uinc_xfer); j++) {
191 xfer = &rx_ring->uinc_xfer[j];
192 xfer->tx_buf = &rx_ring->uinc_buf;
193 xfer->len = len;
194 xfer->cs_change = 1;
195 xfer->cs_change_delay.value = 0;
196 xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
197 }
198
199 /* "cs_change == 1" on the last transfer results in an
200 * active chip select after the complete SPI
201 * message. This causes the controller to interpret
202 * the next register access as data. Set "cs_change"
203 * of the last transfer to "0" to properly deactivate
204 * the chip select at the end of the message.
205 */
206 xfer->cs_change = 0;
207 }
208}
209
fa0b68df 210int mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
d2d5397f 211{
83daa863 212 const struct mcp251xfd_rx_ring *rx_ring;
fa0b68df 213 u16 base = 0, ram_used;
617283b9 214 u8 fifo_nr = 1;
83daa863 215 int i;
617283b9 216
d2d5397f
MKB
217 netdev_reset_queue(priv->ndev);
218
617283b9 219 mcp251xfd_ring_init_tef(priv, &base);
617283b9 220 mcp251xfd_ring_init_rx(priv, &base, &fifo_nr);
62713f0d 221 mcp251xfd_ring_init_tx(priv, &base, &fifo_nr);
fa0b68df 222
887e359d
MKB
223 /* mcp251xfd_handle_rxif() will iterate over all RX rings.
224 * Rings with their corresponding bit set in
225 * priv->regs_status.rxif are read out.
226 *
227 * If the chip is configured for only 1 RX-FIFO, and if there
228 * is an RX interrupt pending (RXIF in INT register is set),
229 * it must be the 1st RX-FIFO.
230 *
231 * We mark the RXIF of the 1st FIFO as pending here, so that
232 * we can skip the read of the RXIF register in
233 * mcp251xfd_read_regs_status() for the 1 RX-FIFO only case.
234 *
235 * If we use more than 1 RX-FIFO, this value gets overwritten
236 * in mcp251xfd_read_regs_status(), so set it unconditionally
237 * here.
238 */
239 priv->regs_status.rxif = BIT(priv->rx[0]->fifo_nr);
240
83daa863
MKB
241 netdev_dbg(priv->ndev,
242 "FIFO setup: TEF: 0x%03x: %2d*%zu bytes = %4zu bytes\n",
243 mcp251xfd_get_tef_obj_addr(0),
244 priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
245 priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
246
247 mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
248 netdev_dbg(priv->ndev,
249 "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
250 rx_ring->nr, rx_ring->fifo_nr,
251 mcp251xfd_get_rx_obj_addr(rx_ring, 0),
252 rx_ring->obj_num, rx_ring->obj_size,
253 rx_ring->obj_num * rx_ring->obj_size);
254 }
255
256 netdev_dbg(priv->ndev,
257 "FIFO setup: TX: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
258 priv->tx->fifo_nr,
259 mcp251xfd_get_tx_obj_addr(priv->tx, 0),
260 priv->tx->obj_num, priv->tx->obj_size,
261 priv->tx->obj_num * priv->tx->obj_size);
262
263 netdev_dbg(priv->ndev,
c47675b1 264 "FIFO setup: free: %4d bytes\n",
83daa863
MKB
265 MCP251XFD_RAM_SIZE - (base - MCP251XFD_RAM_START));
266
fa0b68df
MKB
267 ram_used = base - MCP251XFD_RAM_START;
268 if (ram_used > MCP251XFD_RAM_SIZE) {
269 netdev_err(priv->ndev,
270 "Error during ring configuration, using more RAM (%u bytes) than available (%u bytes).\n",
271 ram_used, MCP251XFD_RAM_SIZE);
272 return -ENOMEM;
273 }
274
275 return 0;
d2d5397f
MKB
276}
277
55bc37c8
MKB
278void mcp251xfd_ring_free(struct mcp251xfd_priv *priv)
279{
280 int i;
281
282 for (i = ARRAY_SIZE(priv->rx) - 1; i >= 0; i--) {
283 kfree(priv->rx[i]);
284 priv->rx[i] = NULL;
285 }
286}
287
288int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
289{
290 struct mcp251xfd_tx_ring *tx_ring;
291 struct mcp251xfd_rx_ring *rx_ring;
0a1f2e65
MKB
292 u8 tef_obj_size, tx_obj_size, rx_obj_size;
293 u8 tx_obj_num;
294 u8 rem, i;
55bc37c8
MKB
295
296 tef_obj_size = sizeof(struct mcp251xfd_hw_tef_obj);
3044a4f2 297 if (mcp251xfd_is_fd_mode(priv)) {
c9e6b80d 298 tx_obj_num = MCP251XFD_TX_OBJ_NUM_CANFD_DEFAULT;
55bc37c8
MKB
299 tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_canfd);
300 rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_canfd);
301 } else {
c9e6b80d 302 tx_obj_num = MCP251XFD_TX_OBJ_NUM_CAN_DEFAULT;
55bc37c8
MKB
303 tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_can);
304 rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can);
305 }
306
d86ba8db
MKB
307 priv->rx_obj_num = 0;
308
55bc37c8
MKB
309 tx_ring = priv->tx;
310 tx_ring->obj_num = tx_obj_num;
311 tx_ring->obj_size = tx_obj_size;
312
0a1f2e65
MKB
313 rem = (MCP251XFD_RAM_SIZE - tx_obj_num *
314 (tef_obj_size + tx_obj_size)) / rx_obj_size;
315 for (i = 0; i < ARRAY_SIZE(priv->rx) && rem; i++) {
316 u8 rx_obj_num;
55bc37c8 317
0a1f2e65
MKB
318 rx_obj_num = min_t(u8, rounddown_pow_of_two(rem),
319 MCP251XFD_FIFO_DEPTH);
320 rem -= rx_obj_num;
55bc37c8 321
d86ba8db
MKB
322 priv->rx_obj_num += rx_obj_num;
323
55bc37c8
MKB
324 rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num,
325 GFP_KERNEL);
326 if (!rx_ring) {
327 mcp251xfd_ring_free(priv);
328 return -ENOMEM;
329 }
0a1f2e65 330
55bc37c8
MKB
331 rx_ring->obj_num = rx_obj_num;
332 rx_ring->obj_size = rx_obj_size;
333 priv->rx[i] = rx_ring;
55bc37c8
MKB
334 }
335 priv->rx_ring_num = i;
336
55bc37c8
MKB
337 return 0;
338}