.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * arch/sh/drivers/dma/dma-sh.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * Copyright (C) 2000 Takashi YOSHII |
---|
7 | 8 | * Copyright (C) 2003, 2004 Paul Mundt |
---|
8 | 9 | * Copyright (C) 2005 Andriy Skulysh |
---|
9 | | - * |
---|
10 | | - * This file is subject to the terms and conditions of the GNU General Public |
---|
11 | | - * License. See the file "COPYING" in the main directory of this archive |
---|
12 | | - * for more details. |
---|
13 | 10 | */ |
---|
14 | 11 | #include <linux/init.h> |
---|
15 | 12 | #include <linux/interrupt.h> |
---|
.. | .. |
---|
22 | 19 | #include <cpu/dma.h> |
---|
23 | 20 | |
---|
24 | 21 | /* |
---|
| 22 | + * Some of the SoCs feature two DMAC modules. In such a case, the channels are |
---|
| 23 | + * distributed equally among them. |
---|
| 24 | + */ |
---|
| 25 | +#ifdef SH_DMAC_BASE1 |
---|
| 26 | +#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2) |
---|
| 27 | +#else |
---|
| 28 | +#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS |
---|
| 29 | +#endif |
---|
| 30 | + |
---|
| 31 | +#define SH_DMAC_CH_SZ 0x10 |
---|
| 32 | + |
---|
| 33 | +/* |
---|
25 | 34 | * Define the default configuration for dual address memory-memory transfer. |
---|
26 | 35 | * The 0x400 value represents auto-request, external->external. |
---|
27 | 36 | */ |
---|
.. | .. |
---|
32 | 41 | unsigned long base = SH_DMAC_BASE0; |
---|
33 | 42 | |
---|
34 | 43 | #ifdef SH_DMAC_BASE1 |
---|
35 | | - if (chan >= 6) |
---|
| 44 | + if (chan >= SH_DMAC_NR_MD_CH) |
---|
36 | 45 | base = SH_DMAC_BASE1; |
---|
37 | 46 | #endif |
---|
38 | 47 | |
---|
.. | .. |
---|
43 | 52 | { |
---|
44 | 53 | unsigned long base = dma_find_base(chan); |
---|
45 | 54 | |
---|
46 | | - /* Normalize offset calculation */ |
---|
47 | | - if (chan >= 9) |
---|
48 | | - chan -= 6; |
---|
49 | | - if (chan >= 4) |
---|
50 | | - base += 0x10; |
---|
| 55 | + chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ; |
---|
51 | 56 | |
---|
52 | | - return base + (chan * 0x10); |
---|
| 57 | + /* DMAOR is placed inside the channel register space. Step over it. */ |
---|
| 58 | + if (chan >= DMAOR) |
---|
| 59 | + base += SH_DMAC_CH_SZ; |
---|
| 60 | + |
---|
| 61 | + return base + chan; |
---|
53 | 62 | } |
---|
54 | 63 | |
---|
55 | 64 | #ifdef CONFIG_SH_DMA_IRQ_MULTI |
---|
.. | .. |
---|
253 | 262 | #define NR_DMAOR 1 |
---|
254 | 263 | #endif |
---|
255 | 264 | |
---|
256 | | -/* |
---|
257 | | - * DMAOR bases are broken out amongst channel groups. DMAOR0 manages |
---|
258 | | - * channels 0 - 5, DMAOR1 6 - 11 (optional). |
---|
259 | | - */ |
---|
260 | | -#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6)) |
---|
261 | | -#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6) |
---|
| 265 | +#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \ |
---|
| 266 | + SH_DMAC_NR_MD_CH) + DMAOR) |
---|
| 267 | +#define dmaor_write_reg(n, data) __raw_writew(data, \ |
---|
| 268 | + dma_find_base((n) * \ |
---|
| 269 | + SH_DMAC_NR_MD_CH) + DMAOR) |
---|
262 | 270 | |
---|
263 | 271 | static inline int dmaor_reset(int no) |
---|
264 | 272 | { |
---|
.. | .. |
---|
414 | 422 | |
---|
415 | 423 | MODULE_AUTHOR("Takashi YOSHII, Paul Mundt, Andriy Skulysh"); |
---|
416 | 424 | MODULE_DESCRIPTION("SuperH On-Chip DMAC Support"); |
---|
417 | | -MODULE_LICENSE("GPL"); |
---|
| 425 | +MODULE_LICENSE("GPL v2"); |
---|