You need to sign in or sign up before continuing.
mv_xor.c 30.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * offload engine driver for the Marvell XOR engine
 * Copyright (C) 2007, 2008, Marvell International Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/init.h>
#include <linux/module.h>
21
#include <linux/slab.h>
22 23 24 25 26 27
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/memory.h>
28
#include <linux/clk.h>
29 30 31
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/irqdomain.h>
32
#include <linux/platform_data/dma-mv_xor.h>
33 34

#include "dmaengine.h"
35 36 37 38 39
#include "mv_xor.h"

static void mv_xor_issue_pending(struct dma_chan *chan);

#define to_mv_xor_chan(chan)		\
40
	container_of(chan, struct mv_xor_chan, dmachan)
41 42 43 44

#define to_mv_xor_slot(tx)		\
	container_of(tx, struct mv_xor_desc_slot, async_tx)

45
#define mv_chan_to_devp(chan)           \
46
	((chan)->dmadev.dev)
47

48 49
static void mv_desc_init(struct mv_xor_desc_slot *desc,
			 dma_addr_t addr, u32 byte_count)
50 51 52 53 54 55
{
	struct mv_xor_desc *hw_desc = desc->hw_desc;

	hw_desc->status = (1 << 31);
	hw_desc->phy_next_desc = 0;
	hw_desc->desc_command = (1 << 31);
56
	hw_desc->phy_dest_addr = addr;
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
	hw_desc->byte_count = byte_count;
}

static void mv_desc_set_next_desc(struct mv_xor_desc_slot *desc,
				  u32 next_desc_addr)
{
	struct mv_xor_desc *hw_desc = desc->hw_desc;
	BUG_ON(hw_desc->phy_next_desc);
	hw_desc->phy_next_desc = next_desc_addr;
}

static void mv_desc_clear_next_desc(struct mv_xor_desc_slot *desc)
{
	struct mv_xor_desc *hw_desc = desc->hw_desc;
	hw_desc->phy_next_desc = 0;
}

static void mv_desc_set_src_addr(struct mv_xor_desc_slot *desc,
				 int index, dma_addr_t addr)
{
	struct mv_xor_desc *hw_desc = desc->hw_desc;
78
	hw_desc->phy_src_addr[mv_phy_src_idx(index)] = addr;
79 80 81 82 83 84
	if (desc->type == DMA_XOR)
		hw_desc->desc_command |= (1 << index);
}

static u32 mv_chan_get_current_desc(struct mv_xor_chan *chan)
{
85
	return readl_relaxed(XOR_CURR_DESC(chan));
86 87 88 89 90
}

static void mv_chan_set_next_descriptor(struct mv_xor_chan *chan,
					u32 next_desc_addr)
{
91
	writel_relaxed(next_desc_addr, XOR_NEXT_DESC(chan));
92 93 94 95
}

static void mv_chan_unmask_interrupts(struct mv_xor_chan *chan)
{
96
	u32 val = readl_relaxed(XOR_INTR_MASK(chan));
97
	val |= XOR_INTR_MASK_VALUE << (chan->idx * 16);
98
	writel_relaxed(val, XOR_INTR_MASK(chan));
99 100 101 102
}

static u32 mv_chan_get_intr_cause(struct mv_xor_chan *chan)
{
103
	u32 intr_cause = readl_relaxed(XOR_INTR_CAUSE(chan));
104 105 106 107 108 109 110 111 112 113 114 115 116 117
	intr_cause = (intr_cause >> (chan->idx * 16)) & 0xFFFF;
	return intr_cause;
}

static int mv_is_err_intr(u32 intr_cause)
{
	if (intr_cause & ((1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)))
		return 1;

	return 0;
}

static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan)
{
118
	u32 val = ~(1 << (chan->idx * 16));
119
	dev_dbg(mv_chan_to_devp(chan), "%s, val 0x%08x\n", __func__, val);
120
	writel_relaxed(val, XOR_INTR_CAUSE(chan));
121 122 123 124 125
}

static void mv_xor_device_clear_err_status(struct mv_xor_chan *chan)
{
	u32 val = 0xFFFF0000 >> (chan->idx * 16);
126
	writel_relaxed(val, XOR_INTR_CAUSE(chan));
127 128 129 130 131 132
}

static void mv_set_mode(struct mv_xor_chan *chan,
			       enum dma_transaction_type type)
{
	u32 op_mode;
133
	u32 config = readl_relaxed(XOR_CONFIG(chan));
134 135 136 137 138 139 140 141 142

	switch (type) {
	case DMA_XOR:
		op_mode = XOR_OPERATION_MODE_XOR;
		break;
	case DMA_MEMCPY:
		op_mode = XOR_OPERATION_MODE_MEMCPY;
		break;
	default:
143
		dev_err(mv_chan_to_devp(chan),
144
			"error: unsupported operation %d\n",
145
			type);
146 147 148 149 150 151
		BUG();
		return;
	}

	config &= ~0x7;
	config |= op_mode;
152 153 154 155 156 157 158

#if defined(__BIG_ENDIAN)
	config |= XOR_DESCRIPTOR_SWAP;
#else
	config &= ~XOR_DESCRIPTOR_SWAP;
#endif

159
	writel_relaxed(config, XOR_CONFIG(chan));
160 161 162 163 164
	chan->current_type = type;
}

static void mv_chan_activate(struct mv_xor_chan *chan)
{
165
	dev_dbg(mv_chan_to_devp(chan), " activate chan.\n");
166 167 168

	/* writel ensures all descriptors are flushed before activation */
	writel(BIT(0), XOR_ACTIVATION(chan));
169 170 171 172
}

static char mv_chan_is_busy(struct mv_xor_chan *chan)
{
173
	u32 state = readl_relaxed(XOR_ACTIVATION(chan));
174 175 176 177 178 179 180 181 182 183 184 185 186 187

	state = (state >> 4) & 0x3;

	return (state == 1) ? 1 : 0;
}

/**
 * mv_xor_free_slots - flags descriptor slots for reuse
 * @slot: Slot to free
 * Caller must hold &mv_chan->lock while calling this function
 */
static void mv_xor_free_slots(struct mv_xor_chan *mv_chan,
			      struct mv_xor_desc_slot *slot)
{
188
	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d slot %p\n",
189 190
		__func__, __LINE__, slot);

191
	slot->slot_used = 0;
192 193 194 195 196 197 198 199 200 201 202

}

/*
 * mv_xor_start_new_chain - program the engine to operate on new chain headed by
 * sw_desc
 * Caller must hold &mv_chan->lock while calling this function
 */
static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan,
				   struct mv_xor_desc_slot *sw_desc)
{
203
	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d: sw_desc %p\n",
204 205
		__func__, __LINE__, sw_desc);

206 207 208
	/* set the hardware chain */
	mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys);

209
	mv_chan->pending++;
210
	mv_xor_issue_pending(&mv_chan->dmachan);
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
}

static dma_cookie_t
mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc,
	struct mv_xor_chan *mv_chan, dma_cookie_t cookie)
{
	BUG_ON(desc->async_tx.cookie < 0);

	if (desc->async_tx.cookie > 0) {
		cookie = desc->async_tx.cookie;

		/* call the callback (must not sleep or submit new
		 * operations to this channel)
		 */
		if (desc->async_tx.callback)
			desc->async_tx.callback(
				desc->async_tx.callback_param);

229
		dma_descriptor_unmap(&desc->async_tx);
230 231 232
	}

	/* run dependent operations */
233
	dma_run_dependencies(&desc->async_tx);
234 235 236 237 238 239 240 241 242

	return cookie;
}

static int
mv_xor_clean_completed_slots(struct mv_xor_chan *mv_chan)
{
	struct mv_xor_desc_slot *iter, *_iter;

243
	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__);
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
	list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots,
				 completed_node) {

		if (async_tx_test_ack(&iter->async_tx)) {
			list_del(&iter->completed_node);
			mv_xor_free_slots(mv_chan, iter);
		}
	}
	return 0;
}

static int
mv_xor_clean_slot(struct mv_xor_desc_slot *desc,
	struct mv_xor_chan *mv_chan)
{
259
	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d: desc %p flags %d\n",
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
		__func__, __LINE__, desc, desc->async_tx.flags);
	list_del(&desc->chain_node);
	/* the client is allowed to attach dependent operations
	 * until 'ack' is set
	 */
	if (!async_tx_test_ack(&desc->async_tx)) {
		/* move this slot to the completed_slots */
		list_add_tail(&desc->completed_node, &mv_chan->completed_slots);
		return 0;
	}

	mv_xor_free_slots(mv_chan, desc);
	return 0;
}

static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
{
	struct mv_xor_desc_slot *iter, *_iter;
	dma_cookie_t cookie = 0;
	int busy = mv_chan_is_busy(mv_chan);
	u32 current_desc = mv_chan_get_current_desc(mv_chan);
	int seen_current = 0;

283 284
	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__);
	dev_dbg(mv_chan_to_devp(mv_chan), "current_desc %x\n", current_desc);
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
	mv_xor_clean_completed_slots(mv_chan);

	/* free completed slots from the chain starting with
	 * the oldest descriptor
	 */

	list_for_each_entry_safe(iter, _iter, &mv_chan->chain,
					chain_node) {
		prefetch(_iter);
		prefetch(&_iter->async_tx);

		/* do not advance past the current descriptor loaded into the
		 * hardware channel, subsequent descriptors are either in
		 * process or have not been submitted
		 */
		if (seen_current)
			break;

		/* stop the search if we reach the current descriptor and the
		 * channel is busy
		 */
		if (iter->async_tx.phys == current_desc) {
			seen_current = 1;
			if (busy)
				break;
		}

		cookie = mv_xor_run_tx_complete_actions(iter, mv_chan, cookie);

		if (mv_xor_clean_slot(iter, mv_chan))
			break;
	}

	if ((busy == 0) && !list_empty(&mv_chan->chain)) {
		struct mv_xor_desc_slot *chain_head;
		chain_head = list_entry(mv_chan->chain.next,
					struct mv_xor_desc_slot,
					chain_node);

		mv_xor_start_new_chain(mv_chan, chain_head);
	}

	if (cookie > 0)
328
		mv_chan->dmachan.completed_cookie = cookie;
329 330 331 332 333 334 335 336 337 338 339 340 341
}

static void
mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
{
	spin_lock_bh(&mv_chan->lock);
	__mv_xor_slot_cleanup(mv_chan);
	spin_unlock_bh(&mv_chan->lock);
}

static void mv_xor_tasklet(unsigned long data)
{
	struct mv_xor_chan *chan = (struct mv_xor_chan *) data;
342
	mv_xor_slot_cleanup(chan);
343 344 345
}

static struct mv_xor_desc_slot *
346
mv_xor_alloc_slot(struct mv_xor_chan *mv_chan)
347
{
348 349
	struct mv_xor_desc_slot *iter, *_iter;
	int retry = 0;
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364

	/* start search from the last allocated descrtiptor
	 * if a contiguous allocation can not be found start searching
	 * from the beginning of the list
	 */
retry:
	if (retry == 0)
		iter = mv_chan->last_used;
	else
		iter = list_entry(&mv_chan->all_slots,
			struct mv_xor_desc_slot,
			slot_node);

	list_for_each_entry_safe_continue(
		iter, _iter, &mv_chan->all_slots, slot_node) {
365

366 367
		prefetch(_iter);
		prefetch(&_iter->async_tx);
368
		if (iter->slot_used) {
369 370 371 372 373 374 375 376
			/* give up after finding the first busy slot
			 * on the second pass through the list
			 */
			if (retry)
				break;
			continue;
		}

377 378 379 380 381 382 383 384 385 386 387
		/* pre-ack descriptor */
		async_tx_ack(&iter->async_tx);

		iter->slot_used = 1;
		INIT_LIST_HEAD(&iter->chain_node);
		iter->async_tx.cookie = -EBUSY;
		mv_chan->last_used = iter;
		mv_desc_clear_next_desc(iter);

		return iter;

388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
	}
	if (!retry++)
		goto retry;

	/* try to free some slots if the allocation fails */
	tasklet_schedule(&mv_chan->irq_tasklet);

	return NULL;
}

/************************ DMA engine API functions ****************************/
static dma_cookie_t
mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
{
	struct mv_xor_desc_slot *sw_desc = to_mv_xor_slot(tx);
	struct mv_xor_chan *mv_chan = to_mv_xor_chan(tx->chan);
404
	struct mv_xor_desc_slot *old_chain_tail;
405 406 407
	dma_cookie_t cookie;
	int new_hw_chain = 1;

408
	dev_dbg(mv_chan_to_devp(mv_chan),
409 410 411 412
		"%s sw_desc %p: async_tx %p\n",
		__func__, sw_desc, &sw_desc->async_tx);

	spin_lock_bh(&mv_chan->lock);
413
	cookie = dma_cookie_assign(tx);
414 415

	if (list_empty(&mv_chan->chain))
416
		list_add_tail(&sw_desc->chain_node, &mv_chan->chain);
417 418 419 420 421 422
	else {
		new_hw_chain = 0;

		old_chain_tail = list_entry(mv_chan->chain.prev,
					    struct mv_xor_desc_slot,
					    chain_node);
423
		list_add_tail(&sw_desc->chain_node, &mv_chan->chain);
424

425 426
		dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %pa\n",
			&old_chain_tail->async_tx.phys);
427 428

		/* fix up the hardware chain */
429
		mv_desc_set_next_desc(old_chain_tail, sw_desc->async_tx.phys);
430 431 432 433 434 435 436 437 438 439 440 441 442 443

		/* if the channel is not busy */
		if (!mv_chan_is_busy(mv_chan)) {
			u32 current_desc = mv_chan_get_current_desc(mv_chan);
			/*
			 * and the curren desc is the end of the chain before
			 * the append, then we need to start the channel
			 */
			if (current_desc == old_chain_tail->async_tx.phys)
				new_hw_chain = 1;
		}
	}

	if (new_hw_chain)
444
		mv_xor_start_new_chain(mv_chan, sw_desc);
445 446 447 448 449 450 451

	spin_unlock_bh(&mv_chan->lock);

	return cookie;
}

/* returns the number of allocated descriptors */
452
static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
453
{
454 455
	void *virt_desc;
	dma_addr_t dma_desc;
456 457 458
	int idx;
	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
	struct mv_xor_desc_slot *slot = NULL;
459
	int num_descs_in_pool = MV_XOR_POOL_SIZE/MV_XOR_SLOT_SIZE;
460 461 462 463 464 465

	/* Allocate descriptor slots */
	idx = mv_chan->slots_allocated;
	while (idx < num_descs_in_pool) {
		slot = kzalloc(sizeof(*slot), GFP_KERNEL);
		if (!slot) {
466 467 468
			dev_info(mv_chan_to_devp(mv_chan),
				 "channel only initialized %d descriptor slots",
				 idx);
469 470
			break;
		}
471 472
		virt_desc = mv_chan->dma_desc_pool_virt;
		slot->hw_desc = virt_desc + idx * MV_XOR_SLOT_SIZE;
473 474 475 476 477

		dma_async_tx_descriptor_init(&slot->async_tx, chan);
		slot->async_tx.tx_submit = mv_xor_tx_submit;
		INIT_LIST_HEAD(&slot->chain_node);
		INIT_LIST_HEAD(&slot->slot_node);
478 479
		dma_desc = mv_chan->dma_desc_pool;
		slot->async_tx.phys = dma_desc + idx * MV_XOR_SLOT_SIZE;
480 481 482 483 484 485 486 487 488 489 490 491 492
		slot->idx = idx++;

		spin_lock_bh(&mv_chan->lock);
		mv_chan->slots_allocated = idx;
		list_add_tail(&slot->slot_node, &mv_chan->all_slots);
		spin_unlock_bh(&mv_chan->lock);
	}

	if (mv_chan->slots_allocated && !mv_chan->last_used)
		mv_chan->last_used = list_entry(mv_chan->all_slots.next,
					struct mv_xor_desc_slot,
					slot_node);

493
	dev_dbg(mv_chan_to_devp(mv_chan),
494 495 496 497 498 499 500 501 502 503 504
		"allocated %d descriptor slots last_used: %p\n",
		mv_chan->slots_allocated, mv_chan->last_used);

	return mv_chan->slots_allocated ? : -ENOMEM;
}

static struct dma_async_tx_descriptor *
mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
		    unsigned int src_cnt, size_t len, unsigned long flags)
{
	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
505
	struct mv_xor_desc_slot *sw_desc;
506 507 508 509

	if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
		return NULL;

510
	BUG_ON(len > MV_XOR_MAX_BYTE_COUNT);
511

512
	dev_dbg(mv_chan_to_devp(mv_chan),
513 514
		"%s src_cnt: %d len: %u dest %pad flags: %ld\n",
		__func__, src_cnt, len, &dest, flags);
515 516

	spin_lock_bh(&mv_chan->lock);
517
	sw_desc = mv_xor_alloc_slot(mv_chan);
518 519 520
	if (sw_desc) {
		sw_desc->type = DMA_XOR;
		sw_desc->async_tx.flags = flags;
521
		mv_desc_init(sw_desc, dest, len);
522 523 524
		sw_desc->unmap_src_cnt = src_cnt;
		sw_desc->unmap_len = len;
		while (src_cnt--)
525
			mv_desc_set_src_addr(sw_desc, src_cnt, src[src_cnt]);
526 527
	}
	spin_unlock_bh(&mv_chan->lock);
528
	dev_dbg(mv_chan_to_devp(mv_chan),
529 530 531 532 533
		"%s sw_desc %p async_tx %p \n",
		__func__, sw_desc, &sw_desc->async_tx);
	return sw_desc ? &sw_desc->async_tx : NULL;
}

534 535 536 537 538 539 540 541 542 543 544
static struct dma_async_tx_descriptor *
mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
		size_t len, unsigned long flags)
{
	/*
	 * A MEMCPY operation is identical to an XOR operation with only
	 * a single source address.
	 */
	return mv_xor_prep_dma_xor(chan, dest, &src, 1, len, flags);
}

545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
static void mv_xor_free_chan_resources(struct dma_chan *chan)
{
	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
	struct mv_xor_desc_slot *iter, *_iter;
	int in_use_descs = 0;

	mv_xor_slot_cleanup(mv_chan);

	spin_lock_bh(&mv_chan->lock);
	list_for_each_entry_safe(iter, _iter, &mv_chan->chain,
					chain_node) {
		in_use_descs++;
		list_del(&iter->chain_node);
	}
	list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots,
				 completed_node) {
		in_use_descs++;
		list_del(&iter->completed_node);
	}
	list_for_each_entry_safe_reverse(
		iter, _iter, &mv_chan->all_slots, slot_node) {
		list_del(&iter->slot_node);
		kfree(iter);
		mv_chan->slots_allocated--;
	}
	mv_chan->last_used = NULL;

572
	dev_dbg(mv_chan_to_devp(mv_chan), "%s slots_allocated %d\n",
573 574 575 576
		__func__, mv_chan->slots_allocated);
	spin_unlock_bh(&mv_chan->lock);

	if (in_use_descs)
577
		dev_err(mv_chan_to_devp(mv_chan),
578 579 580 581
			"freeing %d in use descriptors!\n", in_use_descs);
}

/**
582
 * mv_xor_status - poll the status of an XOR transaction
583 584
 * @chan: XOR channel handle
 * @cookie: XOR transaction identifier
585
 * @txstate: XOR transactions state holder (or NULL)
586
 */
587
static enum dma_status mv_xor_status(struct dma_chan *chan,
588
					  dma_cookie_t cookie,
589
					  struct dma_tx_state *txstate)
590 591 592 593
{
	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
	enum dma_status ret;

594
	ret = dma_cookie_status(chan, cookie, txstate);
595
	if (ret == DMA_COMPLETE) {
596 597 598 599 600
		mv_xor_clean_completed_slots(mv_chan);
		return ret;
	}
	mv_xor_slot_cleanup(mv_chan);

601
	return dma_cookie_status(chan, cookie, txstate);
602 603 604 605 606 607
}

static void mv_dump_xor_regs(struct mv_xor_chan *chan)
{
	u32 val;

608
	val = readl_relaxed(XOR_CONFIG(chan));
609
	dev_err(mv_chan_to_devp(chan), "config       0x%08x\n", val);
610

611
	val = readl_relaxed(XOR_ACTIVATION(chan));
612
	dev_err(mv_chan_to_devp(chan), "activation   0x%08x\n", val);
613

614
	val = readl_relaxed(XOR_INTR_CAUSE(chan));
615
	dev_err(mv_chan_to_devp(chan), "intr cause   0x%08x\n", val);
616

617
	val = readl_relaxed(XOR_INTR_MASK(chan));
618
	dev_err(mv_chan_to_devp(chan), "intr mask    0x%08x\n", val);
619

620
	val = readl_relaxed(XOR_ERROR_CAUSE(chan));
621
	dev_err(mv_chan_to_devp(chan), "error cause  0x%08x\n", val);
622

623
	val = readl_relaxed(XOR_ERROR_ADDR(chan));
624
	dev_err(mv_chan_to_devp(chan), "error addr   0x%08x\n", val);
625 626 627 628 629 630
}

static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan,
					 u32 intr_cause)
{
	if (intr_cause & (1 << 4)) {
631
	     dev_dbg(mv_chan_to_devp(chan),
632 633 634 635
		     "ignore this error\n");
	     return;
	}

636
	dev_err(mv_chan_to_devp(chan),
637
		"error on chan %d. intr cause 0x%08x\n",
638
		chan->idx, intr_cause);
639 640 641 642 643 644 645 646 647 648

	mv_dump_xor_regs(chan);
	BUG();
}

static irqreturn_t mv_xor_interrupt_handler(int irq, void *data)
{
	struct mv_xor_chan *chan = data;
	u32 intr_cause = mv_chan_get_intr_cause(chan);

649
	dev_dbg(mv_chan_to_devp(chan), "intr cause %x\n", intr_cause);
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674

	if (mv_is_err_intr(intr_cause))
		mv_xor_err_interrupt_handler(chan, intr_cause);

	tasklet_schedule(&chan->irq_tasklet);

	mv_xor_device_clear_eoc_cause(chan);

	return IRQ_HANDLED;
}

static void mv_xor_issue_pending(struct dma_chan *chan)
{
	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);

	if (mv_chan->pending >= MV_XOR_THRESHOLD) {
		mv_chan->pending = 0;
		mv_chan_activate(mv_chan);
	}
}

/*
 * Perform a transaction to verify the HW works.
 */

675
static int mv_xor_memcpy_self_test(struct mv_xor_chan *mv_chan)
676 677 678 679 680 681 682
{
	int i;
	void *src, *dest;
	dma_addr_t src_dma, dest_dma;
	struct dma_chan *dma_chan;
	dma_cookie_t cookie;
	struct dma_async_tx_descriptor *tx;
683
	struct dmaengine_unmap_data *unmap;
684 685
	int err = 0;

686
	src = kmalloc(sizeof(u8) * PAGE_SIZE, GFP_KERNEL);
687 688 689
	if (!src)
		return -ENOMEM;

690
	dest = kzalloc(sizeof(u8) * PAGE_SIZE, GFP_KERNEL);
691 692 693 694 695 696
	if (!dest) {
		kfree(src);
		return -ENOMEM;
	}

	/* Fill in src buffer */
697
	for (i = 0; i < PAGE_SIZE; i++)
698 699
		((u8 *) src)[i] = (u8)i;

700
	dma_chan = &mv_chan->dmachan;
701
	if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
702 703 704 705
		err = -ENODEV;
		goto out;
	}

706 707 708 709 710 711 712 713 714 715
	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, 2, GFP_KERNEL);
	if (!unmap) {
		err = -ENOMEM;
		goto free_resources;
	}

	src_dma = dma_map_page(dma_chan->device->dev, virt_to_page(src), 0,
				 PAGE_SIZE, DMA_TO_DEVICE);
	unmap->to_cnt = 1;
	unmap->addr[0] = src_dma;
716

717 718 719 720 721 722
	dest_dma = dma_map_page(dma_chan->device->dev, virt_to_page(dest), 0,
				  PAGE_SIZE, DMA_FROM_DEVICE);
	unmap->from_cnt = 1;
	unmap->addr[1] = dest_dma;

	unmap->len = PAGE_SIZE;
723 724

	tx = mv_xor_prep_dma_memcpy(dma_chan, dest_dma, src_dma,
725
				    PAGE_SIZE, 0);
726 727 728 729 730
	cookie = mv_xor_tx_submit(tx);
	mv_xor_issue_pending(dma_chan);
	async_tx_ack(tx);
	msleep(1);

731
	if (mv_xor_status(dma_chan, cookie, NULL) !=
732
	    DMA_COMPLETE) {
733 734
		dev_err(dma_chan->device->dev,
			"Self-test copy timed out, disabling\n");
735 736 737 738
		err = -ENODEV;
		goto free_resources;
	}

739
	dma_sync_single_for_cpu(dma_chan->device->dev, dest_dma,
740 741
				PAGE_SIZE, DMA_FROM_DEVICE);
	if (memcmp(src, dest, PAGE_SIZE)) {
742 743
		dev_err(dma_chan->device->dev,
			"Self-test copy failed compare, disabling\n");
744 745 746 747 748
		err = -ENODEV;
		goto free_resources;
	}

free_resources:
749
	dmaengine_unmap_put(unmap);
750 751 752 753 754 755 756 757
	mv_xor_free_chan_resources(dma_chan);
out:
	kfree(src);
	kfree(dest);
	return err;
}

#define MV_XOR_NUM_SRC_TEST 4 /* must be <= 15 */
B
Bill Pemberton 已提交
758
static int
759
mv_xor_xor_self_test(struct mv_xor_chan *mv_chan)
760 761 762 763 764 765 766
{
	int i, src_idx;
	struct page *dest;
	struct page *xor_srcs[MV_XOR_NUM_SRC_TEST];
	dma_addr_t dma_srcs[MV_XOR_NUM_SRC_TEST];
	dma_addr_t dest_dma;
	struct dma_async_tx_descriptor *tx;
767
	struct dmaengine_unmap_data *unmap;
768 769 770 771 772
	struct dma_chan *dma_chan;
	dma_cookie_t cookie;
	u8 cmp_byte = 0;
	u32 cmp_word;
	int err = 0;
773
	int src_count = MV_XOR_NUM_SRC_TEST;
774

775
	for (src_idx = 0; src_idx < src_count; src_idx++) {
776
		xor_srcs[src_idx] = alloc_page(GFP_KERNEL);
777 778
		if (!xor_srcs[src_idx]) {
			while (src_idx--)
779
				__free_page(xor_srcs[src_idx]);
780 781
			return -ENOMEM;
		}
782 783 784
	}

	dest = alloc_page(GFP_KERNEL);
785 786
	if (!dest) {
		while (src_idx--)
787
			__free_page(xor_srcs[src_idx]);
788 789
		return -ENOMEM;
	}
790 791

	/* Fill in src buffers */
792
	for (src_idx = 0; src_idx < src_count; src_idx++) {
793 794 795 796 797
		u8 *ptr = page_address(xor_srcs[src_idx]);
		for (i = 0; i < PAGE_SIZE; i++)
			ptr[i] = (1 << src_idx);
	}

798
	for (src_idx = 0; src_idx < src_count; src_idx++)
799 800 801 802 803 804 805
		cmp_byte ^= (u8) (1 << src_idx);

	cmp_word = (cmp_byte << 24) | (cmp_byte << 16) |
		(cmp_byte << 8) | cmp_byte;

	memset(page_address(dest), 0, PAGE_SIZE);

806
	dma_chan = &mv_chan->dmachan;
807
	if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
808 809 810 811
		err = -ENODEV;
		goto out;
	}

812 813 814 815 816 817 818
	unmap = dmaengine_get_unmap_data(dma_chan->device->dev, src_count + 1,
					 GFP_KERNEL);
	if (!unmap) {
		err = -ENOMEM;
		goto free_resources;
	}

819
	/* test xor */
820 821 822 823 824 825
	for (i = 0; i < src_count; i++) {
		unmap->addr[i] = dma_map_page(dma_chan->device->dev, xor_srcs[i],
					      0, PAGE_SIZE, DMA_TO_DEVICE);
		dma_srcs[i] = unmap->addr[i];
		unmap->to_cnt++;
	}
826

827 828 829 830 831
	unmap->addr[src_count] = dma_map_page(dma_chan->device->dev, dest, 0, PAGE_SIZE,
				      DMA_FROM_DEVICE);
	dest_dma = unmap->addr[src_count];
	unmap->from_cnt = 1;
	unmap->len = PAGE_SIZE;
832 833

	tx = mv_xor_prep_dma_xor(dma_chan, dest_dma, dma_srcs,
834
				 src_count, PAGE_SIZE, 0);
835 836 837 838 839 840

	cookie = mv_xor_tx_submit(tx);
	mv_xor_issue_pending(dma_chan);
	async_tx_ack(tx);
	msleep(8);

841
	if (mv_xor_status(dma_chan, cookie, NULL) !=
842
	    DMA_COMPLETE) {
843 844
		dev_err(dma_chan->device->dev,
			"Self-test xor timed out, disabling\n");
845 846 847 848
		err = -ENODEV;
		goto free_resources;
	}

849
	dma_sync_single_for_cpu(dma_chan->device->dev, dest_dma,
850 851 852 853
				PAGE_SIZE, DMA_FROM_DEVICE);
	for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) {
		u32 *ptr = page_address(dest);
		if (ptr[i] != cmp_word) {
854
			dev_err(dma_chan->device->dev,
855 856
				"Self-test xor failed compare, disabling. index %d, data %x, expected %x\n",
				i, ptr[i], cmp_word);
857 858 859 860 861 862
			err = -ENODEV;
			goto free_resources;
		}
	}

free_resources:
863
	dmaengine_unmap_put(unmap);
864 865
	mv_xor_free_chan_resources(dma_chan);
out:
866
	src_idx = src_count;
867 868 869 870 871 872
	while (src_idx--)
		__free_page(xor_srcs[src_idx]);
	__free_page(dest);
	return err;
}

873 874 875 876 877 878 879 880
/* This driver does not implement any of the optional DMA operations. */
static int
mv_xor_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
	       unsigned long arg)
{
	return -ENOSYS;
}

881
static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
882 883
{
	struct dma_chan *chan, *_chan;
884
	struct device *dev = mv_chan->dmadev.dev;
885

886
	dma_async_device_unregister(&mv_chan->dmadev);
887

888
	dma_free_coherent(dev, MV_XOR_POOL_SIZE,
889
			  mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
890

891
	list_for_each_entry_safe(chan, _chan, &mv_chan->dmadev.channels,
892
				 device_node) {
893 894 895
		list_del(&chan->device_node);
	}

896 897
	free_irq(mv_chan->irq, mv_chan);

898 899 900
	return 0;
}

901
static struct mv_xor_chan *
902
mv_xor_channel_add(struct mv_xor_device *xordev,
903
		   struct platform_device *pdev,
904
		   int idx, dma_cap_mask_t cap_mask, int irq)
905 906 907 908 909
{
	int ret = 0;
	struct mv_xor_chan *mv_chan;
	struct dma_device *dma_dev;

910
	mv_chan = devm_kzalloc(&pdev->dev, sizeof(*mv_chan), GFP_KERNEL);
911 912
	if (!mv_chan)
		return ERR_PTR(-ENOMEM);
913

914
	mv_chan->idx = idx;
915
	mv_chan->irq = irq;
916

917
	dma_dev = &mv_chan->dmadev;
918 919 920 921 922

	/* allocate coherent memory for hardware descriptors
	 * note: writecombine gives slightly better performance, but
	 * requires that we explicitly flush the writes
	 */
923
	mv_chan->dma_desc_pool_virt =
924
	  dma_alloc_writecombine(&pdev->dev, MV_XOR_POOL_SIZE,
925 926
				 &mv_chan->dma_desc_pool, GFP_KERNEL);
	if (!mv_chan->dma_desc_pool_virt)
927
		return ERR_PTR(-ENOMEM);
928 929

	/* discover transaction capabilites from the platform data */
930
	dma_dev->cap_mask = cap_mask;
931 932 933 934 935 936

	INIT_LIST_HEAD(&dma_dev->channels);

	/* set base routines */
	dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources;
	dma_dev->device_free_chan_resources = mv_xor_free_chan_resources;
937
	dma_dev->device_tx_status = mv_xor_status;
938
	dma_dev->device_issue_pending = mv_xor_issue_pending;
939
	dma_dev->device_control = mv_xor_control;
940 941 942 943 944 945
	dma_dev->dev = &pdev->dev;

	/* set prep routines based on capability */
	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask))
		dma_dev->device_prep_dma_memcpy = mv_xor_prep_dma_memcpy;
	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
946
		dma_dev->max_xor = 8;
947 948 949
		dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor;
	}

950
	mv_chan->mmr_base = xordev->xor_base;
951
	mv_chan->mmr_high_base = xordev->xor_high_base;
952 953 954 955 956 957
	tasklet_init(&mv_chan->irq_tasklet, mv_xor_tasklet, (unsigned long)
		     mv_chan);

	/* clear errors before enabling interrupts */
	mv_xor_device_clear_err_status(mv_chan);

958 959
	ret = request_irq(mv_chan->irq, mv_xor_interrupt_handler,
			  0, dev_name(&pdev->dev), mv_chan);
960 961 962 963 964
	if (ret)
		goto err_free_dma;

	mv_chan_unmask_interrupts(mv_chan);

965
	mv_set_mode(mv_chan, DMA_XOR);
966 967 968 969 970

	spin_lock_init(&mv_chan->lock);
	INIT_LIST_HEAD(&mv_chan->chain);
	INIT_LIST_HEAD(&mv_chan->completed_slots);
	INIT_LIST_HEAD(&mv_chan->all_slots);
971 972
	mv_chan->dmachan.device = dma_dev;
	dma_cookie_init(&mv_chan->dmachan);
973

974
	list_add_tail(&mv_chan->dmachan.device_node, &dma_dev->channels);
975 976

	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
977
		ret = mv_xor_memcpy_self_test(mv_chan);
978 979
		dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret);
		if (ret)
980
			goto err_free_irq;
981 982 983
	}

	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
984
		ret = mv_xor_xor_self_test(mv_chan);
985 986
		dev_dbg(&pdev->dev, "xor self test returned %d\n", ret);
		if (ret)
987
			goto err_free_irq;
988 989
	}

990
	dev_info(&pdev->dev, "Marvell XOR: ( %s%s%s)\n",
991 992 993
		 dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
		 dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
		 dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
994 995

	dma_async_device_register(dma_dev);
996
	return mv_chan;
997

998 999
err_free_irq:
	free_irq(mv_chan->irq, mv_chan);
1000
 err_free_dma:
1001
	dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE,
1002
			  mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
1003
	return ERR_PTR(ret);
1004 1005 1006
}

static void
1007
mv_xor_conf_mbus_windows(struct mv_xor_device *xordev,
1008
			 const struct mbus_dram_target_info *dram)
1009
{
1010
	void __iomem *base = xordev->xor_high_base;
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
	u32 win_enable = 0;
	int i;

	for (i = 0; i < 8; i++) {
		writel(0, base + WINDOW_BASE(i));
		writel(0, base + WINDOW_SIZE(i));
		if (i < 4)
			writel(0, base + WINDOW_REMAP_HIGH(i));
	}

	for (i = 0; i < dram->num_cs; i++) {
1022
		const struct mbus_dram_window *cs = dram->cs + i;
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034

		writel((cs->base & 0xffff0000) |
		       (cs->mbus_attr << 8) |
		       dram->mbus_dram_target_id, base + WINDOW_BASE(i));
		writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i));

		win_enable |= (1 << i);
		win_enable |= 3 << (16 + (2 * i));
	}

	writel(win_enable, base + WINDOW_BAR_ENABLE(0));
	writel(win_enable, base + WINDOW_BAR_ENABLE(1));
1035 1036
	writel(0, base + WINDOW_OVERRIDE_CTRL(0));
	writel(0, base + WINDOW_OVERRIDE_CTRL(1));
1037 1038
}

1039
static int mv_xor_probe(struct platform_device *pdev)
1040
{
1041
	const struct mbus_dram_target_info *dram;
1042
	struct mv_xor_device *xordev;
J
Jingoo Han 已提交
1043
	struct mv_xor_platform_data *pdata = dev_get_platdata(&pdev->dev);
1044
	struct resource *res;
1045
	int i, ret;
1046

1047
	dev_notice(&pdev->dev, "Marvell shared XOR driver\n");
1048

1049 1050
	xordev = devm_kzalloc(&pdev->dev, sizeof(*xordev), GFP_KERNEL);
	if (!xordev)
1051 1052 1053 1054 1055 1056
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

1057 1058 1059
	xordev->xor_base = devm_ioremap(&pdev->dev, res->start,
					resource_size(res));
	if (!xordev->xor_base)
1060 1061 1062 1063 1064 1065
		return -EBUSY;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res)
		return -ENODEV;

1066 1067 1068
	xordev->xor_high_base = devm_ioremap(&pdev->dev, res->start,
					     resource_size(res));
	if (!xordev->xor_high_base)
1069 1070
		return -EBUSY;

1071
	platform_set_drvdata(pdev, xordev);
1072 1073 1074 1075

	/*
	 * (Re-)program MBUS remapping windows if we are asked to.
	 */
1076 1077
	dram = mv_mbus_dram_info();
	if (dram)
1078
		mv_xor_conf_mbus_windows(xordev, dram);
1079

1080 1081 1082
	/* Not all platforms can gate the clock, so it is not
	 * an error if the clock does not exists.
	 */
1083 1084 1085
	xordev->clk = clk_get(&pdev->dev, NULL);
	if (!IS_ERR(xordev->clk))
		clk_prepare_enable(xordev->clk);
1086

1087 1088 1089 1090 1091
	if (pdev->dev.of_node) {
		struct device_node *np;
		int i = 0;

		for_each_child_of_node(pdev->dev.of_node, np) {
1092
			struct mv_xor_chan *chan;
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
			dma_cap_mask_t cap_mask;
			int irq;

			dma_cap_zero(cap_mask);
			if (of_property_read_bool(np, "dmacap,memcpy"))
				dma_cap_set(DMA_MEMCPY, cap_mask);
			if (of_property_read_bool(np, "dmacap,xor"))
				dma_cap_set(DMA_XOR, cap_mask);
			if (of_property_read_bool(np, "dmacap,interrupt"))
				dma_cap_set(DMA_INTERRUPT, cap_mask);

			irq = irq_of_parse_and_map(np, 0);
1105 1106
			if (!irq) {
				ret = -ENODEV;
1107 1108 1109
				goto err_channel_add;
			}

1110 1111 1112 1113
			chan = mv_xor_channel_add(xordev, pdev, i,
						  cap_mask, irq);
			if (IS_ERR(chan)) {
				ret = PTR_ERR(chan);
1114 1115 1116 1117
				irq_dispose_mapping(irq);
				goto err_channel_add;
			}

1118
			xordev->channels[i] = chan;
1119 1120 1121
			i++;
		}
	} else if (pdata && pdata->channels) {
1122
		for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
1123
			struct mv_xor_channel_data *cd;
1124
			struct mv_xor_chan *chan;
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
			int irq;

			cd = &pdata->channels[i];
			if (!cd) {
				ret = -ENODEV;
				goto err_channel_add;
			}

			irq = platform_get_irq(pdev, i);
			if (irq < 0) {
				ret = irq;
				goto err_channel_add;
			}

1139 1140 1141 1142
			chan = mv_xor_channel_add(xordev, pdev, i,
						  cd->cap_mask, irq);
			if (IS_ERR(chan)) {
				ret = PTR_ERR(chan);
1143 1144
				goto err_channel_add;
			}
1145 1146

			xordev->channels[i] = chan;
1147 1148
		}
	}
1149

1150
	return 0;
1151 1152 1153

err_channel_add:
	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++)
1154
		if (xordev->channels[i]) {
1155
			mv_xor_channel_remove(xordev->channels[i]);
1156 1157 1158
			if (pdev->dev.of_node)
				irq_dispose_mapping(xordev->channels[i]->irq);
		}
1159

1160 1161 1162 1163 1164
	if (!IS_ERR(xordev->clk)) {
		clk_disable_unprepare(xordev->clk);
		clk_put(xordev->clk);
	}

1165
	return ret;
1166 1167
}

1168
static int mv_xor_remove(struct platform_device *pdev)
1169
{
1170
	struct mv_xor_device *xordev = platform_get_drvdata(pdev);
1171 1172 1173
	int i;

	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
1174 1175
		if (xordev->channels[i])
			mv_xor_channel_remove(xordev->channels[i]);
1176
	}
1177

1178 1179 1180
	if (!IS_ERR(xordev->clk)) {
		clk_disable_unprepare(xordev->clk);
		clk_put(xordev->clk);
1181 1182
	}

1183 1184 1185
	return 0;
}

1186
#ifdef CONFIG_OF
1187
static struct of_device_id mv_xor_dt_ids[] = {
1188 1189 1190 1191 1192 1193
       { .compatible = "marvell,orion-xor", },
       {},
};
MODULE_DEVICE_TABLE(of, mv_xor_dt_ids);
#endif

1194 1195
static struct platform_driver mv_xor_driver = {
	.probe		= mv_xor_probe,
1196
	.remove		= mv_xor_remove,
1197
	.driver		= {
1198 1199 1200
		.owner	        = THIS_MODULE,
		.name	        = MV_XOR_NAME,
		.of_match_table = of_match_ptr(mv_xor_dt_ids),
1201 1202 1203 1204 1205 1206
	},
};


static int __init mv_xor_init(void)
{
1207
	return platform_driver_register(&mv_xor_driver);
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
}
module_init(mv_xor_init);

/* it's currently unsafe to unload this module */
#if 0
static void __exit mv_xor_exit(void)
{
	platform_driver_unregister(&mv_xor_driver);
	return;
}

module_exit(mv_xor_exit);
#endif

MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
MODULE_DESCRIPTION("DMA engine driver for Marvell's XOR engine");
MODULE_LICENSE("GPL");