1 // SPDX-License-Identifier: GPL-2.0-only
3 * offload engine driver for the Marvell XOR engine
4 * Copyright (C) 2007, 2008, Marvell International Ltd.
7 #include <linux/init.h>
8 #include <linux/slab.h>
9 #include <linux/delay.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/spinlock.h>
12 #include <linux/interrupt.h>
13 #include <linux/of_device.h>
14 #include <linux/platform_device.h>
15 #include <linux/memory.h>
16 #include <linux/clk.h>
18 #include <linux/of_irq.h>
19 #include <linux/irqdomain.h>
20 #include <linux/cpumask.h>
21 #include <linux/platform_data/dma-mv_xor.h>
23 #include "dmaengine.h"
37 static void mv_xor_issue_pending(struct dma_chan
*chan
);
39 #define to_mv_xor_chan(chan) \
40 container_of(chan, struct mv_xor_chan, dmachan)
42 #define to_mv_xor_slot(tx) \
43 container_of(tx, struct mv_xor_desc_slot, async_tx)
45 #define mv_chan_to_devp(chan) \
48 static void mv_desc_init(struct mv_xor_desc_slot
*desc
,
49 dma_addr_t addr
, u32 byte_count
,
50 enum dma_ctrl_flags flags
)
52 struct mv_xor_desc
*hw_desc
= desc
->hw_desc
;
54 hw_desc
->status
= XOR_DESC_DMA_OWNED
;
55 hw_desc
->phy_next_desc
= 0;
56 /* Enable end-of-descriptor interrupts only for DMA_PREP_INTERRUPT */
57 hw_desc
->desc_command
= (flags
& DMA_PREP_INTERRUPT
) ?
58 XOR_DESC_EOD_INT_EN
: 0;
59 hw_desc
->phy_dest_addr
= addr
;
60 hw_desc
->byte_count
= byte_count
;
63 static void mv_desc_set_mode(struct mv_xor_desc_slot
*desc
)
65 struct mv_xor_desc
*hw_desc
= desc
->hw_desc
;
70 hw_desc
->desc_command
|= XOR_DESC_OPERATION_XOR
;
73 hw_desc
->desc_command
|= XOR_DESC_OPERATION_MEMCPY
;
81 static void mv_desc_set_next_desc(struct mv_xor_desc_slot
*desc
,
84 struct mv_xor_desc
*hw_desc
= desc
->hw_desc
;
85 BUG_ON(hw_desc
->phy_next_desc
);
86 hw_desc
->phy_next_desc
= next_desc_addr
;
89 static void mv_desc_set_src_addr(struct mv_xor_desc_slot
*desc
,
90 int index
, dma_addr_t addr
)
92 struct mv_xor_desc
*hw_desc
= desc
->hw_desc
;
93 hw_desc
->phy_src_addr
[mv_phy_src_idx(index
)] = addr
;
94 if (desc
->type
== DMA_XOR
)
95 hw_desc
->desc_command
|= (1 << index
);
98 static u32
mv_chan_get_current_desc(struct mv_xor_chan
*chan
)
100 return readl_relaxed(XOR_CURR_DESC(chan
));
103 static void mv_chan_set_next_descriptor(struct mv_xor_chan
*chan
,
106 writel_relaxed(next_desc_addr
, XOR_NEXT_DESC(chan
));
109 static void mv_chan_unmask_interrupts(struct mv_xor_chan
*chan
)
111 u32 val
= readl_relaxed(XOR_INTR_MASK(chan
));
112 val
|= XOR_INTR_MASK_VALUE
<< (chan
->idx
* 16);
113 writel_relaxed(val
, XOR_INTR_MASK(chan
));
116 static u32
mv_chan_get_intr_cause(struct mv_xor_chan
*chan
)
118 u32 intr_cause
= readl_relaxed(XOR_INTR_CAUSE(chan
));
119 intr_cause
= (intr_cause
>> (chan
->idx
* 16)) & 0xFFFF;
123 static void mv_chan_clear_eoc_cause(struct mv_xor_chan
*chan
)
127 val
= XOR_INT_END_OF_DESC
| XOR_INT_END_OF_CHAIN
| XOR_INT_STOPPED
;
128 val
= ~(val
<< (chan
->idx
* 16));
129 dev_dbg(mv_chan_to_devp(chan
), "%s, val 0x%08x\n", __func__
, val
);
130 writel_relaxed(val
, XOR_INTR_CAUSE(chan
));
133 static void mv_chan_clear_err_status(struct mv_xor_chan
*chan
)
135 u32 val
= 0xFFFF0000 >> (chan
->idx
* 16);
136 writel_relaxed(val
, XOR_INTR_CAUSE(chan
));
139 static void mv_chan_set_mode(struct mv_xor_chan
*chan
,
142 u32 config
= readl_relaxed(XOR_CONFIG(chan
));
147 #if defined(__BIG_ENDIAN)
148 config
|= XOR_DESCRIPTOR_SWAP
;
150 config
&= ~XOR_DESCRIPTOR_SWAP
;
153 writel_relaxed(config
, XOR_CONFIG(chan
));
156 static void mv_chan_activate(struct mv_xor_chan
*chan
)
158 dev_dbg(mv_chan_to_devp(chan
), " activate chan.\n");
160 /* writel ensures all descriptors are flushed before activation */
161 writel(BIT(0), XOR_ACTIVATION(chan
));
164 static char mv_chan_is_busy(struct mv_xor_chan
*chan
)
166 u32 state
= readl_relaxed(XOR_ACTIVATION(chan
));
168 state
= (state
>> 4) & 0x3;
170 return (state
== 1) ? 1 : 0;
174 * mv_chan_start_new_chain - program the engine to operate on new
175 * chain headed by sw_desc
176 * Caller must hold &mv_chan->lock while calling this function
178 static void mv_chan_start_new_chain(struct mv_xor_chan
*mv_chan
,
179 struct mv_xor_desc_slot
*sw_desc
)
181 dev_dbg(mv_chan_to_devp(mv_chan
), "%s %d: sw_desc %p\n",
182 __func__
, __LINE__
, sw_desc
);
184 /* set the hardware chain */
185 mv_chan_set_next_descriptor(mv_chan
, sw_desc
->async_tx
.phys
);
188 mv_xor_issue_pending(&mv_chan
->dmachan
);
192 mv_desc_run_tx_complete_actions(struct mv_xor_desc_slot
*desc
,
193 struct mv_xor_chan
*mv_chan
,
196 BUG_ON(desc
->async_tx
.cookie
< 0);
198 if (desc
->async_tx
.cookie
> 0) {
199 cookie
= desc
->async_tx
.cookie
;
201 dma_descriptor_unmap(&desc
->async_tx
);
202 /* call the callback (must not sleep or submit new
203 * operations to this channel)
205 dmaengine_desc_get_callback_invoke(&desc
->async_tx
, NULL
);
208 /* run dependent operations */
209 dma_run_dependencies(&desc
->async_tx
);
215 mv_chan_clean_completed_slots(struct mv_xor_chan
*mv_chan
)
217 struct mv_xor_desc_slot
*iter
, *_iter
;
219 dev_dbg(mv_chan_to_devp(mv_chan
), "%s %d\n", __func__
, __LINE__
);
220 list_for_each_entry_safe(iter
, _iter
, &mv_chan
->completed_slots
,
223 if (async_tx_test_ack(&iter
->async_tx
)) {
224 list_move_tail(&iter
->node
, &mv_chan
->free_slots
);
225 if (!list_empty(&iter
->sg_tx_list
)) {
226 list_splice_tail_init(&iter
->sg_tx_list
,
227 &mv_chan
->free_slots
);
235 mv_desc_clean_slot(struct mv_xor_desc_slot
*desc
,
236 struct mv_xor_chan
*mv_chan
)
238 dev_dbg(mv_chan_to_devp(mv_chan
), "%s %d: desc %p flags %d\n",
239 __func__
, __LINE__
, desc
, desc
->async_tx
.flags
);
241 /* the client is allowed to attach dependent operations
244 if (!async_tx_test_ack(&desc
->async_tx
)) {
245 /* move this slot to the completed_slots */
246 list_move_tail(&desc
->node
, &mv_chan
->completed_slots
);
247 if (!list_empty(&desc
->sg_tx_list
)) {
248 list_splice_tail_init(&desc
->sg_tx_list
,
249 &mv_chan
->completed_slots
);
252 list_move_tail(&desc
->node
, &mv_chan
->free_slots
);
253 if (!list_empty(&desc
->sg_tx_list
)) {
254 list_splice_tail_init(&desc
->sg_tx_list
,
255 &mv_chan
->free_slots
);
262 /* This function must be called with the mv_xor_chan spinlock held */
263 static void mv_chan_slot_cleanup(struct mv_xor_chan
*mv_chan
)
265 struct mv_xor_desc_slot
*iter
, *_iter
;
266 dma_cookie_t cookie
= 0;
267 int busy
= mv_chan_is_busy(mv_chan
);
268 u32 current_desc
= mv_chan_get_current_desc(mv_chan
);
269 int current_cleaned
= 0;
270 struct mv_xor_desc
*hw_desc
;
272 dev_dbg(mv_chan_to_devp(mv_chan
), "%s %d\n", __func__
, __LINE__
);
273 dev_dbg(mv_chan_to_devp(mv_chan
), "current_desc %x\n", current_desc
);
274 mv_chan_clean_completed_slots(mv_chan
);
276 /* free completed slots from the chain starting with
277 * the oldest descriptor
280 list_for_each_entry_safe(iter
, _iter
, &mv_chan
->chain
,
283 /* clean finished descriptors */
284 hw_desc
= iter
->hw_desc
;
285 if (hw_desc
->status
& XOR_DESC_SUCCESS
) {
286 cookie
= mv_desc_run_tx_complete_actions(iter
, mv_chan
,
289 /* done processing desc, clean slot */
290 mv_desc_clean_slot(iter
, mv_chan
);
292 /* break if we did cleaned the current */
293 if (iter
->async_tx
.phys
== current_desc
) {
298 if (iter
->async_tx
.phys
== current_desc
) {
305 if ((busy
== 0) && !list_empty(&mv_chan
->chain
)) {
306 if (current_cleaned
) {
308 * current descriptor cleaned and removed, run
311 iter
= list_entry(mv_chan
->chain
.next
,
312 struct mv_xor_desc_slot
,
314 mv_chan_start_new_chain(mv_chan
, iter
);
316 if (!list_is_last(&iter
->node
, &mv_chan
->chain
)) {
318 * descriptors are still waiting after
319 * current, trigger them
321 iter
= list_entry(iter
->node
.next
,
322 struct mv_xor_desc_slot
,
324 mv_chan_start_new_chain(mv_chan
, iter
);
327 * some descriptors are still waiting
330 tasklet_schedule(&mv_chan
->irq_tasklet
);
336 mv_chan
->dmachan
.completed_cookie
= cookie
;
339 static void mv_xor_tasklet(unsigned long data
)
341 struct mv_xor_chan
*chan
= (struct mv_xor_chan
*) data
;
343 spin_lock(&chan
->lock
);
344 mv_chan_slot_cleanup(chan
);
345 spin_unlock(&chan
->lock
);
348 static struct mv_xor_desc_slot
*
349 mv_chan_alloc_slot(struct mv_xor_chan
*mv_chan
)
351 struct mv_xor_desc_slot
*iter
;
353 spin_lock_bh(&mv_chan
->lock
);
355 if (!list_empty(&mv_chan
->free_slots
)) {
356 iter
= list_first_entry(&mv_chan
->free_slots
,
357 struct mv_xor_desc_slot
,
360 list_move_tail(&iter
->node
, &mv_chan
->allocated_slots
);
362 spin_unlock_bh(&mv_chan
->lock
);
364 /* pre-ack descriptor */
365 async_tx_ack(&iter
->async_tx
);
366 iter
->async_tx
.cookie
= -EBUSY
;
372 spin_unlock_bh(&mv_chan
->lock
);
374 /* try to free some slots if the allocation fails */
375 tasklet_schedule(&mv_chan
->irq_tasklet
);
380 /************************ DMA engine API functions ****************************/
382 mv_xor_tx_submit(struct dma_async_tx_descriptor
*tx
)
384 struct mv_xor_desc_slot
*sw_desc
= to_mv_xor_slot(tx
);
385 struct mv_xor_chan
*mv_chan
= to_mv_xor_chan(tx
->chan
);
386 struct mv_xor_desc_slot
*old_chain_tail
;
388 int new_hw_chain
= 1;
390 dev_dbg(mv_chan_to_devp(mv_chan
),
391 "%s sw_desc %p: async_tx %p\n",
392 __func__
, sw_desc
, &sw_desc
->async_tx
);
394 spin_lock_bh(&mv_chan
->lock
);
395 cookie
= dma_cookie_assign(tx
);
397 if (list_empty(&mv_chan
->chain
))
398 list_move_tail(&sw_desc
->node
, &mv_chan
->chain
);
402 old_chain_tail
= list_entry(mv_chan
->chain
.prev
,
403 struct mv_xor_desc_slot
,
405 list_move_tail(&sw_desc
->node
, &mv_chan
->chain
);
407 dev_dbg(mv_chan_to_devp(mv_chan
), "Append to last desc %pa\n",
408 &old_chain_tail
->async_tx
.phys
);
410 /* fix up the hardware chain */
411 mv_desc_set_next_desc(old_chain_tail
, sw_desc
->async_tx
.phys
);
413 /* if the channel is not busy */
414 if (!mv_chan_is_busy(mv_chan
)) {
415 u32 current_desc
= mv_chan_get_current_desc(mv_chan
);
417 * and the curren desc is the end of the chain before
418 * the append, then we need to start the channel
420 if (current_desc
== old_chain_tail
->async_tx
.phys
)
426 mv_chan_start_new_chain(mv_chan
, sw_desc
);
428 spin_unlock_bh(&mv_chan
->lock
);
433 /* returns the number of allocated descriptors */
434 static int mv_xor_alloc_chan_resources(struct dma_chan
*chan
)
439 struct mv_xor_chan
*mv_chan
= to_mv_xor_chan(chan
);
440 struct mv_xor_desc_slot
*slot
= NULL
;
441 int num_descs_in_pool
= MV_XOR_POOL_SIZE
/MV_XOR_SLOT_SIZE
;
443 /* Allocate descriptor slots */
444 idx
= mv_chan
->slots_allocated
;
445 while (idx
< num_descs_in_pool
) {
446 slot
= kzalloc(sizeof(*slot
), GFP_KERNEL
);
448 dev_info(mv_chan_to_devp(mv_chan
),
449 "channel only initialized %d descriptor slots",
453 virt_desc
= mv_chan
->dma_desc_pool_virt
;
454 slot
->hw_desc
= virt_desc
+ idx
* MV_XOR_SLOT_SIZE
;
456 dma_async_tx_descriptor_init(&slot
->async_tx
, chan
);
457 slot
->async_tx
.tx_submit
= mv_xor_tx_submit
;
458 INIT_LIST_HEAD(&slot
->node
);
459 INIT_LIST_HEAD(&slot
->sg_tx_list
);
460 dma_desc
= mv_chan
->dma_desc_pool
;
461 slot
->async_tx
.phys
= dma_desc
+ idx
* MV_XOR_SLOT_SIZE
;
464 spin_lock_bh(&mv_chan
->lock
);
465 mv_chan
->slots_allocated
= idx
;
466 list_add_tail(&slot
->node
, &mv_chan
->free_slots
);
467 spin_unlock_bh(&mv_chan
->lock
);
470 dev_dbg(mv_chan_to_devp(mv_chan
),
471 "allocated %d descriptor slots\n",
472 mv_chan
->slots_allocated
);
474 return mv_chan
->slots_allocated
? : -ENOMEM
;
478 * Check if source or destination is an PCIe/IO address (non-SDRAM) and add
479 * a new MBus window if necessary. Use a cache for these check so that
480 * the MMIO mapped registers don't have to be accessed for this check
481 * to speed up this process.
483 static int mv_xor_add_io_win(struct mv_xor_chan
*mv_chan
, u32 addr
)
485 struct mv_xor_device
*xordev
= mv_chan
->xordev
;
486 void __iomem
*base
= mv_chan
->mmr_high_base
;
493 /* Nothing needs to get done for the Armada 3700 */
494 if (xordev
->xor_type
== XOR_ARMADA_37XX
)
498 * Loop over the cached windows to check, if the requested area
499 * is already mapped. If this the case, nothing needs to be done
502 for (i
= 0; i
< WINDOW_COUNT
; i
++) {
503 if (addr
>= xordev
->win_start
[i
] &&
504 addr
<= xordev
->win_end
[i
]) {
505 /* Window is already mapped */
511 * The window is not mapped, so we need to create the new mapping
514 /* If no IO window is found that addr has to be located in SDRAM */
515 ret
= mvebu_mbus_get_io_win_info(addr
, &size
, &target
, &attr
);
520 * Mask the base addr 'addr' according to 'size' read back from the
521 * MBus window. Otherwise we might end up with an address located
522 * somewhere in the middle of this area here.
528 * Reading one of both enabled register is enough, as they are always
529 * programmed to the identical values
531 win_enable
= readl(base
+ WINDOW_BAR_ENABLE(0));
533 /* Set 'i' to the first free window to write the new values to */
534 i
= ffs(~win_enable
) - 1;
535 if (i
>= WINDOW_COUNT
)
538 writel((addr
& 0xffff0000) | (attr
<< 8) | target
,
539 base
+ WINDOW_BASE(i
));
540 writel(size
& 0xffff0000, base
+ WINDOW_SIZE(i
));
542 /* Fill the caching variables for later use */
543 xordev
->win_start
[i
] = addr
;
544 xordev
->win_end
[i
] = addr
+ size
;
546 win_enable
|= (1 << i
);
547 win_enable
|= 3 << (16 + (2 * i
));
548 writel(win_enable
, base
+ WINDOW_BAR_ENABLE(0));
549 writel(win_enable
, base
+ WINDOW_BAR_ENABLE(1));
554 static struct dma_async_tx_descriptor
*
555 mv_xor_prep_dma_xor(struct dma_chan
*chan
, dma_addr_t dest
, dma_addr_t
*src
,
556 unsigned int src_cnt
, size_t len
, unsigned long flags
)
558 struct mv_xor_chan
*mv_chan
= to_mv_xor_chan(chan
);
559 struct mv_xor_desc_slot
*sw_desc
;
562 if (unlikely(len
< MV_XOR_MIN_BYTE_COUNT
))
565 BUG_ON(len
> MV_XOR_MAX_BYTE_COUNT
);
567 dev_dbg(mv_chan_to_devp(mv_chan
),
568 "%s src_cnt: %d len: %zu dest %pad flags: %ld\n",
569 __func__
, src_cnt
, len
, &dest
, flags
);
571 /* Check if a new window needs to get added for 'dest' */
572 ret
= mv_xor_add_io_win(mv_chan
, dest
);
576 sw_desc
= mv_chan_alloc_slot(mv_chan
);
578 sw_desc
->type
= DMA_XOR
;
579 sw_desc
->async_tx
.flags
= flags
;
580 mv_desc_init(sw_desc
, dest
, len
, flags
);
581 if (mv_chan
->op_in_desc
== XOR_MODE_IN_DESC
)
582 mv_desc_set_mode(sw_desc
);
584 /* Check if a new window needs to get added for 'src' */
585 ret
= mv_xor_add_io_win(mv_chan
, src
[src_cnt
]);
588 mv_desc_set_src_addr(sw_desc
, src_cnt
, src
[src_cnt
]);
592 dev_dbg(mv_chan_to_devp(mv_chan
),
593 "%s sw_desc %p async_tx %p \n",
594 __func__
, sw_desc
, &sw_desc
->async_tx
);
595 return sw_desc
? &sw_desc
->async_tx
: NULL
;
598 static struct dma_async_tx_descriptor
*
599 mv_xor_prep_dma_memcpy(struct dma_chan
*chan
, dma_addr_t dest
, dma_addr_t src
,
600 size_t len
, unsigned long flags
)
603 * A MEMCPY operation is identical to an XOR operation with only
604 * a single source address.
606 return mv_xor_prep_dma_xor(chan
, dest
, &src
, 1, len
, flags
);
609 static struct dma_async_tx_descriptor
*
610 mv_xor_prep_dma_interrupt(struct dma_chan
*chan
, unsigned long flags
)
612 struct mv_xor_chan
*mv_chan
= to_mv_xor_chan(chan
);
613 dma_addr_t src
, dest
;
616 src
= mv_chan
->dummy_src_addr
;
617 dest
= mv_chan
->dummy_dst_addr
;
618 len
= MV_XOR_MIN_BYTE_COUNT
;
621 * We implement the DMA_INTERRUPT operation as a minimum sized
622 * XOR operation with a single dummy source address.
624 return mv_xor_prep_dma_xor(chan
, dest
, &src
, 1, len
, flags
);
627 static void mv_xor_free_chan_resources(struct dma_chan
*chan
)
629 struct mv_xor_chan
*mv_chan
= to_mv_xor_chan(chan
);
630 struct mv_xor_desc_slot
*iter
, *_iter
;
631 int in_use_descs
= 0;
633 spin_lock_bh(&mv_chan
->lock
);
635 mv_chan_slot_cleanup(mv_chan
);
637 list_for_each_entry_safe(iter
, _iter
, &mv_chan
->chain
,
640 list_move_tail(&iter
->node
, &mv_chan
->free_slots
);
642 list_for_each_entry_safe(iter
, _iter
, &mv_chan
->completed_slots
,
645 list_move_tail(&iter
->node
, &mv_chan
->free_slots
);
647 list_for_each_entry_safe(iter
, _iter
, &mv_chan
->allocated_slots
,
650 list_move_tail(&iter
->node
, &mv_chan
->free_slots
);
652 list_for_each_entry_safe_reverse(
653 iter
, _iter
, &mv_chan
->free_slots
, node
) {
654 list_del(&iter
->node
);
656 mv_chan
->slots_allocated
--;
659 dev_dbg(mv_chan_to_devp(mv_chan
), "%s slots_allocated %d\n",
660 __func__
, mv_chan
->slots_allocated
);
661 spin_unlock_bh(&mv_chan
->lock
);
664 dev_err(mv_chan_to_devp(mv_chan
),
665 "freeing %d in use descriptors!\n", in_use_descs
);
669 * mv_xor_status - poll the status of an XOR transaction
670 * @chan: XOR channel handle
671 * @cookie: XOR transaction identifier
672 * @txstate: XOR transactions state holder (or NULL)
674 static enum dma_status
mv_xor_status(struct dma_chan
*chan
,
676 struct dma_tx_state
*txstate
)
678 struct mv_xor_chan
*mv_chan
= to_mv_xor_chan(chan
);
681 ret
= dma_cookie_status(chan
, cookie
, txstate
);
682 if (ret
== DMA_COMPLETE
)
685 spin_lock_bh(&mv_chan
->lock
);
686 mv_chan_slot_cleanup(mv_chan
);
687 spin_unlock_bh(&mv_chan
->lock
);
689 return dma_cookie_status(chan
, cookie
, txstate
);
692 static void mv_chan_dump_regs(struct mv_xor_chan
*chan
)
696 val
= readl_relaxed(XOR_CONFIG(chan
));
697 dev_err(mv_chan_to_devp(chan
), "config 0x%08x\n", val
);
699 val
= readl_relaxed(XOR_ACTIVATION(chan
));
700 dev_err(mv_chan_to_devp(chan
), "activation 0x%08x\n", val
);
702 val
= readl_relaxed(XOR_INTR_CAUSE(chan
));
703 dev_err(mv_chan_to_devp(chan
), "intr cause 0x%08x\n", val
);
705 val
= readl_relaxed(XOR_INTR_MASK(chan
));
706 dev_err(mv_chan_to_devp(chan
), "intr mask 0x%08x\n", val
);
708 val
= readl_relaxed(XOR_ERROR_CAUSE(chan
));
709 dev_err(mv_chan_to_devp(chan
), "error cause 0x%08x\n", val
);
711 val
= readl_relaxed(XOR_ERROR_ADDR(chan
));
712 dev_err(mv_chan_to_devp(chan
), "error addr 0x%08x\n", val
);
715 static void mv_chan_err_interrupt_handler(struct mv_xor_chan
*chan
,
718 if (intr_cause
& XOR_INT_ERR_DECODE
) {
719 dev_dbg(mv_chan_to_devp(chan
), "ignoring address decode error\n");
723 dev_err(mv_chan_to_devp(chan
), "error on chan %d. intr cause 0x%08x\n",
724 chan
->idx
, intr_cause
);
726 mv_chan_dump_regs(chan
);
730 static irqreturn_t
mv_xor_interrupt_handler(int irq
, void *data
)
732 struct mv_xor_chan
*chan
= data
;
733 u32 intr_cause
= mv_chan_get_intr_cause(chan
);
735 dev_dbg(mv_chan_to_devp(chan
), "intr cause %x\n", intr_cause
);
737 if (intr_cause
& XOR_INTR_ERRORS
)
738 mv_chan_err_interrupt_handler(chan
, intr_cause
);
740 tasklet_schedule(&chan
->irq_tasklet
);
742 mv_chan_clear_eoc_cause(chan
);
747 static void mv_xor_issue_pending(struct dma_chan
*chan
)
749 struct mv_xor_chan
*mv_chan
= to_mv_xor_chan(chan
);
751 if (mv_chan
->pending
>= MV_XOR_THRESHOLD
) {
752 mv_chan
->pending
= 0;
753 mv_chan_activate(mv_chan
);
758 * Perform a transaction to verify the HW works.
761 static int mv_chan_memcpy_self_test(struct mv_xor_chan
*mv_chan
)
765 dma_addr_t src_dma
, dest_dma
;
766 struct dma_chan
*dma_chan
;
768 struct dma_async_tx_descriptor
*tx
;
769 struct dmaengine_unmap_data
*unmap
;
772 src
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
776 dest
= kzalloc(PAGE_SIZE
, GFP_KERNEL
);
782 /* Fill in src buffer */
783 for (i
= 0; i
< PAGE_SIZE
; i
++)
784 ((u8
*) src
)[i
] = (u8
)i
;
786 dma_chan
= &mv_chan
->dmachan
;
787 if (mv_xor_alloc_chan_resources(dma_chan
) < 1) {
792 unmap
= dmaengine_get_unmap_data(dma_chan
->device
->dev
, 2, GFP_KERNEL
);
798 src_dma
= dma_map_page(dma_chan
->device
->dev
, virt_to_page(src
),
799 offset_in_page(src
), PAGE_SIZE
,
801 unmap
->addr
[0] = src_dma
;
803 ret
= dma_mapping_error(dma_chan
->device
->dev
, src_dma
);
810 dest_dma
= dma_map_page(dma_chan
->device
->dev
, virt_to_page(dest
),
811 offset_in_page(dest
), PAGE_SIZE
,
813 unmap
->addr
[1] = dest_dma
;
815 ret
= dma_mapping_error(dma_chan
->device
->dev
, dest_dma
);
821 unmap
->len
= PAGE_SIZE
;
823 tx
= mv_xor_prep_dma_memcpy(dma_chan
, dest_dma
, src_dma
,
826 dev_err(dma_chan
->device
->dev
,
827 "Self-test cannot prepare operation, disabling\n");
832 cookie
= mv_xor_tx_submit(tx
);
833 if (dma_submit_error(cookie
)) {
834 dev_err(dma_chan
->device
->dev
,
835 "Self-test submit error, disabling\n");
840 mv_xor_issue_pending(dma_chan
);
844 if (mv_xor_status(dma_chan
, cookie
, NULL
) !=
846 dev_err(dma_chan
->device
->dev
,
847 "Self-test copy timed out, disabling\n");
852 dma_sync_single_for_cpu(dma_chan
->device
->dev
, dest_dma
,
853 PAGE_SIZE
, DMA_FROM_DEVICE
);
854 if (memcmp(src
, dest
, PAGE_SIZE
)) {
855 dev_err(dma_chan
->device
->dev
,
856 "Self-test copy failed compare, disabling\n");
862 dmaengine_unmap_put(unmap
);
863 mv_xor_free_chan_resources(dma_chan
);
870 #define MV_XOR_NUM_SRC_TEST 4 /* must be <= 15 */
872 mv_chan_xor_self_test(struct mv_xor_chan
*mv_chan
)
876 struct page
*xor_srcs
[MV_XOR_NUM_SRC_TEST
];
877 dma_addr_t dma_srcs
[MV_XOR_NUM_SRC_TEST
];
879 struct dma_async_tx_descriptor
*tx
;
880 struct dmaengine_unmap_data
*unmap
;
881 struct dma_chan
*dma_chan
;
886 int src_count
= MV_XOR_NUM_SRC_TEST
;
888 for (src_idx
= 0; src_idx
< src_count
; src_idx
++) {
889 xor_srcs
[src_idx
] = alloc_page(GFP_KERNEL
);
890 if (!xor_srcs
[src_idx
]) {
892 __free_page(xor_srcs
[src_idx
]);
897 dest
= alloc_page(GFP_KERNEL
);
900 __free_page(xor_srcs
[src_idx
]);
904 /* Fill in src buffers */
905 for (src_idx
= 0; src_idx
< src_count
; src_idx
++) {
906 u8
*ptr
= page_address(xor_srcs
[src_idx
]);
907 for (i
= 0; i
< PAGE_SIZE
; i
++)
908 ptr
[i
] = (1 << src_idx
);
911 for (src_idx
= 0; src_idx
< src_count
; src_idx
++)
912 cmp_byte
^= (u8
) (1 << src_idx
);
914 cmp_word
= (cmp_byte
<< 24) | (cmp_byte
<< 16) |
915 (cmp_byte
<< 8) | cmp_byte
;
917 memset(page_address(dest
), 0, PAGE_SIZE
);
919 dma_chan
= &mv_chan
->dmachan
;
920 if (mv_xor_alloc_chan_resources(dma_chan
) < 1) {
925 unmap
= dmaengine_get_unmap_data(dma_chan
->device
->dev
, src_count
+ 1,
933 for (i
= 0; i
< src_count
; i
++) {
934 unmap
->addr
[i
] = dma_map_page(dma_chan
->device
->dev
, xor_srcs
[i
],
935 0, PAGE_SIZE
, DMA_TO_DEVICE
);
936 dma_srcs
[i
] = unmap
->addr
[i
];
937 ret
= dma_mapping_error(dma_chan
->device
->dev
, unmap
->addr
[i
]);
945 unmap
->addr
[src_count
] = dma_map_page(dma_chan
->device
->dev
, dest
, 0, PAGE_SIZE
,
947 dest_dma
= unmap
->addr
[src_count
];
948 ret
= dma_mapping_error(dma_chan
->device
->dev
, unmap
->addr
[src_count
]);
954 unmap
->len
= PAGE_SIZE
;
956 tx
= mv_xor_prep_dma_xor(dma_chan
, dest_dma
, dma_srcs
,
957 src_count
, PAGE_SIZE
, 0);
959 dev_err(dma_chan
->device
->dev
,
960 "Self-test cannot prepare operation, disabling\n");
965 cookie
= mv_xor_tx_submit(tx
);
966 if (dma_submit_error(cookie
)) {
967 dev_err(dma_chan
->device
->dev
,
968 "Self-test submit error, disabling\n");
973 mv_xor_issue_pending(dma_chan
);
977 if (mv_xor_status(dma_chan
, cookie
, NULL
) !=
979 dev_err(dma_chan
->device
->dev
,
980 "Self-test xor timed out, disabling\n");
985 dma_sync_single_for_cpu(dma_chan
->device
->dev
, dest_dma
,
986 PAGE_SIZE
, DMA_FROM_DEVICE
);
987 for (i
= 0; i
< (PAGE_SIZE
/ sizeof(u32
)); i
++) {
988 u32
*ptr
= page_address(dest
);
989 if (ptr
[i
] != cmp_word
) {
990 dev_err(dma_chan
->device
->dev
,
991 "Self-test xor failed compare, disabling. index %d, data %x, expected %x\n",
992 i
, ptr
[i
], cmp_word
);
999 dmaengine_unmap_put(unmap
);
1000 mv_xor_free_chan_resources(dma_chan
);
1002 src_idx
= src_count
;
1004 __free_page(xor_srcs
[src_idx
]);
1009 static int mv_xor_channel_remove(struct mv_xor_chan
*mv_chan
)
1011 struct dma_chan
*chan
, *_chan
;
1012 struct device
*dev
= mv_chan
->dmadev
.dev
;
1014 dma_async_device_unregister(&mv_chan
->dmadev
);
1016 dma_free_coherent(dev
, MV_XOR_POOL_SIZE
,
1017 mv_chan
->dma_desc_pool_virt
, mv_chan
->dma_desc_pool
);
1018 dma_unmap_single(dev
, mv_chan
->dummy_src_addr
,
1019 MV_XOR_MIN_BYTE_COUNT
, DMA_FROM_DEVICE
);
1020 dma_unmap_single(dev
, mv_chan
->dummy_dst_addr
,
1021 MV_XOR_MIN_BYTE_COUNT
, DMA_TO_DEVICE
);
1023 list_for_each_entry_safe(chan
, _chan
, &mv_chan
->dmadev
.channels
,
1025 list_del(&chan
->device_node
);
1028 free_irq(mv_chan
->irq
, mv_chan
);
1033 static struct mv_xor_chan
*
1034 mv_xor_channel_add(struct mv_xor_device
*xordev
,
1035 struct platform_device
*pdev
,
1036 int idx
, dma_cap_mask_t cap_mask
, int irq
)
1039 struct mv_xor_chan
*mv_chan
;
1040 struct dma_device
*dma_dev
;
1042 mv_chan
= devm_kzalloc(&pdev
->dev
, sizeof(*mv_chan
), GFP_KERNEL
);
1044 return ERR_PTR(-ENOMEM
);
1048 if (xordev
->xor_type
== XOR_ORION
)
1049 mv_chan
->op_in_desc
= XOR_MODE_IN_REG
;
1051 mv_chan
->op_in_desc
= XOR_MODE_IN_DESC
;
1053 dma_dev
= &mv_chan
->dmadev
;
1054 dma_dev
->dev
= &pdev
->dev
;
1055 mv_chan
->xordev
= xordev
;
1058 * These source and destination dummy buffers are used to implement
1059 * a DMA_INTERRUPT operation as a minimum-sized XOR operation.
1060 * Hence, we only need to map the buffers at initialization-time.
1062 mv_chan
->dummy_src_addr
= dma_map_single(dma_dev
->dev
,
1063 mv_chan
->dummy_src
, MV_XOR_MIN_BYTE_COUNT
, DMA_FROM_DEVICE
);
1064 mv_chan
->dummy_dst_addr
= dma_map_single(dma_dev
->dev
,
1065 mv_chan
->dummy_dst
, MV_XOR_MIN_BYTE_COUNT
, DMA_TO_DEVICE
);
1067 /* allocate coherent memory for hardware descriptors
1068 * note: writecombine gives slightly better performance, but
1069 * requires that we explicitly flush the writes
1071 mv_chan
->dma_desc_pool_virt
=
1072 dma_alloc_wc(&pdev
->dev
, MV_XOR_POOL_SIZE
, &mv_chan
->dma_desc_pool
,
1074 if (!mv_chan
->dma_desc_pool_virt
)
1075 return ERR_PTR(-ENOMEM
);
1077 /* discover transaction capabilites from the platform data */
1078 dma_dev
->cap_mask
= cap_mask
;
1080 INIT_LIST_HEAD(&dma_dev
->channels
);
1082 /* set base routines */
1083 dma_dev
->device_alloc_chan_resources
= mv_xor_alloc_chan_resources
;
1084 dma_dev
->device_free_chan_resources
= mv_xor_free_chan_resources
;
1085 dma_dev
->device_tx_status
= mv_xor_status
;
1086 dma_dev
->device_issue_pending
= mv_xor_issue_pending
;
1088 /* set prep routines based on capability */
1089 if (dma_has_cap(DMA_INTERRUPT
, dma_dev
->cap_mask
))
1090 dma_dev
->device_prep_dma_interrupt
= mv_xor_prep_dma_interrupt
;
1091 if (dma_has_cap(DMA_MEMCPY
, dma_dev
->cap_mask
))
1092 dma_dev
->device_prep_dma_memcpy
= mv_xor_prep_dma_memcpy
;
1093 if (dma_has_cap(DMA_XOR
, dma_dev
->cap_mask
)) {
1094 dma_dev
->max_xor
= 8;
1095 dma_dev
->device_prep_dma_xor
= mv_xor_prep_dma_xor
;
1098 mv_chan
->mmr_base
= xordev
->xor_base
;
1099 mv_chan
->mmr_high_base
= xordev
->xor_high_base
;
1100 tasklet_init(&mv_chan
->irq_tasklet
, mv_xor_tasklet
, (unsigned long)
1103 /* clear errors before enabling interrupts */
1104 mv_chan_clear_err_status(mv_chan
);
1106 ret
= request_irq(mv_chan
->irq
, mv_xor_interrupt_handler
,
1107 0, dev_name(&pdev
->dev
), mv_chan
);
1111 mv_chan_unmask_interrupts(mv_chan
);
1113 if (mv_chan
->op_in_desc
== XOR_MODE_IN_DESC
)
1114 mv_chan_set_mode(mv_chan
, XOR_OPERATION_MODE_IN_DESC
);
1116 mv_chan_set_mode(mv_chan
, XOR_OPERATION_MODE_XOR
);
1118 spin_lock_init(&mv_chan
->lock
);
1119 INIT_LIST_HEAD(&mv_chan
->chain
);
1120 INIT_LIST_HEAD(&mv_chan
->completed_slots
);
1121 INIT_LIST_HEAD(&mv_chan
->free_slots
);
1122 INIT_LIST_HEAD(&mv_chan
->allocated_slots
);
1123 mv_chan
->dmachan
.device
= dma_dev
;
1124 dma_cookie_init(&mv_chan
->dmachan
);
1126 list_add_tail(&mv_chan
->dmachan
.device_node
, &dma_dev
->channels
);
1128 if (dma_has_cap(DMA_MEMCPY
, dma_dev
->cap_mask
)) {
1129 ret
= mv_chan_memcpy_self_test(mv_chan
);
1130 dev_dbg(&pdev
->dev
, "memcpy self test returned %d\n", ret
);
1135 if (dma_has_cap(DMA_XOR
, dma_dev
->cap_mask
)) {
1136 ret
= mv_chan_xor_self_test(mv_chan
);
1137 dev_dbg(&pdev
->dev
, "xor self test returned %d\n", ret
);
1142 dev_info(&pdev
->dev
, "Marvell XOR (%s): ( %s%s%s)\n",
1143 mv_chan
->op_in_desc
? "Descriptor Mode" : "Registers Mode",
1144 dma_has_cap(DMA_XOR
, dma_dev
->cap_mask
) ? "xor " : "",
1145 dma_has_cap(DMA_MEMCPY
, dma_dev
->cap_mask
) ? "cpy " : "",
1146 dma_has_cap(DMA_INTERRUPT
, dma_dev
->cap_mask
) ? "intr " : "");
1148 ret
= dma_async_device_register(dma_dev
);
1155 free_irq(mv_chan
->irq
, mv_chan
);
1157 dma_free_coherent(&pdev
->dev
, MV_XOR_POOL_SIZE
,
1158 mv_chan
->dma_desc_pool_virt
, mv_chan
->dma_desc_pool
);
1159 return ERR_PTR(ret
);
1163 mv_xor_conf_mbus_windows(struct mv_xor_device
*xordev
,
1164 const struct mbus_dram_target_info
*dram
)
1166 void __iomem
*base
= xordev
->xor_high_base
;
1170 for (i
= 0; i
< 8; i
++) {
1171 writel(0, base
+ WINDOW_BASE(i
));
1172 writel(0, base
+ WINDOW_SIZE(i
));
1174 writel(0, base
+ WINDOW_REMAP_HIGH(i
));
1177 for (i
= 0; i
< dram
->num_cs
; i
++) {
1178 const struct mbus_dram_window
*cs
= dram
->cs
+ i
;
1180 writel((cs
->base
& 0xffff0000) |
1181 (cs
->mbus_attr
<< 8) |
1182 dram
->mbus_dram_target_id
, base
+ WINDOW_BASE(i
));
1183 writel((cs
->size
- 1) & 0xffff0000, base
+ WINDOW_SIZE(i
));
1185 /* Fill the caching variables for later use */
1186 xordev
->win_start
[i
] = cs
->base
;
1187 xordev
->win_end
[i
] = cs
->base
+ cs
->size
- 1;
1189 win_enable
|= (1 << i
);
1190 win_enable
|= 3 << (16 + (2 * i
));
1193 writel(win_enable
, base
+ WINDOW_BAR_ENABLE(0));
1194 writel(win_enable
, base
+ WINDOW_BAR_ENABLE(1));
1195 writel(0, base
+ WINDOW_OVERRIDE_CTRL(0));
1196 writel(0, base
+ WINDOW_OVERRIDE_CTRL(1));
1200 mv_xor_conf_mbus_windows_a3700(struct mv_xor_device
*xordev
)
1202 void __iomem
*base
= xordev
->xor_high_base
;
1206 for (i
= 0; i
< 8; i
++) {
1207 writel(0, base
+ WINDOW_BASE(i
));
1208 writel(0, base
+ WINDOW_SIZE(i
));
1210 writel(0, base
+ WINDOW_REMAP_HIGH(i
));
1213 * For Armada3700 open default 4GB Mbus window. The dram
1214 * related configuration are done at AXIS level.
1216 writel(0xffff0000, base
+ WINDOW_SIZE(0));
1218 win_enable
|= 3 << 16;
1220 writel(win_enable
, base
+ WINDOW_BAR_ENABLE(0));
1221 writel(win_enable
, base
+ WINDOW_BAR_ENABLE(1));
1222 writel(0, base
+ WINDOW_OVERRIDE_CTRL(0));
1223 writel(0, base
+ WINDOW_OVERRIDE_CTRL(1));
1227 * Since this XOR driver is basically used only for RAID5, we don't
1228 * need to care about synchronizing ->suspend with DMA activity,
1229 * because the DMA engine will naturally be quiet due to the block
1230 * devices being suspended.
1232 static int mv_xor_suspend(struct platform_device
*pdev
, pm_message_t state
)
1234 struct mv_xor_device
*xordev
= platform_get_drvdata(pdev
);
1237 for (i
= 0; i
< MV_XOR_MAX_CHANNELS
; i
++) {
1238 struct mv_xor_chan
*mv_chan
= xordev
->channels
[i
];
1243 mv_chan
->saved_config_reg
=
1244 readl_relaxed(XOR_CONFIG(mv_chan
));
1245 mv_chan
->saved_int_mask_reg
=
1246 readl_relaxed(XOR_INTR_MASK(mv_chan
));
1252 static int mv_xor_resume(struct platform_device
*dev
)
1254 struct mv_xor_device
*xordev
= platform_get_drvdata(dev
);
1255 const struct mbus_dram_target_info
*dram
;
1258 for (i
= 0; i
< MV_XOR_MAX_CHANNELS
; i
++) {
1259 struct mv_xor_chan
*mv_chan
= xordev
->channels
[i
];
1264 writel_relaxed(mv_chan
->saved_config_reg
,
1265 XOR_CONFIG(mv_chan
));
1266 writel_relaxed(mv_chan
->saved_int_mask_reg
,
1267 XOR_INTR_MASK(mv_chan
));
1270 if (xordev
->xor_type
== XOR_ARMADA_37XX
) {
1271 mv_xor_conf_mbus_windows_a3700(xordev
);
1275 dram
= mv_mbus_dram_info();
1277 mv_xor_conf_mbus_windows(xordev
, dram
);
1282 static const struct of_device_id mv_xor_dt_ids
[] = {
1283 { .compatible
= "marvell,orion-xor", .data
= (void *)XOR_ORION
},
1284 { .compatible
= "marvell,armada-380-xor", .data
= (void *)XOR_ARMADA_38X
},
1285 { .compatible
= "marvell,armada-3700-xor", .data
= (void *)XOR_ARMADA_37XX
},
1289 static unsigned int mv_xor_engine_count
;
1291 static int mv_xor_probe(struct platform_device
*pdev
)
1293 const struct mbus_dram_target_info
*dram
;
1294 struct mv_xor_device
*xordev
;
1295 struct mv_xor_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
1296 struct resource
*res
;
1297 unsigned int max_engines
, max_channels
;
1300 dev_notice(&pdev
->dev
, "Marvell shared XOR driver\n");
1302 xordev
= devm_kzalloc(&pdev
->dev
, sizeof(*xordev
), GFP_KERNEL
);
1306 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1310 xordev
->xor_base
= devm_ioremap(&pdev
->dev
, res
->start
,
1311 resource_size(res
));
1312 if (!xordev
->xor_base
)
1315 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
1319 xordev
->xor_high_base
= devm_ioremap(&pdev
->dev
, res
->start
,
1320 resource_size(res
));
1321 if (!xordev
->xor_high_base
)
1324 platform_set_drvdata(pdev
, xordev
);
1328 * We need to know which type of XOR device we use before
1329 * setting up. In non-dt case it can only be the legacy one.
1331 xordev
->xor_type
= XOR_ORION
;
1332 if (pdev
->dev
.of_node
) {
1333 const struct of_device_id
*of_id
=
1334 of_match_device(mv_xor_dt_ids
,
1337 xordev
->xor_type
= (uintptr_t)of_id
->data
;
1341 * (Re-)program MBUS remapping windows if we are asked to.
1343 if (xordev
->xor_type
== XOR_ARMADA_37XX
) {
1344 mv_xor_conf_mbus_windows_a3700(xordev
);
1346 dram
= mv_mbus_dram_info();
1348 mv_xor_conf_mbus_windows(xordev
, dram
);
1351 /* Not all platforms can gate the clock, so it is not
1352 * an error if the clock does not exists.
1354 xordev
->clk
= clk_get(&pdev
->dev
, NULL
);
1355 if (!IS_ERR(xordev
->clk
))
1356 clk_prepare_enable(xordev
->clk
);
1359 * We don't want to have more than one channel per CPU in
1360 * order for async_tx to perform well. So we limit the number
1361 * of engines and channels so that we take into account this
1362 * constraint. Note that we also want to use channels from
1363 * separate engines when possible. For dual-CPU Armada 3700
1364 * SoC with single XOR engine allow using its both channels.
1366 max_engines
= num_present_cpus();
1367 if (xordev
->xor_type
== XOR_ARMADA_37XX
)
1368 max_channels
= num_present_cpus();
1370 max_channels
= min_t(unsigned int,
1371 MV_XOR_MAX_CHANNELS
,
1372 DIV_ROUND_UP(num_present_cpus(), 2));
1374 if (mv_xor_engine_count
>= max_engines
)
1377 if (pdev
->dev
.of_node
) {
1378 struct device_node
*np
;
1381 for_each_child_of_node(pdev
->dev
.of_node
, np
) {
1382 struct mv_xor_chan
*chan
;
1383 dma_cap_mask_t cap_mask
;
1386 if (i
>= max_channels
)
1389 dma_cap_zero(cap_mask
);
1390 dma_cap_set(DMA_MEMCPY
, cap_mask
);
1391 dma_cap_set(DMA_XOR
, cap_mask
);
1392 dma_cap_set(DMA_INTERRUPT
, cap_mask
);
1394 irq
= irq_of_parse_and_map(np
, 0);
1397 goto err_channel_add
;
1400 chan
= mv_xor_channel_add(xordev
, pdev
, i
,
1403 ret
= PTR_ERR(chan
);
1404 irq_dispose_mapping(irq
);
1405 goto err_channel_add
;
1408 xordev
->channels
[i
] = chan
;
1411 } else if (pdata
&& pdata
->channels
) {
1412 for (i
= 0; i
< max_channels
; i
++) {
1413 struct mv_xor_channel_data
*cd
;
1414 struct mv_xor_chan
*chan
;
1417 cd
= &pdata
->channels
[i
];
1418 irq
= platform_get_irq(pdev
, i
);
1421 goto err_channel_add
;
1424 chan
= mv_xor_channel_add(xordev
, pdev
, i
,
1427 ret
= PTR_ERR(chan
);
1428 goto err_channel_add
;
1431 xordev
->channels
[i
] = chan
;
1438 for (i
= 0; i
< MV_XOR_MAX_CHANNELS
; i
++)
1439 if (xordev
->channels
[i
]) {
1440 mv_xor_channel_remove(xordev
->channels
[i
]);
1441 if (pdev
->dev
.of_node
)
1442 irq_dispose_mapping(xordev
->channels
[i
]->irq
);
1445 if (!IS_ERR(xordev
->clk
)) {
1446 clk_disable_unprepare(xordev
->clk
);
1447 clk_put(xordev
->clk
);
1453 static struct platform_driver mv_xor_driver
= {
1454 .probe
= mv_xor_probe
,
1455 .suspend
= mv_xor_suspend
,
1456 .resume
= mv_xor_resume
,
1458 .name
= MV_XOR_NAME
,
1459 .of_match_table
= of_match_ptr(mv_xor_dt_ids
),
1463 builtin_platform_driver(mv_xor_driver
);
1466 MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
1467 MODULE_DESCRIPTION("DMA engine driver for Marvell's XOR engine");
1468 MODULE_LICENSE("GPL");