pty: Repair TIOCGPTPEER
[cris-mirror.git] / drivers / mailbox / bcm-flexrm-mailbox.c
blobda67882caa7bf7f39efa6d6df03dadd29122b6cf
1 /* Broadcom FlexRM Mailbox Driver
3 * Copyright (C) 2017 Broadcom
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Each Broadcom FlexSparx4 offload engine is implemented as an
10 * extension to Broadcom FlexRM ring manager. The FlexRM ring
11 * manager provides a set of rings which can be used to submit
12 * work to a FlexSparx4 offload engine.
14 * This driver creates a mailbox controller using a set of FlexRM
15 * rings where each mailbox channel represents a separate FlexRM ring.
18 #include <asm/barrier.h>
19 #include <asm/byteorder.h>
20 #include <linux/delay.h>
21 #include <linux/device.h>
22 #include <linux/dma-mapping.h>
23 #include <linux/dmapool.h>
24 #include <linux/err.h>
25 #include <linux/idr.h>
26 #include <linux/interrupt.h>
27 #include <linux/kernel.h>
28 #include <linux/mailbox_controller.h>
29 #include <linux/mailbox_client.h>
30 #include <linux/mailbox/brcm-message.h>
31 #include <linux/module.h>
32 #include <linux/msi.h>
33 #include <linux/of_address.h>
34 #include <linux/of_irq.h>
35 #include <linux/platform_device.h>
36 #include <linux/spinlock.h>
38 /* ====== FlexRM register defines ===== */
40 /* FlexRM configuration */
41 #define RING_REGS_SIZE 0x10000
42 #define RING_DESC_SIZE 8
43 #define RING_DESC_INDEX(offset) \
44 ((offset) / RING_DESC_SIZE)
45 #define RING_DESC_OFFSET(index) \
46 ((index) * RING_DESC_SIZE)
47 #define RING_MAX_REQ_COUNT 1024
48 #define RING_BD_ALIGN_ORDER 12
49 #define RING_BD_ALIGN_CHECK(addr) \
50 (!((addr) & ((0x1 << RING_BD_ALIGN_ORDER) - 1)))
51 #define RING_BD_TOGGLE_INVALID(offset) \
52 (((offset) >> RING_BD_ALIGN_ORDER) & 0x1)
53 #define RING_BD_TOGGLE_VALID(offset) \
54 (!RING_BD_TOGGLE_INVALID(offset))
55 #define RING_BD_DESC_PER_REQ 32
56 #define RING_BD_DESC_COUNT \
57 (RING_MAX_REQ_COUNT * RING_BD_DESC_PER_REQ)
58 #define RING_BD_SIZE \
59 (RING_BD_DESC_COUNT * RING_DESC_SIZE)
60 #define RING_CMPL_ALIGN_ORDER 13
61 #define RING_CMPL_DESC_COUNT RING_MAX_REQ_COUNT
62 #define RING_CMPL_SIZE \
63 (RING_CMPL_DESC_COUNT * RING_DESC_SIZE)
64 #define RING_VER_MAGIC 0x76303031
66 /* Per-Ring register offsets */
67 #define RING_VER 0x000
68 #define RING_BD_START_ADDR 0x004
69 #define RING_BD_READ_PTR 0x008
70 #define RING_BD_WRITE_PTR 0x00c
71 #define RING_BD_READ_PTR_DDR_LS 0x010
72 #define RING_BD_READ_PTR_DDR_MS 0x014
73 #define RING_CMPL_START_ADDR 0x018
74 #define RING_CMPL_WRITE_PTR 0x01c
75 #define RING_NUM_REQ_RECV_LS 0x020
76 #define RING_NUM_REQ_RECV_MS 0x024
77 #define RING_NUM_REQ_TRANS_LS 0x028
78 #define RING_NUM_REQ_TRANS_MS 0x02c
79 #define RING_NUM_REQ_OUTSTAND 0x030
80 #define RING_CONTROL 0x034
81 #define RING_FLUSH_DONE 0x038
82 #define RING_MSI_ADDR_LS 0x03c
83 #define RING_MSI_ADDR_MS 0x040
84 #define RING_MSI_CONTROL 0x048
85 #define RING_BD_READ_PTR_DDR_CONTROL 0x04c
86 #define RING_MSI_DATA_VALUE 0x064
88 /* Register RING_BD_START_ADDR fields */
89 #define BD_LAST_UPDATE_HW_SHIFT 28
90 #define BD_LAST_UPDATE_HW_MASK 0x1
91 #define BD_START_ADDR_VALUE(pa) \
92 ((u32)((((dma_addr_t)(pa)) >> RING_BD_ALIGN_ORDER) & 0x0fffffff))
93 #define BD_START_ADDR_DECODE(val) \
94 ((dma_addr_t)((val) & 0x0fffffff) << RING_BD_ALIGN_ORDER)
96 /* Register RING_CMPL_START_ADDR fields */
97 #define CMPL_START_ADDR_VALUE(pa) \
98 ((u32)((((u64)(pa)) >> RING_CMPL_ALIGN_ORDER) & 0x03ffffff))
100 /* Register RING_CONTROL fields */
101 #define CONTROL_MASK_DISABLE_CONTROL 12
102 #define CONTROL_FLUSH_SHIFT 5
103 #define CONTROL_ACTIVE_SHIFT 4
104 #define CONTROL_RATE_ADAPT_MASK 0xf
105 #define CONTROL_RATE_DYNAMIC 0x0
106 #define CONTROL_RATE_FAST 0x8
107 #define CONTROL_RATE_MEDIUM 0x9
108 #define CONTROL_RATE_SLOW 0xa
109 #define CONTROL_RATE_IDLE 0xb
111 /* Register RING_FLUSH_DONE fields */
112 #define FLUSH_DONE_MASK 0x1
114 /* Register RING_MSI_CONTROL fields */
115 #define MSI_TIMER_VAL_SHIFT 16
116 #define MSI_TIMER_VAL_MASK 0xffff
117 #define MSI_ENABLE_SHIFT 15
118 #define MSI_ENABLE_MASK 0x1
119 #define MSI_COUNT_SHIFT 0
120 #define MSI_COUNT_MASK 0x3ff
122 /* Register RING_BD_READ_PTR_DDR_CONTROL fields */
123 #define BD_READ_PTR_DDR_TIMER_VAL_SHIFT 16
124 #define BD_READ_PTR_DDR_TIMER_VAL_MASK 0xffff
125 #define BD_READ_PTR_DDR_ENABLE_SHIFT 15
126 #define BD_READ_PTR_DDR_ENABLE_MASK 0x1
128 /* ====== FlexRM ring descriptor defines ===== */
130 /* Completion descriptor format */
131 #define CMPL_OPAQUE_SHIFT 0
132 #define CMPL_OPAQUE_MASK 0xffff
133 #define CMPL_ENGINE_STATUS_SHIFT 16
134 #define CMPL_ENGINE_STATUS_MASK 0xffff
135 #define CMPL_DME_STATUS_SHIFT 32
136 #define CMPL_DME_STATUS_MASK 0xffff
137 #define CMPL_RM_STATUS_SHIFT 48
138 #define CMPL_RM_STATUS_MASK 0xffff
140 /* Completion DME status code */
141 #define DME_STATUS_MEM_COR_ERR BIT(0)
142 #define DME_STATUS_MEM_UCOR_ERR BIT(1)
143 #define DME_STATUS_FIFO_UNDERFLOW BIT(2)
144 #define DME_STATUS_FIFO_OVERFLOW BIT(3)
145 #define DME_STATUS_RRESP_ERR BIT(4)
146 #define DME_STATUS_BRESP_ERR BIT(5)
147 #define DME_STATUS_ERROR_MASK (DME_STATUS_MEM_COR_ERR | \
148 DME_STATUS_MEM_UCOR_ERR | \
149 DME_STATUS_FIFO_UNDERFLOW | \
150 DME_STATUS_FIFO_OVERFLOW | \
151 DME_STATUS_RRESP_ERR | \
152 DME_STATUS_BRESP_ERR)
154 /* Completion RM status code */
155 #define RM_STATUS_CODE_SHIFT 0
156 #define RM_STATUS_CODE_MASK 0x3ff
157 #define RM_STATUS_CODE_GOOD 0x0
158 #define RM_STATUS_CODE_AE_TIMEOUT 0x3ff
160 /* General descriptor format */
161 #define DESC_TYPE_SHIFT 60
162 #define DESC_TYPE_MASK 0xf
163 #define DESC_PAYLOAD_SHIFT 0
164 #define DESC_PAYLOAD_MASK 0x0fffffffffffffff
166 /* Null descriptor format */
167 #define NULL_TYPE 0
168 #define NULL_TOGGLE_SHIFT 58
169 #define NULL_TOGGLE_MASK 0x1
171 /* Header descriptor format */
172 #define HEADER_TYPE 1
173 #define HEADER_TOGGLE_SHIFT 58
174 #define HEADER_TOGGLE_MASK 0x1
175 #define HEADER_ENDPKT_SHIFT 57
176 #define HEADER_ENDPKT_MASK 0x1
177 #define HEADER_STARTPKT_SHIFT 56
178 #define HEADER_STARTPKT_MASK 0x1
179 #define HEADER_BDCOUNT_SHIFT 36
180 #define HEADER_BDCOUNT_MASK 0x1f
181 #define HEADER_BDCOUNT_MAX HEADER_BDCOUNT_MASK
182 #define HEADER_FLAGS_SHIFT 16
183 #define HEADER_FLAGS_MASK 0xffff
184 #define HEADER_OPAQUE_SHIFT 0
185 #define HEADER_OPAQUE_MASK 0xffff
187 /* Source (SRC) descriptor format */
188 #define SRC_TYPE 2
189 #define SRC_LENGTH_SHIFT 44
190 #define SRC_LENGTH_MASK 0xffff
191 #define SRC_ADDR_SHIFT 0
192 #define SRC_ADDR_MASK 0x00000fffffffffff
194 /* Destination (DST) descriptor format */
195 #define DST_TYPE 3
196 #define DST_LENGTH_SHIFT 44
197 #define DST_LENGTH_MASK 0xffff
198 #define DST_ADDR_SHIFT 0
199 #define DST_ADDR_MASK 0x00000fffffffffff
201 /* Immediate (IMM) descriptor format */
202 #define IMM_TYPE 4
203 #define IMM_DATA_SHIFT 0
204 #define IMM_DATA_MASK 0x0fffffffffffffff
206 /* Next pointer (NPTR) descriptor format */
207 #define NPTR_TYPE 5
208 #define NPTR_TOGGLE_SHIFT 58
209 #define NPTR_TOGGLE_MASK 0x1
210 #define NPTR_ADDR_SHIFT 0
211 #define NPTR_ADDR_MASK 0x00000fffffffffff
213 /* Mega source (MSRC) descriptor format */
214 #define MSRC_TYPE 6
215 #define MSRC_LENGTH_SHIFT 44
216 #define MSRC_LENGTH_MASK 0xffff
217 #define MSRC_ADDR_SHIFT 0
218 #define MSRC_ADDR_MASK 0x00000fffffffffff
220 /* Mega destination (MDST) descriptor format */
221 #define MDST_TYPE 7
222 #define MDST_LENGTH_SHIFT 44
223 #define MDST_LENGTH_MASK 0xffff
224 #define MDST_ADDR_SHIFT 0
225 #define MDST_ADDR_MASK 0x00000fffffffffff
227 /* Source with tlast (SRCT) descriptor format */
228 #define SRCT_TYPE 8
229 #define SRCT_LENGTH_SHIFT 44
230 #define SRCT_LENGTH_MASK 0xffff
231 #define SRCT_ADDR_SHIFT 0
232 #define SRCT_ADDR_MASK 0x00000fffffffffff
234 /* Destination with tlast (DSTT) descriptor format */
235 #define DSTT_TYPE 9
236 #define DSTT_LENGTH_SHIFT 44
237 #define DSTT_LENGTH_MASK 0xffff
238 #define DSTT_ADDR_SHIFT 0
239 #define DSTT_ADDR_MASK 0x00000fffffffffff
241 /* Immediate with tlast (IMMT) descriptor format */
242 #define IMMT_TYPE 10
243 #define IMMT_DATA_SHIFT 0
244 #define IMMT_DATA_MASK 0x0fffffffffffffff
246 /* Descriptor helper macros */
247 #define DESC_DEC(_d, _s, _m) (((_d) >> (_s)) & (_m))
248 #define DESC_ENC(_d, _v, _s, _m) \
249 do { \
250 (_d) &= ~((u64)(_m) << (_s)); \
251 (_d) |= (((u64)(_v) & (_m)) << (_s)); \
252 } while (0)
254 /* ====== FlexRM data structures ===== */
256 struct flexrm_ring {
257 /* Unprotected members */
258 int num;
259 struct flexrm_mbox *mbox;
260 void __iomem *regs;
261 bool irq_requested;
262 unsigned int irq;
263 unsigned int msi_timer_val;
264 unsigned int msi_count_threshold;
265 struct ida requests_ida;
266 struct brcm_message *requests[RING_MAX_REQ_COUNT];
267 void *bd_base;
268 dma_addr_t bd_dma_base;
269 u32 bd_write_offset;
270 void *cmpl_base;
271 dma_addr_t cmpl_dma_base;
272 /* Protected members */
273 spinlock_t lock;
274 struct brcm_message *last_pending_msg;
275 u32 cmpl_read_offset;
278 struct flexrm_mbox {
279 struct device *dev;
280 void __iomem *regs;
281 u32 num_rings;
282 struct flexrm_ring *rings;
283 struct dma_pool *bd_pool;
284 struct dma_pool *cmpl_pool;
285 struct mbox_controller controller;
288 /* ====== FlexRM ring descriptor helper routines ===== */
290 static u64 flexrm_read_desc(void *desc_ptr)
292 return le64_to_cpu(*((u64 *)desc_ptr));
295 static void flexrm_write_desc(void *desc_ptr, u64 desc)
297 *((u64 *)desc_ptr) = cpu_to_le64(desc);
300 static u32 flexrm_cmpl_desc_to_reqid(u64 cmpl_desc)
302 return (u32)(cmpl_desc & CMPL_OPAQUE_MASK);
305 static int flexrm_cmpl_desc_to_error(u64 cmpl_desc)
307 u32 status;
309 status = DESC_DEC(cmpl_desc, CMPL_DME_STATUS_SHIFT,
310 CMPL_DME_STATUS_MASK);
311 if (status & DME_STATUS_ERROR_MASK)
312 return -EIO;
314 status = DESC_DEC(cmpl_desc, CMPL_RM_STATUS_SHIFT,
315 CMPL_RM_STATUS_MASK);
316 status &= RM_STATUS_CODE_MASK;
317 if (status == RM_STATUS_CODE_AE_TIMEOUT)
318 return -ETIMEDOUT;
320 return 0;
323 static bool flexrm_is_next_table_desc(void *desc_ptr)
325 u64 desc = flexrm_read_desc(desc_ptr);
326 u32 type = DESC_DEC(desc, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
328 return (type == NPTR_TYPE) ? true : false;
331 static u64 flexrm_next_table_desc(u32 toggle, dma_addr_t next_addr)
333 u64 desc = 0;
335 DESC_ENC(desc, NPTR_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
336 DESC_ENC(desc, toggle, NPTR_TOGGLE_SHIFT, NPTR_TOGGLE_MASK);
337 DESC_ENC(desc, next_addr, NPTR_ADDR_SHIFT, NPTR_ADDR_MASK);
339 return desc;
342 static u64 flexrm_null_desc(u32 toggle)
344 u64 desc = 0;
346 DESC_ENC(desc, NULL_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
347 DESC_ENC(desc, toggle, NULL_TOGGLE_SHIFT, NULL_TOGGLE_MASK);
349 return desc;
352 static u32 flexrm_estimate_header_desc_count(u32 nhcnt)
354 u32 hcnt = nhcnt / HEADER_BDCOUNT_MAX;
356 if (!(nhcnt % HEADER_BDCOUNT_MAX))
357 hcnt += 1;
359 return hcnt;
362 static void flexrm_flip_header_toogle(void *desc_ptr)
364 u64 desc = flexrm_read_desc(desc_ptr);
366 if (desc & ((u64)0x1 << HEADER_TOGGLE_SHIFT))
367 desc &= ~((u64)0x1 << HEADER_TOGGLE_SHIFT);
368 else
369 desc |= ((u64)0x1 << HEADER_TOGGLE_SHIFT);
371 flexrm_write_desc(desc_ptr, desc);
374 static u64 flexrm_header_desc(u32 toggle, u32 startpkt, u32 endpkt,
375 u32 bdcount, u32 flags, u32 opaque)
377 u64 desc = 0;
379 DESC_ENC(desc, HEADER_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
380 DESC_ENC(desc, toggle, HEADER_TOGGLE_SHIFT, HEADER_TOGGLE_MASK);
381 DESC_ENC(desc, startpkt, HEADER_STARTPKT_SHIFT, HEADER_STARTPKT_MASK);
382 DESC_ENC(desc, endpkt, HEADER_ENDPKT_SHIFT, HEADER_ENDPKT_MASK);
383 DESC_ENC(desc, bdcount, HEADER_BDCOUNT_SHIFT, HEADER_BDCOUNT_MASK);
384 DESC_ENC(desc, flags, HEADER_FLAGS_SHIFT, HEADER_FLAGS_MASK);
385 DESC_ENC(desc, opaque, HEADER_OPAQUE_SHIFT, HEADER_OPAQUE_MASK);
387 return desc;
390 static void flexrm_enqueue_desc(u32 nhpos, u32 nhcnt, u32 reqid,
391 u64 desc, void **desc_ptr, u32 *toggle,
392 void *start_desc, void *end_desc)
394 u64 d;
395 u32 nhavail, _toggle, _startpkt, _endpkt, _bdcount;
397 /* Sanity check */
398 if (nhcnt <= nhpos)
399 return;
402 * Each request or packet start with a HEADER descriptor followed
403 * by one or more non-HEADER descriptors (SRC, SRCT, MSRC, DST,
404 * DSTT, MDST, IMM, and IMMT). The number of non-HEADER descriptors
405 * following a HEADER descriptor is represented by BDCOUNT field
406 * of HEADER descriptor. The max value of BDCOUNT field is 31 which
407 * means we can only have 31 non-HEADER descriptors following one
408 * HEADER descriptor.
410 * In general use, number of non-HEADER descriptors can easily go
411 * beyond 31. To tackle this situation, we have packet (or request)
412 * extenstion bits (STARTPKT and ENDPKT) in the HEADER descriptor.
414 * To use packet extension, the first HEADER descriptor of request
415 * (or packet) will have STARTPKT=1 and ENDPKT=0. The intermediate
416 * HEADER descriptors will have STARTPKT=0 and ENDPKT=0. The last
417 * HEADER descriptor will have STARTPKT=0 and ENDPKT=1. Also, the
418 * TOGGLE bit of the first HEADER will be set to invalid state to
419 * ensure that FlexRM does not start fetching descriptors till all
420 * descriptors are enqueued. The user of this function will flip
421 * the TOGGLE bit of first HEADER after all descriptors are
422 * enqueued.
425 if ((nhpos % HEADER_BDCOUNT_MAX == 0) && (nhcnt - nhpos)) {
426 /* Prepare the header descriptor */
427 nhavail = (nhcnt - nhpos);
428 _toggle = (nhpos == 0) ? !(*toggle) : (*toggle);
429 _startpkt = (nhpos == 0) ? 0x1 : 0x0;
430 _endpkt = (nhavail <= HEADER_BDCOUNT_MAX) ? 0x1 : 0x0;
431 _bdcount = (nhavail <= HEADER_BDCOUNT_MAX) ?
432 nhavail : HEADER_BDCOUNT_MAX;
433 if (nhavail <= HEADER_BDCOUNT_MAX)
434 _bdcount = nhavail;
435 else
436 _bdcount = HEADER_BDCOUNT_MAX;
437 d = flexrm_header_desc(_toggle, _startpkt, _endpkt,
438 _bdcount, 0x0, reqid);
440 /* Write header descriptor */
441 flexrm_write_desc(*desc_ptr, d);
443 /* Point to next descriptor */
444 *desc_ptr += sizeof(desc);
445 if (*desc_ptr == end_desc)
446 *desc_ptr = start_desc;
448 /* Skip next pointer descriptors */
449 while (flexrm_is_next_table_desc(*desc_ptr)) {
450 *toggle = (*toggle) ? 0 : 1;
451 *desc_ptr += sizeof(desc);
452 if (*desc_ptr == end_desc)
453 *desc_ptr = start_desc;
457 /* Write desired descriptor */
458 flexrm_write_desc(*desc_ptr, desc);
460 /* Point to next descriptor */
461 *desc_ptr += sizeof(desc);
462 if (*desc_ptr == end_desc)
463 *desc_ptr = start_desc;
465 /* Skip next pointer descriptors */
466 while (flexrm_is_next_table_desc(*desc_ptr)) {
467 *toggle = (*toggle) ? 0 : 1;
468 *desc_ptr += sizeof(desc);
469 if (*desc_ptr == end_desc)
470 *desc_ptr = start_desc;
474 static u64 flexrm_src_desc(dma_addr_t addr, unsigned int length)
476 u64 desc = 0;
478 DESC_ENC(desc, SRC_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
479 DESC_ENC(desc, length, SRC_LENGTH_SHIFT, SRC_LENGTH_MASK);
480 DESC_ENC(desc, addr, SRC_ADDR_SHIFT, SRC_ADDR_MASK);
482 return desc;
485 static u64 flexrm_msrc_desc(dma_addr_t addr, unsigned int length_div_16)
487 u64 desc = 0;
489 DESC_ENC(desc, MSRC_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
490 DESC_ENC(desc, length_div_16, MSRC_LENGTH_SHIFT, MSRC_LENGTH_MASK);
491 DESC_ENC(desc, addr, MSRC_ADDR_SHIFT, MSRC_ADDR_MASK);
493 return desc;
496 static u64 flexrm_dst_desc(dma_addr_t addr, unsigned int length)
498 u64 desc = 0;
500 DESC_ENC(desc, DST_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
501 DESC_ENC(desc, length, DST_LENGTH_SHIFT, DST_LENGTH_MASK);
502 DESC_ENC(desc, addr, DST_ADDR_SHIFT, DST_ADDR_MASK);
504 return desc;
507 static u64 flexrm_mdst_desc(dma_addr_t addr, unsigned int length_div_16)
509 u64 desc = 0;
511 DESC_ENC(desc, MDST_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
512 DESC_ENC(desc, length_div_16, MDST_LENGTH_SHIFT, MDST_LENGTH_MASK);
513 DESC_ENC(desc, addr, MDST_ADDR_SHIFT, MDST_ADDR_MASK);
515 return desc;
518 static u64 flexrm_imm_desc(u64 data)
520 u64 desc = 0;
522 DESC_ENC(desc, IMM_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
523 DESC_ENC(desc, data, IMM_DATA_SHIFT, IMM_DATA_MASK);
525 return desc;
528 static u64 flexrm_srct_desc(dma_addr_t addr, unsigned int length)
530 u64 desc = 0;
532 DESC_ENC(desc, SRCT_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
533 DESC_ENC(desc, length, SRCT_LENGTH_SHIFT, SRCT_LENGTH_MASK);
534 DESC_ENC(desc, addr, SRCT_ADDR_SHIFT, SRCT_ADDR_MASK);
536 return desc;
539 static u64 flexrm_dstt_desc(dma_addr_t addr, unsigned int length)
541 u64 desc = 0;
543 DESC_ENC(desc, DSTT_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
544 DESC_ENC(desc, length, DSTT_LENGTH_SHIFT, DSTT_LENGTH_MASK);
545 DESC_ENC(desc, addr, DSTT_ADDR_SHIFT, DSTT_ADDR_MASK);
547 return desc;
550 static u64 flexrm_immt_desc(u64 data)
552 u64 desc = 0;
554 DESC_ENC(desc, IMMT_TYPE, DESC_TYPE_SHIFT, DESC_TYPE_MASK);
555 DESC_ENC(desc, data, IMMT_DATA_SHIFT, IMMT_DATA_MASK);
557 return desc;
560 static bool flexrm_spu_sanity_check(struct brcm_message *msg)
562 struct scatterlist *sg;
564 if (!msg->spu.src || !msg->spu.dst)
565 return false;
566 for (sg = msg->spu.src; sg; sg = sg_next(sg)) {
567 if (sg->length & 0xf) {
568 if (sg->length > SRC_LENGTH_MASK)
569 return false;
570 } else {
571 if (sg->length > (MSRC_LENGTH_MASK * 16))
572 return false;
575 for (sg = msg->spu.dst; sg; sg = sg_next(sg)) {
576 if (sg->length & 0xf) {
577 if (sg->length > DST_LENGTH_MASK)
578 return false;
579 } else {
580 if (sg->length > (MDST_LENGTH_MASK * 16))
581 return false;
585 return true;
588 static u32 flexrm_spu_estimate_nonheader_desc_count(struct brcm_message *msg)
590 u32 cnt = 0;
591 unsigned int dst_target = 0;
592 struct scatterlist *src_sg = msg->spu.src, *dst_sg = msg->spu.dst;
594 while (src_sg || dst_sg) {
595 if (src_sg) {
596 cnt++;
597 dst_target = src_sg->length;
598 src_sg = sg_next(src_sg);
599 } else
600 dst_target = UINT_MAX;
602 while (dst_target && dst_sg) {
603 cnt++;
604 if (dst_sg->length < dst_target)
605 dst_target -= dst_sg->length;
606 else
607 dst_target = 0;
608 dst_sg = sg_next(dst_sg);
612 return cnt;
615 static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg)
617 int rc;
619 rc = dma_map_sg(dev, msg->spu.src, sg_nents(msg->spu.src),
620 DMA_TO_DEVICE);
621 if (rc < 0)
622 return rc;
624 rc = dma_map_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst),
625 DMA_FROM_DEVICE);
626 if (rc < 0) {
627 dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src),
628 DMA_TO_DEVICE);
629 return rc;
632 return 0;
635 static void flexrm_spu_dma_unmap(struct device *dev, struct brcm_message *msg)
637 dma_unmap_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst),
638 DMA_FROM_DEVICE);
639 dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src),
640 DMA_TO_DEVICE);
643 static void *flexrm_spu_write_descs(struct brcm_message *msg, u32 nhcnt,
644 u32 reqid, void *desc_ptr, u32 toggle,
645 void *start_desc, void *end_desc)
647 u64 d;
648 u32 nhpos = 0;
649 void *orig_desc_ptr = desc_ptr;
650 unsigned int dst_target = 0;
651 struct scatterlist *src_sg = msg->spu.src, *dst_sg = msg->spu.dst;
653 while (src_sg || dst_sg) {
654 if (src_sg) {
655 if (sg_dma_len(src_sg) & 0xf)
656 d = flexrm_src_desc(sg_dma_address(src_sg),
657 sg_dma_len(src_sg));
658 else
659 d = flexrm_msrc_desc(sg_dma_address(src_sg),
660 sg_dma_len(src_sg)/16);
661 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
662 d, &desc_ptr, &toggle,
663 start_desc, end_desc);
664 nhpos++;
665 dst_target = sg_dma_len(src_sg);
666 src_sg = sg_next(src_sg);
667 } else
668 dst_target = UINT_MAX;
670 while (dst_target && dst_sg) {
671 if (sg_dma_len(dst_sg) & 0xf)
672 d = flexrm_dst_desc(sg_dma_address(dst_sg),
673 sg_dma_len(dst_sg));
674 else
675 d = flexrm_mdst_desc(sg_dma_address(dst_sg),
676 sg_dma_len(dst_sg)/16);
677 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
678 d, &desc_ptr, &toggle,
679 start_desc, end_desc);
680 nhpos++;
681 if (sg_dma_len(dst_sg) < dst_target)
682 dst_target -= sg_dma_len(dst_sg);
683 else
684 dst_target = 0;
685 dst_sg = sg_next(dst_sg);
689 /* Null descriptor with invalid toggle bit */
690 flexrm_write_desc(desc_ptr, flexrm_null_desc(!toggle));
692 /* Ensure that descriptors have been written to memory */
693 wmb();
695 /* Flip toggle bit in header */
696 flexrm_flip_header_toogle(orig_desc_ptr);
698 return desc_ptr;
701 static bool flexrm_sba_sanity_check(struct brcm_message *msg)
703 u32 i;
705 if (!msg->sba.cmds || !msg->sba.cmds_count)
706 return false;
708 for (i = 0; i < msg->sba.cmds_count; i++) {
709 if (((msg->sba.cmds[i].flags & BRCM_SBA_CMD_TYPE_B) ||
710 (msg->sba.cmds[i].flags & BRCM_SBA_CMD_TYPE_C)) &&
711 (msg->sba.cmds[i].flags & BRCM_SBA_CMD_HAS_OUTPUT))
712 return false;
713 if ((msg->sba.cmds[i].flags & BRCM_SBA_CMD_TYPE_B) &&
714 (msg->sba.cmds[i].data_len > SRCT_LENGTH_MASK))
715 return false;
716 if ((msg->sba.cmds[i].flags & BRCM_SBA_CMD_TYPE_C) &&
717 (msg->sba.cmds[i].data_len > SRCT_LENGTH_MASK))
718 return false;
719 if ((msg->sba.cmds[i].flags & BRCM_SBA_CMD_HAS_RESP) &&
720 (msg->sba.cmds[i].resp_len > DSTT_LENGTH_MASK))
721 return false;
722 if ((msg->sba.cmds[i].flags & BRCM_SBA_CMD_HAS_OUTPUT) &&
723 (msg->sba.cmds[i].data_len > DSTT_LENGTH_MASK))
724 return false;
727 return true;
730 static u32 flexrm_sba_estimate_nonheader_desc_count(struct brcm_message *msg)
732 u32 i, cnt;
734 cnt = 0;
735 for (i = 0; i < msg->sba.cmds_count; i++) {
736 cnt++;
738 if ((msg->sba.cmds[i].flags & BRCM_SBA_CMD_TYPE_B) ||
739 (msg->sba.cmds[i].flags & BRCM_SBA_CMD_TYPE_C))
740 cnt++;
742 if (msg->sba.cmds[i].flags & BRCM_SBA_CMD_HAS_RESP)
743 cnt++;
745 if (msg->sba.cmds[i].flags & BRCM_SBA_CMD_HAS_OUTPUT)
746 cnt++;
749 return cnt;
752 static void *flexrm_sba_write_descs(struct brcm_message *msg, u32 nhcnt,
753 u32 reqid, void *desc_ptr, u32 toggle,
754 void *start_desc, void *end_desc)
756 u64 d;
757 u32 i, nhpos = 0;
758 struct brcm_sba_command *c;
759 void *orig_desc_ptr = desc_ptr;
761 /* Convert SBA commands into descriptors */
762 for (i = 0; i < msg->sba.cmds_count; i++) {
763 c = &msg->sba.cmds[i];
765 if ((c->flags & BRCM_SBA_CMD_HAS_RESP) &&
766 (c->flags & BRCM_SBA_CMD_HAS_OUTPUT)) {
767 /* Destination response descriptor */
768 d = flexrm_dst_desc(c->resp, c->resp_len);
769 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
770 d, &desc_ptr, &toggle,
771 start_desc, end_desc);
772 nhpos++;
773 } else if (c->flags & BRCM_SBA_CMD_HAS_RESP) {
774 /* Destination response with tlast descriptor */
775 d = flexrm_dstt_desc(c->resp, c->resp_len);
776 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
777 d, &desc_ptr, &toggle,
778 start_desc, end_desc);
779 nhpos++;
782 if (c->flags & BRCM_SBA_CMD_HAS_OUTPUT) {
783 /* Destination with tlast descriptor */
784 d = flexrm_dstt_desc(c->data, c->data_len);
785 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
786 d, &desc_ptr, &toggle,
787 start_desc, end_desc);
788 nhpos++;
791 if (c->flags & BRCM_SBA_CMD_TYPE_B) {
792 /* Command as immediate descriptor */
793 d = flexrm_imm_desc(c->cmd);
794 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
795 d, &desc_ptr, &toggle,
796 start_desc, end_desc);
797 nhpos++;
798 } else {
799 /* Command as immediate descriptor with tlast */
800 d = flexrm_immt_desc(c->cmd);
801 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
802 d, &desc_ptr, &toggle,
803 start_desc, end_desc);
804 nhpos++;
807 if ((c->flags & BRCM_SBA_CMD_TYPE_B) ||
808 (c->flags & BRCM_SBA_CMD_TYPE_C)) {
809 /* Source with tlast descriptor */
810 d = flexrm_srct_desc(c->data, c->data_len);
811 flexrm_enqueue_desc(nhpos, nhcnt, reqid,
812 d, &desc_ptr, &toggle,
813 start_desc, end_desc);
814 nhpos++;
818 /* Null descriptor with invalid toggle bit */
819 flexrm_write_desc(desc_ptr, flexrm_null_desc(!toggle));
821 /* Ensure that descriptors have been written to memory */
822 wmb();
824 /* Flip toggle bit in header */
825 flexrm_flip_header_toogle(orig_desc_ptr);
827 return desc_ptr;
830 static bool flexrm_sanity_check(struct brcm_message *msg)
832 if (!msg)
833 return false;
835 switch (msg->type) {
836 case BRCM_MESSAGE_SPU:
837 return flexrm_spu_sanity_check(msg);
838 case BRCM_MESSAGE_SBA:
839 return flexrm_sba_sanity_check(msg);
840 default:
841 return false;
845 static u32 flexrm_estimate_nonheader_desc_count(struct brcm_message *msg)
847 if (!msg)
848 return 0;
850 switch (msg->type) {
851 case BRCM_MESSAGE_SPU:
852 return flexrm_spu_estimate_nonheader_desc_count(msg);
853 case BRCM_MESSAGE_SBA:
854 return flexrm_sba_estimate_nonheader_desc_count(msg);
855 default:
856 return 0;
860 static int flexrm_dma_map(struct device *dev, struct brcm_message *msg)
862 if (!dev || !msg)
863 return -EINVAL;
865 switch (msg->type) {
866 case BRCM_MESSAGE_SPU:
867 return flexrm_spu_dma_map(dev, msg);
868 default:
869 break;
872 return 0;
875 static void flexrm_dma_unmap(struct device *dev, struct brcm_message *msg)
877 if (!dev || !msg)
878 return;
880 switch (msg->type) {
881 case BRCM_MESSAGE_SPU:
882 flexrm_spu_dma_unmap(dev, msg);
883 break;
884 default:
885 break;
889 static void *flexrm_write_descs(struct brcm_message *msg, u32 nhcnt,
890 u32 reqid, void *desc_ptr, u32 toggle,
891 void *start_desc, void *end_desc)
893 if (!msg || !desc_ptr || !start_desc || !end_desc)
894 return ERR_PTR(-ENOTSUPP);
896 if ((desc_ptr < start_desc) || (end_desc <= desc_ptr))
897 return ERR_PTR(-ERANGE);
899 switch (msg->type) {
900 case BRCM_MESSAGE_SPU:
901 return flexrm_spu_write_descs(msg, nhcnt, reqid,
902 desc_ptr, toggle,
903 start_desc, end_desc);
904 case BRCM_MESSAGE_SBA:
905 return flexrm_sba_write_descs(msg, nhcnt, reqid,
906 desc_ptr, toggle,
907 start_desc, end_desc);
908 default:
909 return ERR_PTR(-ENOTSUPP);
913 /* ====== FlexRM driver helper routines ===== */
915 static int flexrm_new_request(struct flexrm_ring *ring,
916 struct brcm_message *batch_msg,
917 struct brcm_message *msg)
919 void *next;
920 unsigned long flags;
921 u32 val, count, nhcnt;
922 u32 read_offset, write_offset;
923 bool exit_cleanup = false;
924 int ret = 0, reqid;
926 /* Do sanity check on message */
927 if (!flexrm_sanity_check(msg))
928 return -EIO;
929 msg->error = 0;
931 /* If no requests possible then save data pointer and goto done. */
932 reqid = ida_simple_get(&ring->requests_ida, 0,
933 RING_MAX_REQ_COUNT, GFP_KERNEL);
934 if (reqid < 0) {
935 spin_lock_irqsave(&ring->lock, flags);
936 if (batch_msg)
937 ring->last_pending_msg = batch_msg;
938 else
939 ring->last_pending_msg = msg;
940 spin_unlock_irqrestore(&ring->lock, flags);
941 return 0;
943 ring->requests[reqid] = msg;
945 /* Do DMA mappings for the message */
946 ret = flexrm_dma_map(ring->mbox->dev, msg);
947 if (ret < 0) {
948 ring->requests[reqid] = NULL;
949 ida_simple_remove(&ring->requests_ida, reqid);
950 return ret;
953 /* If last_pending_msg is already set then goto done with error */
954 spin_lock_irqsave(&ring->lock, flags);
955 if (ring->last_pending_msg)
956 ret = -ENOSPC;
957 spin_unlock_irqrestore(&ring->lock, flags);
958 if (ret < 0) {
959 dev_warn(ring->mbox->dev, "no space in ring %d\n", ring->num);
960 exit_cleanup = true;
961 goto exit;
964 /* Determine current HW BD read offset */
965 read_offset = readl_relaxed(ring->regs + RING_BD_READ_PTR);
966 val = readl_relaxed(ring->regs + RING_BD_START_ADDR);
967 read_offset *= RING_DESC_SIZE;
968 read_offset += (u32)(BD_START_ADDR_DECODE(val) - ring->bd_dma_base);
971 * Number required descriptors = number of non-header descriptors +
972 * number of header descriptors +
973 * 1x null descriptor
975 nhcnt = flexrm_estimate_nonheader_desc_count(msg);
976 count = flexrm_estimate_header_desc_count(nhcnt) + nhcnt + 1;
978 /* Check for available descriptor space. */
979 write_offset = ring->bd_write_offset;
980 while (count) {
981 if (!flexrm_is_next_table_desc(ring->bd_base + write_offset))
982 count--;
983 write_offset += RING_DESC_SIZE;
984 if (write_offset == RING_BD_SIZE)
985 write_offset = 0x0;
986 if (write_offset == read_offset)
987 break;
989 if (count) {
990 spin_lock_irqsave(&ring->lock, flags);
991 if (batch_msg)
992 ring->last_pending_msg = batch_msg;
993 else
994 ring->last_pending_msg = msg;
995 spin_unlock_irqrestore(&ring->lock, flags);
996 ret = 0;
997 exit_cleanup = true;
998 goto exit;
1001 /* Write descriptors to ring */
1002 next = flexrm_write_descs(msg, nhcnt, reqid,
1003 ring->bd_base + ring->bd_write_offset,
1004 RING_BD_TOGGLE_VALID(ring->bd_write_offset),
1005 ring->bd_base, ring->bd_base + RING_BD_SIZE);
1006 if (IS_ERR(next)) {
1007 ret = PTR_ERR(next);
1008 exit_cleanup = true;
1009 goto exit;
1012 /* Save ring BD write offset */
1013 ring->bd_write_offset = (unsigned long)(next - ring->bd_base);
1015 exit:
1016 /* Update error status in message */
1017 msg->error = ret;
1019 /* Cleanup if we failed */
1020 if (exit_cleanup) {
1021 flexrm_dma_unmap(ring->mbox->dev, msg);
1022 ring->requests[reqid] = NULL;
1023 ida_simple_remove(&ring->requests_ida, reqid);
1026 return ret;
1029 static int flexrm_process_completions(struct flexrm_ring *ring)
1031 u64 desc;
1032 int err, count = 0;
1033 unsigned long flags;
1034 struct brcm_message *msg = NULL;
1035 u32 reqid, cmpl_read_offset, cmpl_write_offset;
1036 struct mbox_chan *chan = &ring->mbox->controller.chans[ring->num];
1038 spin_lock_irqsave(&ring->lock, flags);
1040 /* Check last_pending_msg */
1041 if (ring->last_pending_msg) {
1042 msg = ring->last_pending_msg;
1043 ring->last_pending_msg = NULL;
1047 * Get current completion read and write offset
1049 * Note: We should read completion write pointer atleast once
1050 * after we get a MSI interrupt because HW maintains internal
1051 * MSI status which will allow next MSI interrupt only after
1052 * completion write pointer is read.
1054 cmpl_write_offset = readl_relaxed(ring->regs + RING_CMPL_WRITE_PTR);
1055 cmpl_write_offset *= RING_DESC_SIZE;
1056 cmpl_read_offset = ring->cmpl_read_offset;
1057 ring->cmpl_read_offset = cmpl_write_offset;
1059 spin_unlock_irqrestore(&ring->lock, flags);
1061 /* If last_pending_msg was set then queue it back */
1062 if (msg)
1063 mbox_send_message(chan, msg);
1065 /* For each completed request notify mailbox clients */
1066 reqid = 0;
1067 while (cmpl_read_offset != cmpl_write_offset) {
1068 /* Dequeue next completion descriptor */
1069 desc = *((u64 *)(ring->cmpl_base + cmpl_read_offset));
1071 /* Next read offset */
1072 cmpl_read_offset += RING_DESC_SIZE;
1073 if (cmpl_read_offset == RING_CMPL_SIZE)
1074 cmpl_read_offset = 0;
1076 /* Decode error from completion descriptor */
1077 err = flexrm_cmpl_desc_to_error(desc);
1078 if (err < 0) {
1079 dev_warn(ring->mbox->dev,
1080 "got completion desc=0x%lx with error %d",
1081 (unsigned long)desc, err);
1084 /* Determine request id from completion descriptor */
1085 reqid = flexrm_cmpl_desc_to_reqid(desc);
1087 /* Determine message pointer based on reqid */
1088 msg = ring->requests[reqid];
1089 if (!msg) {
1090 dev_warn(ring->mbox->dev,
1091 "null msg pointer for completion desc=0x%lx",
1092 (unsigned long)desc);
1093 continue;
1096 /* Release reqid for recycling */
1097 ring->requests[reqid] = NULL;
1098 ida_simple_remove(&ring->requests_ida, reqid);
1100 /* Unmap DMA mappings */
1101 flexrm_dma_unmap(ring->mbox->dev, msg);
1103 /* Give-back message to mailbox client */
1104 msg->error = err;
1105 mbox_chan_received_data(chan, msg);
1107 /* Increment number of completions processed */
1108 count++;
1111 return count;
1114 /* ====== FlexRM interrupt handler ===== */
1116 static irqreturn_t flexrm_irq_event(int irq, void *dev_id)
1118 /* We only have MSI for completions so just wakeup IRQ thread */
1119 /* Ring related errors will be informed via completion descriptors */
1121 return IRQ_WAKE_THREAD;
1124 static irqreturn_t flexrm_irq_thread(int irq, void *dev_id)
1126 flexrm_process_completions(dev_id);
1128 return IRQ_HANDLED;
1131 /* ====== FlexRM mailbox callbacks ===== */
1133 static int flexrm_send_data(struct mbox_chan *chan, void *data)
1135 int i, rc;
1136 struct flexrm_ring *ring = chan->con_priv;
1137 struct brcm_message *msg = data;
1139 if (msg->type == BRCM_MESSAGE_BATCH) {
1140 for (i = msg->batch.msgs_queued;
1141 i < msg->batch.msgs_count; i++) {
1142 rc = flexrm_new_request(ring, msg,
1143 &msg->batch.msgs[i]);
1144 if (rc) {
1145 msg->error = rc;
1146 return rc;
1148 msg->batch.msgs_queued++;
1150 return 0;
1153 return flexrm_new_request(ring, NULL, data);
1156 static bool flexrm_peek_data(struct mbox_chan *chan)
1158 int cnt = flexrm_process_completions(chan->con_priv);
1160 return (cnt > 0) ? true : false;
1163 static int flexrm_startup(struct mbox_chan *chan)
1165 u64 d;
1166 u32 val, off;
1167 int ret = 0;
1168 dma_addr_t next_addr;
1169 struct flexrm_ring *ring = chan->con_priv;
1171 /* Allocate BD memory */
1172 ring->bd_base = dma_pool_alloc(ring->mbox->bd_pool,
1173 GFP_KERNEL, &ring->bd_dma_base);
1174 if (!ring->bd_base) {
1175 dev_err(ring->mbox->dev, "can't allocate BD memory\n");
1176 ret = -ENOMEM;
1177 goto fail;
1180 /* Configure next table pointer entries in BD memory */
1181 for (off = 0; off < RING_BD_SIZE; off += RING_DESC_SIZE) {
1182 next_addr = off + RING_DESC_SIZE;
1183 if (next_addr == RING_BD_SIZE)
1184 next_addr = 0;
1185 next_addr += ring->bd_dma_base;
1186 if (RING_BD_ALIGN_CHECK(next_addr))
1187 d = flexrm_next_table_desc(RING_BD_TOGGLE_VALID(off),
1188 next_addr);
1189 else
1190 d = flexrm_null_desc(RING_BD_TOGGLE_INVALID(off));
1191 flexrm_write_desc(ring->bd_base + off, d);
1194 /* Allocate completion memory */
1195 ring->cmpl_base = dma_pool_alloc(ring->mbox->cmpl_pool,
1196 GFP_KERNEL, &ring->cmpl_dma_base);
1197 if (!ring->cmpl_base) {
1198 dev_err(ring->mbox->dev, "can't allocate completion memory\n");
1199 ret = -ENOMEM;
1200 goto fail_free_bd_memory;
1202 memset(ring->cmpl_base, 0, RING_CMPL_SIZE);
1204 /* Request IRQ */
1205 if (ring->irq == UINT_MAX) {
1206 dev_err(ring->mbox->dev, "ring IRQ not available\n");
1207 ret = -ENODEV;
1208 goto fail_free_cmpl_memory;
1210 ret = request_threaded_irq(ring->irq,
1211 flexrm_irq_event,
1212 flexrm_irq_thread,
1213 0, dev_name(ring->mbox->dev), ring);
1214 if (ret) {
1215 dev_err(ring->mbox->dev, "failed to request ring IRQ\n");
1216 goto fail_free_cmpl_memory;
1218 ring->irq_requested = true;
1220 /* Disable/inactivate ring */
1221 writel_relaxed(0x0, ring->regs + RING_CONTROL);
1223 /* Program BD start address */
1224 val = BD_START_ADDR_VALUE(ring->bd_dma_base);
1225 writel_relaxed(val, ring->regs + RING_BD_START_ADDR);
1227 /* BD write pointer will be same as HW write pointer */
1228 ring->bd_write_offset =
1229 readl_relaxed(ring->regs + RING_BD_WRITE_PTR);
1230 ring->bd_write_offset *= RING_DESC_SIZE;
1232 /* Program completion start address */
1233 val = CMPL_START_ADDR_VALUE(ring->cmpl_dma_base);
1234 writel_relaxed(val, ring->regs + RING_CMPL_START_ADDR);
1236 /* Ensure last pending message is cleared */
1237 ring->last_pending_msg = NULL;
1239 /* Completion read pointer will be same as HW write pointer */
1240 ring->cmpl_read_offset =
1241 readl_relaxed(ring->regs + RING_CMPL_WRITE_PTR);
1242 ring->cmpl_read_offset *= RING_DESC_SIZE;
1244 /* Read ring Tx, Rx, and Outstanding counts to clear */
1245 readl_relaxed(ring->regs + RING_NUM_REQ_RECV_LS);
1246 readl_relaxed(ring->regs + RING_NUM_REQ_RECV_MS);
1247 readl_relaxed(ring->regs + RING_NUM_REQ_TRANS_LS);
1248 readl_relaxed(ring->regs + RING_NUM_REQ_TRANS_MS);
1249 readl_relaxed(ring->regs + RING_NUM_REQ_OUTSTAND);
1251 /* Configure RING_MSI_CONTROL */
1252 val = 0;
1253 val |= (ring->msi_timer_val << MSI_TIMER_VAL_SHIFT);
1254 val |= BIT(MSI_ENABLE_SHIFT);
1255 val |= (ring->msi_count_threshold & MSI_COUNT_MASK) << MSI_COUNT_SHIFT;
1256 writel_relaxed(val, ring->regs + RING_MSI_CONTROL);
1258 /* Enable/activate ring */
1259 val = BIT(CONTROL_ACTIVE_SHIFT);
1260 writel_relaxed(val, ring->regs + RING_CONTROL);
1262 return 0;
1264 fail_free_cmpl_memory:
1265 dma_pool_free(ring->mbox->cmpl_pool,
1266 ring->cmpl_base, ring->cmpl_dma_base);
1267 ring->cmpl_base = NULL;
1268 fail_free_bd_memory:
1269 dma_pool_free(ring->mbox->bd_pool,
1270 ring->bd_base, ring->bd_dma_base);
1271 ring->bd_base = NULL;
1272 fail:
1273 return ret;
1276 static void flexrm_shutdown(struct mbox_chan *chan)
1278 u32 reqid;
1279 unsigned int timeout;
1280 struct brcm_message *msg;
1281 struct flexrm_ring *ring = chan->con_priv;
1283 /* Disable/inactivate ring */
1284 writel_relaxed(0x0, ring->regs + RING_CONTROL);
1286 /* Flush ring with timeout of 1s */
1287 timeout = 1000;
1288 writel_relaxed(BIT(CONTROL_FLUSH_SHIFT),
1289 ring->regs + RING_CONTROL);
1290 do {
1291 if (readl_relaxed(ring->regs + RING_FLUSH_DONE) &
1292 FLUSH_DONE_MASK)
1293 break;
1294 mdelay(1);
1295 } while (timeout--);
1297 /* Abort all in-flight requests */
1298 for (reqid = 0; reqid < RING_MAX_REQ_COUNT; reqid++) {
1299 msg = ring->requests[reqid];
1300 if (!msg)
1301 continue;
1303 /* Release reqid for recycling */
1304 ring->requests[reqid] = NULL;
1305 ida_simple_remove(&ring->requests_ida, reqid);
1307 /* Unmap DMA mappings */
1308 flexrm_dma_unmap(ring->mbox->dev, msg);
1310 /* Give-back message to mailbox client */
1311 msg->error = -EIO;
1312 mbox_chan_received_data(chan, msg);
1315 /* Release IRQ */
1316 if (ring->irq_requested) {
1317 free_irq(ring->irq, ring);
1318 ring->irq_requested = false;
1321 /* Free-up completion descriptor ring */
1322 if (ring->cmpl_base) {
1323 dma_pool_free(ring->mbox->cmpl_pool,
1324 ring->cmpl_base, ring->cmpl_dma_base);
1325 ring->cmpl_base = NULL;
1328 /* Free-up BD descriptor ring */
1329 if (ring->bd_base) {
1330 dma_pool_free(ring->mbox->bd_pool,
1331 ring->bd_base, ring->bd_dma_base);
1332 ring->bd_base = NULL;
1336 static bool flexrm_last_tx_done(struct mbox_chan *chan)
1338 bool ret;
1339 unsigned long flags;
1340 struct flexrm_ring *ring = chan->con_priv;
1342 spin_lock_irqsave(&ring->lock, flags);
1343 ret = (ring->last_pending_msg) ? false : true;
1344 spin_unlock_irqrestore(&ring->lock, flags);
1346 return ret;
1349 static const struct mbox_chan_ops flexrm_mbox_chan_ops = {
1350 .send_data = flexrm_send_data,
1351 .startup = flexrm_startup,
1352 .shutdown = flexrm_shutdown,
1353 .last_tx_done = flexrm_last_tx_done,
1354 .peek_data = flexrm_peek_data,
1357 static struct mbox_chan *flexrm_mbox_of_xlate(struct mbox_controller *cntlr,
1358 const struct of_phandle_args *pa)
1360 struct mbox_chan *chan;
1361 struct flexrm_ring *ring;
1363 if (pa->args_count < 3)
1364 return ERR_PTR(-EINVAL);
1366 if (pa->args[0] >= cntlr->num_chans)
1367 return ERR_PTR(-ENOENT);
1369 if (pa->args[1] > MSI_COUNT_MASK)
1370 return ERR_PTR(-EINVAL);
1372 if (pa->args[2] > MSI_TIMER_VAL_MASK)
1373 return ERR_PTR(-EINVAL);
1375 chan = &cntlr->chans[pa->args[0]];
1376 ring = chan->con_priv;
1377 ring->msi_count_threshold = pa->args[1];
1378 ring->msi_timer_val = pa->args[2];
1380 return chan;
1383 /* ====== FlexRM platform driver ===== */
1385 static void flexrm_mbox_msi_write(struct msi_desc *desc, struct msi_msg *msg)
1387 struct device *dev = msi_desc_to_dev(desc);
1388 struct flexrm_mbox *mbox = dev_get_drvdata(dev);
1389 struct flexrm_ring *ring = &mbox->rings[desc->platform.msi_index];
1391 /* Configure per-Ring MSI registers */
1392 writel_relaxed(msg->address_lo, ring->regs + RING_MSI_ADDR_LS);
1393 writel_relaxed(msg->address_hi, ring->regs + RING_MSI_ADDR_MS);
1394 writel_relaxed(msg->data, ring->regs + RING_MSI_DATA_VALUE);
1397 static int flexrm_mbox_probe(struct platform_device *pdev)
1399 int index, ret = 0;
1400 void __iomem *regs;
1401 void __iomem *regs_end;
1402 struct msi_desc *desc;
1403 struct resource *iomem;
1404 struct flexrm_ring *ring;
1405 struct flexrm_mbox *mbox;
1406 struct device *dev = &pdev->dev;
1408 /* Allocate driver mailbox struct */
1409 mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
1410 if (!mbox) {
1411 ret = -ENOMEM;
1412 goto fail;
1414 mbox->dev = dev;
1415 platform_set_drvdata(pdev, mbox);
1417 /* Get resource for registers */
1418 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1419 if (!iomem || (resource_size(iomem) < RING_REGS_SIZE)) {
1420 ret = -ENODEV;
1421 goto fail;
1424 /* Map registers of all rings */
1425 mbox->regs = devm_ioremap_resource(&pdev->dev, iomem);
1426 if (IS_ERR(mbox->regs)) {
1427 ret = PTR_ERR(mbox->regs);
1428 dev_err(&pdev->dev, "Failed to remap mailbox regs: %d\n", ret);
1429 goto fail;
1431 regs_end = mbox->regs + resource_size(iomem);
1433 /* Scan and count available rings */
1434 mbox->num_rings = 0;
1435 for (regs = mbox->regs; regs < regs_end; regs += RING_REGS_SIZE) {
1436 if (readl_relaxed(regs + RING_VER) == RING_VER_MAGIC)
1437 mbox->num_rings++;
1439 if (!mbox->num_rings) {
1440 ret = -ENODEV;
1441 goto fail;
1444 /* Allocate driver ring structs */
1445 ring = devm_kcalloc(dev, mbox->num_rings, sizeof(*ring), GFP_KERNEL);
1446 if (!ring) {
1447 ret = -ENOMEM;
1448 goto fail;
1450 mbox->rings = ring;
1452 /* Initialize members of driver ring structs */
1453 regs = mbox->regs;
1454 for (index = 0; index < mbox->num_rings; index++) {
1455 ring = &mbox->rings[index];
1456 ring->num = index;
1457 ring->mbox = mbox;
1458 while ((regs < regs_end) &&
1459 (readl_relaxed(regs + RING_VER) != RING_VER_MAGIC))
1460 regs += RING_REGS_SIZE;
1461 if (regs_end <= regs) {
1462 ret = -ENODEV;
1463 goto fail;
1465 ring->regs = regs;
1466 regs += RING_REGS_SIZE;
1467 ring->irq = UINT_MAX;
1468 ring->irq_requested = false;
1469 ring->msi_timer_val = MSI_TIMER_VAL_MASK;
1470 ring->msi_count_threshold = 0x1;
1471 ida_init(&ring->requests_ida);
1472 memset(ring->requests, 0, sizeof(ring->requests));
1473 ring->bd_base = NULL;
1474 ring->bd_dma_base = 0;
1475 ring->cmpl_base = NULL;
1476 ring->cmpl_dma_base = 0;
1477 spin_lock_init(&ring->lock);
1478 ring->last_pending_msg = NULL;
1479 ring->cmpl_read_offset = 0;
1482 /* FlexRM is capable of 40-bit physical addresses only */
1483 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
1484 if (ret) {
1485 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
1486 if (ret)
1487 goto fail;
1490 /* Create DMA pool for ring BD memory */
1491 mbox->bd_pool = dma_pool_create("bd", dev, RING_BD_SIZE,
1492 1 << RING_BD_ALIGN_ORDER, 0);
1493 if (!mbox->bd_pool) {
1494 ret = -ENOMEM;
1495 goto fail;
1498 /* Create DMA pool for ring completion memory */
1499 mbox->cmpl_pool = dma_pool_create("cmpl", dev, RING_CMPL_SIZE,
1500 1 << RING_CMPL_ALIGN_ORDER, 0);
1501 if (!mbox->cmpl_pool) {
1502 ret = -ENOMEM;
1503 goto fail_destroy_bd_pool;
1506 /* Allocate platform MSIs for each ring */
1507 ret = platform_msi_domain_alloc_irqs(dev, mbox->num_rings,
1508 flexrm_mbox_msi_write);
1509 if (ret)
1510 goto fail_destroy_cmpl_pool;
1512 /* Save alloced IRQ numbers for each ring */
1513 for_each_msi_entry(desc, dev) {
1514 ring = &mbox->rings[desc->platform.msi_index];
1515 ring->irq = desc->irq;
1518 /* Initialize mailbox controller */
1519 mbox->controller.txdone_irq = false;
1520 mbox->controller.txdone_poll = true;
1521 mbox->controller.txpoll_period = 1;
1522 mbox->controller.ops = &flexrm_mbox_chan_ops;
1523 mbox->controller.dev = dev;
1524 mbox->controller.num_chans = mbox->num_rings;
1525 mbox->controller.of_xlate = flexrm_mbox_of_xlate;
1526 mbox->controller.chans = devm_kcalloc(dev, mbox->num_rings,
1527 sizeof(*mbox->controller.chans), GFP_KERNEL);
1528 if (!mbox->controller.chans) {
1529 ret = -ENOMEM;
1530 goto fail_free_msis;
1532 for (index = 0; index < mbox->num_rings; index++)
1533 mbox->controller.chans[index].con_priv = &mbox->rings[index];
1535 /* Register mailbox controller */
1536 ret = mbox_controller_register(&mbox->controller);
1537 if (ret)
1538 goto fail_free_msis;
1540 dev_info(dev, "registered flexrm mailbox with %d channels\n",
1541 mbox->controller.num_chans);
1543 return 0;
1545 fail_free_msis:
1546 platform_msi_domain_free_irqs(dev);
1547 fail_destroy_cmpl_pool:
1548 dma_pool_destroy(mbox->cmpl_pool);
1549 fail_destroy_bd_pool:
1550 dma_pool_destroy(mbox->bd_pool);
1551 fail:
1552 return ret;
1555 static int flexrm_mbox_remove(struct platform_device *pdev)
1557 int index;
1558 struct device *dev = &pdev->dev;
1559 struct flexrm_ring *ring;
1560 struct flexrm_mbox *mbox = platform_get_drvdata(pdev);
1562 mbox_controller_unregister(&mbox->controller);
1564 platform_msi_domain_free_irqs(dev);
1566 dma_pool_destroy(mbox->cmpl_pool);
1567 dma_pool_destroy(mbox->bd_pool);
1569 for (index = 0; index < mbox->num_rings; index++) {
1570 ring = &mbox->rings[index];
1571 ida_destroy(&ring->requests_ida);
1574 return 0;
1577 static const struct of_device_id flexrm_mbox_of_match[] = {
1578 { .compatible = "brcm,iproc-flexrm-mbox", },
1581 MODULE_DEVICE_TABLE(of, flexrm_mbox_of_match);
1583 static struct platform_driver flexrm_mbox_driver = {
1584 .driver = {
1585 .name = "brcm-flexrm-mbox",
1586 .of_match_table = flexrm_mbox_of_match,
1588 .probe = flexrm_mbox_probe,
1589 .remove = flexrm_mbox_remove,
1591 module_platform_driver(flexrm_mbox_driver);
1593 MODULE_AUTHOR("Anup Patel <anup.patel@broadcom.com>");
1594 MODULE_DESCRIPTION("Broadcom FlexRM mailbox driver");
1595 MODULE_LICENSE("GPL v2");