Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: rcar-dmac: Add support for R-Car V3U

The DMACs (both SYS-DMAC and RT-DMAC) on R-Car V3U differ slightly from
the DMACs on R-Car Gen2 and other R-Car Gen3 SoCs:
1. The per-channel registers are located in a second register block.
Add support for mapping the second block, using the appropriate
offsets and stride.
2. The common Channel Clear Register (DMACHCLR) was replaced by a
per-channel register.
Update rcar_dmac_chan_clear{,_all}() to handle this.
As rcar_dmac_init() needs to clear the status before the individual
channels are probed, channel index and base address initialization
are moved forward.

Inspired by a patch in the BSP by Phong Hoang
<phong.hoang.wz@renesas.com>.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Link: https://lore.kernel.org/r/20210128084455.2237256-5-geert+renesas@glider.be
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Geert Uytterhoeven and committed by
Vinod Koul
e5bfbbb9 245bbd16

+58 -23
+58 -23
drivers/dma/sh/rcar-dmac.c
··· 189 189 * struct rcar_dmac - R-Car Gen2 DMA Controller 190 190 * @engine: base DMA engine object 191 191 * @dev: the hardware device 192 - * @iomem: remapped I/O memory base 192 + * @dmac_base: remapped base register block 193 + * @chan_base: remapped channel register block (optional) 193 194 * @n_channels: number of available channels 194 195 * @channels: array of DMAC channels 195 196 * @channels_mask: bitfield of which DMA channels are managed by this driver ··· 199 198 struct rcar_dmac { 200 199 struct dma_device engine; 201 200 struct device *dev; 202 - void __iomem *iomem; 201 + void __iomem *dmac_base; 202 + void __iomem *chan_base; 203 203 204 204 unsigned int n_channels; 205 205 struct rcar_dmac_chan *channels; ··· 236 234 #define RCAR_DMAOR_PRI_ROUND_ROBIN (3 << 8) 237 235 #define RCAR_DMAOR_AE (1 << 2) 238 236 #define RCAR_DMAOR_DME (1 << 0) 239 - #define RCAR_DMACHCLR 0x0080 237 + #define RCAR_DMACHCLR 0x0080 /* Not on R-Car V3U */ 240 238 #define RCAR_DMADPSEC 0x00a0 241 239 242 240 #define RCAR_DMASAR 0x0000 ··· 299 297 #define RCAR_DMAFIXDAR 0x0014 300 298 #define RCAR_DMAFIXDPBASE 0x0060 301 299 300 + /* For R-Car V3U */ 301 + #define RCAR_V3U_DMACHCLR 0x0100 302 + 302 303 /* Hardcode the MEMCPY transfer size to 4 bytes. */ 303 304 #define RCAR_DMAC_MEMCPY_XFER_SIZE 4 304 305 ··· 312 307 static void rcar_dmac_write(struct rcar_dmac *dmac, u32 reg, u32 data) 313 308 { 314 309 if (reg == RCAR_DMAOR) 315 - writew(data, dmac->iomem + reg); 310 + writew(data, dmac->dmac_base + reg); 316 311 else 317 - writel(data, dmac->iomem + reg); 312 + writel(data, dmac->dmac_base + reg); 318 313 } 319 314 320 315 static u32 rcar_dmac_read(struct rcar_dmac *dmac, u32 reg) 321 316 { 322 317 if (reg == RCAR_DMAOR) 323 - return readw(dmac->iomem + reg); 318 + return readw(dmac->dmac_base + reg); 324 319 else 325 - return readl(dmac->iomem + reg); 320 + return readl(dmac->dmac_base + reg); 326 321 } 327 322 328 323 static u32 rcar_dmac_chan_read(struct rcar_dmac_chan *chan, u32 reg) ··· 344 339 static void rcar_dmac_chan_clear(struct rcar_dmac *dmac, 345 340 struct rcar_dmac_chan *chan) 346 341 { 347 - rcar_dmac_write(dmac, RCAR_DMACHCLR, BIT(chan->index)); 342 + if (dmac->chan_base) 343 + rcar_dmac_chan_write(chan, RCAR_V3U_DMACHCLR, 1); 344 + else 345 + rcar_dmac_write(dmac, RCAR_DMACHCLR, BIT(chan->index)); 348 346 } 349 347 350 348 static void rcar_dmac_chan_clear_all(struct rcar_dmac *dmac) 351 349 { 352 - rcar_dmac_write(dmac, RCAR_DMACHCLR, dmac->channels_mask); 350 + struct rcar_dmac_chan *chan; 351 + unsigned int i; 352 + 353 + if (dmac->chan_base) { 354 + for_each_rcar_dmac_chan(i, dmac, chan) 355 + rcar_dmac_chan_write(chan, RCAR_V3U_DMACHCLR, 1); 356 + } else { 357 + rcar_dmac_write(dmac, RCAR_DMACHCLR, dmac->channels_mask); 358 + } 353 359 } 354 360 355 361 /* ----------------------------------------------------------------------------- ··· 1759 1743 */ 1760 1744 1761 1745 static int rcar_dmac_chan_probe(struct rcar_dmac *dmac, 1762 - struct rcar_dmac_chan *rchan, 1763 - const struct rcar_dmac_of_data *data, 1764 - unsigned int index) 1746 + struct rcar_dmac_chan *rchan) 1765 1747 { 1766 1748 struct platform_device *pdev = to_platform_device(dmac->dev); 1767 1749 struct dma_chan *chan = &rchan->chan; ··· 1767 1753 char *irqname; 1768 1754 int ret; 1769 1755 1770 - rchan->index = index; 1771 - rchan->iomem = dmac->iomem + data->chan_offset_base + 1772 - data->chan_offset_stride * index; 1773 1756 rchan->mid_rid = -EINVAL; 1774 1757 1775 1758 spin_lock_init(&rchan->lock); ··· 1778 1767 INIT_LIST_HEAD(&rchan->desc.wait); 1779 1768 1780 1769 /* Request the channel interrupt. */ 1781 - sprintf(pdev_irqname, "ch%u", index); 1770 + sprintf(pdev_irqname, "ch%u", rchan->index); 1782 1771 rchan->irq = platform_get_irq_byname(pdev, pdev_irqname); 1783 1772 if (rchan->irq < 0) 1784 1773 return -ENODEV; 1785 1774 1786 1775 irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u", 1787 - dev_name(dmac->dev), index); 1776 + dev_name(dmac->dev), rchan->index); 1788 1777 if (!irqname) 1789 1778 return -ENOMEM; 1790 1779 ··· 1853 1842 const struct rcar_dmac_of_data *data; 1854 1843 struct rcar_dmac_chan *chan; 1855 1844 struct dma_device *engine; 1845 + void __iomem *chan_base; 1856 1846 struct rcar_dmac *dmac; 1857 1847 unsigned int i; 1858 1848 int ret; ··· 1892 1880 return -ENOMEM; 1893 1881 1894 1882 /* Request resources. */ 1895 - dmac->iomem = devm_platform_ioremap_resource(pdev, 0); 1896 - if (IS_ERR(dmac->iomem)) 1897 - return PTR_ERR(dmac->iomem); 1883 + dmac->dmac_base = devm_platform_ioremap_resource(pdev, 0); 1884 + if (IS_ERR(dmac->dmac_base)) 1885 + return PTR_ERR(dmac->dmac_base); 1886 + 1887 + if (!data->chan_offset_base) { 1888 + dmac->chan_base = devm_platform_ioremap_resource(pdev, 1); 1889 + if (IS_ERR(dmac->chan_base)) 1890 + return PTR_ERR(dmac->chan_base); 1891 + 1892 + chan_base = dmac->chan_base; 1893 + } else { 1894 + chan_base = dmac->dmac_base + data->chan_offset_base; 1895 + } 1896 + 1897 + for_each_rcar_dmac_chan(i, dmac, chan) { 1898 + chan->index = i; 1899 + chan->iomem = chan_base + i * data->chan_offset_stride; 1900 + } 1898 1901 1899 1902 /* Enable runtime PM and initialize the device. */ 1900 1903 pm_runtime_enable(&pdev->dev); ··· 1956 1929 INIT_LIST_HEAD(&engine->channels); 1957 1930 1958 1931 for_each_rcar_dmac_chan(i, dmac, chan) { 1959 - ret = rcar_dmac_chan_probe(dmac, chan, data, i); 1932 + ret = rcar_dmac_chan_probe(dmac, chan); 1960 1933 if (ret < 0) 1961 1934 goto error; 1962 1935 } ··· 2004 1977 } 2005 1978 2006 1979 static const struct rcar_dmac_of_data rcar_dmac_data = { 2007 - .chan_offset_base = 0x8000, 2008 - .chan_offset_stride = 0x80, 1980 + .chan_offset_base = 0x8000, 1981 + .chan_offset_stride = 0x80, 1982 + }; 1983 + 1984 + static const struct rcar_dmac_of_data rcar_v3u_dmac_data = { 1985 + .chan_offset_base = 0x0, 1986 + .chan_offset_stride = 0x1000, 2009 1987 }; 2010 1988 2011 1989 static const struct of_device_id rcar_dmac_of_ids[] = { 2012 1990 { 2013 1991 .compatible = "renesas,rcar-dmac", 2014 1992 .data = &rcar_dmac_data, 1993 + }, { 1994 + .compatible = "renesas,dmac-r8a779a0", 1995 + .data = &rcar_v3u_dmac_data, 2015 1996 }, 2016 1997 { /* Sentinel */ } 2017 1998 };