.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
---|
2 | 2 | /* |
---|
3 | | - * Renesas R-Car Gen2 DMA Controller Driver |
---|
| 3 | + * Renesas R-Car Gen2/Gen3 DMA Controller Driver |
---|
4 | 4 | * |
---|
5 | | - * Copyright (C) 2014 Renesas Electronics Inc. |
---|
| 5 | + * Copyright (C) 2014-2019 Renesas Electronics Inc. |
---|
6 | 6 | * |
---|
7 | 7 | * Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
---|
8 | 8 | */ |
---|
.. | .. |
---|
192 | 192 | * @iomem: remapped I/O memory base |
---|
193 | 193 | * @n_channels: number of available channels |
---|
194 | 194 | * @channels: array of DMAC channels |
---|
| 195 | + * @channels_mask: bitfield of which DMA channels are managed by this driver |
---|
195 | 196 | * @modules: bitmask of client modules in use |
---|
196 | 197 | */ |
---|
197 | 198 | struct rcar_dmac { |
---|
198 | 199 | struct dma_device engine; |
---|
199 | 200 | struct device *dev; |
---|
200 | 201 | void __iomem *iomem; |
---|
201 | | - struct device_dma_parameters parms; |
---|
202 | 202 | |
---|
203 | 203 | unsigned int n_channels; |
---|
204 | 204 | struct rcar_dmac_chan *channels; |
---|
| 205 | + u32 channels_mask; |
---|
205 | 206 | |
---|
206 | 207 | DECLARE_BITMAP(modules, 256); |
---|
207 | 208 | }; |
---|
208 | 209 | |
---|
209 | 210 | #define to_rcar_dmac(d) container_of(d, struct rcar_dmac, engine) |
---|
210 | 211 | |
---|
| 212 | +/* |
---|
| 213 | + * struct rcar_dmac_of_data - This driver's OF data |
---|
| 214 | + * @chan_offset_base: DMAC channels base offset |
---|
| 215 | + * @chan_offset_stride: DMAC channels offset stride |
---|
| 216 | + */ |
---|
| 217 | +struct rcar_dmac_of_data { |
---|
| 218 | + u32 chan_offset_base; |
---|
| 219 | + u32 chan_offset_stride; |
---|
| 220 | +}; |
---|
| 221 | + |
---|
211 | 222 | /* ----------------------------------------------------------------------------- |
---|
212 | 223 | * Registers |
---|
213 | 224 | */ |
---|
214 | | - |
---|
215 | | -#define RCAR_DMAC_CHAN_OFFSET(i) (0x8000 + 0x80 * (i)) |
---|
216 | 225 | |
---|
217 | 226 | #define RCAR_DMAISTA 0x0020 |
---|
218 | 227 | #define RCAR_DMASEC 0x0030 |
---|
.. | .. |
---|
438 | 447 | u16 dmaor; |
---|
439 | 448 | |
---|
440 | 449 | /* Clear all channels and enable the DMAC globally. */ |
---|
441 | | - rcar_dmac_write(dmac, RCAR_DMACHCLR, GENMASK(dmac->n_channels - 1, 0)); |
---|
| 450 | + rcar_dmac_write(dmac, RCAR_DMACHCLR, dmac->channels_mask); |
---|
442 | 451 | rcar_dmac_write(dmac, RCAR_DMAOR, |
---|
443 | 452 | RCAR_DMAOR_PRI_FIXED | RCAR_DMAOR_DME); |
---|
444 | 453 | |
---|
.. | .. |
---|
813 | 822 | /* Stop all channels. */ |
---|
814 | 823 | for (i = 0; i < dmac->n_channels; ++i) { |
---|
815 | 824 | struct rcar_dmac_chan *chan = &dmac->channels[i]; |
---|
| 825 | + |
---|
| 826 | + if (!(dmac->channels_mask & BIT(i))) |
---|
| 827 | + continue; |
---|
816 | 828 | |
---|
817 | 829 | /* Stop and reinitialize the channel. */ |
---|
818 | 830 | spin_lock_irq(&chan->lock); |
---|
.. | .. |
---|
1206 | 1218 | sg_len = buf_len / period_len; |
---|
1207 | 1219 | if (sg_len > RCAR_DMAC_MAX_SG_LEN) { |
---|
1208 | 1220 | dev_err(chan->device->dev, |
---|
1209 | | - "chan%u: sg length %d exceds limit %d", |
---|
| 1221 | + "chan%u: sg length %d exceeds limit %d", |
---|
1210 | 1222 | rchan->index, sg_len, RCAR_DMAC_MAX_SG_LEN); |
---|
1211 | 1223 | return NULL; |
---|
1212 | 1224 | } |
---|
.. | .. |
---|
1215 | 1227 | * Allocate the sg list dynamically as it would consume too much stack |
---|
1216 | 1228 | * space. |
---|
1217 | 1229 | */ |
---|
1218 | | - sgl = kcalloc(sg_len, sizeof(*sgl), GFP_NOWAIT); |
---|
| 1230 | + sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_NOWAIT); |
---|
1219 | 1231 | if (!sgl) |
---|
1220 | 1232 | return NULL; |
---|
1221 | 1233 | |
---|
.. | .. |
---|
1654 | 1666 | * Forcing it to call dma_request_channel() and iterate through all |
---|
1655 | 1667 | * channels from all controllers is just pointless. |
---|
1656 | 1668 | */ |
---|
1657 | | - if (chan->device->device_config != rcar_dmac_device_config || |
---|
1658 | | - dma_spec->np != chan->device->dev->of_node) |
---|
| 1669 | + if (chan->device->device_config != rcar_dmac_device_config) |
---|
1659 | 1670 | return false; |
---|
1660 | 1671 | |
---|
1661 | 1672 | return !test_and_set_bit(dma_spec->args[0], dmac->modules); |
---|
.. | .. |
---|
1675 | 1686 | dma_cap_zero(mask); |
---|
1676 | 1687 | dma_cap_set(DMA_SLAVE, mask); |
---|
1677 | 1688 | |
---|
1678 | | - chan = dma_request_channel(mask, rcar_dmac_chan_filter, dma_spec); |
---|
| 1689 | + chan = __dma_request_channel(&mask, rcar_dmac_chan_filter, dma_spec, |
---|
| 1690 | + ofdma->of_node); |
---|
1679 | 1691 | if (!chan) |
---|
1680 | 1692 | return NULL; |
---|
1681 | 1693 | |
---|
.. | .. |
---|
1721 | 1733 | |
---|
1722 | 1734 | static int rcar_dmac_chan_probe(struct rcar_dmac *dmac, |
---|
1723 | 1735 | struct rcar_dmac_chan *rchan, |
---|
| 1736 | + const struct rcar_dmac_of_data *data, |
---|
1724 | 1737 | unsigned int index) |
---|
1725 | 1738 | { |
---|
1726 | 1739 | struct platform_device *pdev = to_platform_device(dmac->dev); |
---|
.. | .. |
---|
1730 | 1743 | int ret; |
---|
1731 | 1744 | |
---|
1732 | 1745 | rchan->index = index; |
---|
1733 | | - rchan->iomem = dmac->iomem + RCAR_DMAC_CHAN_OFFSET(index); |
---|
| 1746 | + rchan->iomem = dmac->iomem + data->chan_offset_base + |
---|
| 1747 | + data->chan_offset_stride * index; |
---|
1734 | 1748 | rchan->mid_rid = -EINVAL; |
---|
1735 | 1749 | |
---|
1736 | 1750 | spin_lock_init(&rchan->lock); |
---|
.. | .. |
---|
1744 | 1758 | /* Request the channel interrupt. */ |
---|
1745 | 1759 | sprintf(pdev_irqname, "ch%u", index); |
---|
1746 | 1760 | rchan->irq = platform_get_irq_byname(pdev, pdev_irqname); |
---|
1747 | | - if (rchan->irq < 0) { |
---|
1748 | | - dev_err(dmac->dev, "no IRQ specified for channel %u\n", index); |
---|
| 1761 | + if (rchan->irq < 0) |
---|
1749 | 1762 | return -ENODEV; |
---|
1750 | | - } |
---|
1751 | 1763 | |
---|
1752 | 1764 | irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u", |
---|
1753 | 1765 | dev_name(dmac->dev), index); |
---|
.. | .. |
---|
1776 | 1788 | return 0; |
---|
1777 | 1789 | } |
---|
1778 | 1790 | |
---|
| 1791 | +#define RCAR_DMAC_MAX_CHANNELS 32 |
---|
| 1792 | + |
---|
1779 | 1793 | static int rcar_dmac_parse_of(struct device *dev, struct rcar_dmac *dmac) |
---|
1780 | 1794 | { |
---|
1781 | 1795 | struct device_node *np = dev->of_node; |
---|
.. | .. |
---|
1787 | 1801 | return ret; |
---|
1788 | 1802 | } |
---|
1789 | 1803 | |
---|
1790 | | - if (dmac->n_channels <= 0 || dmac->n_channels >= 100) { |
---|
| 1804 | + /* The hardware and driver don't support more than 32 bits in CHCLR */ |
---|
| 1805 | + if (dmac->n_channels <= 0 || |
---|
| 1806 | + dmac->n_channels >= RCAR_DMAC_MAX_CHANNELS) { |
---|
1791 | 1807 | dev_err(dev, "invalid number of channels %u\n", |
---|
1792 | 1808 | dmac->n_channels); |
---|
1793 | 1809 | return -EINVAL; |
---|
1794 | 1810 | } |
---|
| 1811 | + |
---|
| 1812 | + /* |
---|
| 1813 | + * If the driver is unable to read dma-channel-mask property, |
---|
| 1814 | + * the driver assumes that it can use all channels. |
---|
| 1815 | + */ |
---|
| 1816 | + dmac->channels_mask = GENMASK(dmac->n_channels - 1, 0); |
---|
| 1817 | + of_property_read_u32(np, "dma-channel-mask", &dmac->channels_mask); |
---|
| 1818 | + |
---|
| 1819 | + /* If the property has out-of-channel mask, this driver clears it */ |
---|
| 1820 | + dmac->channels_mask &= GENMASK(dmac->n_channels - 1, 0); |
---|
1795 | 1821 | |
---|
1796 | 1822 | return 0; |
---|
1797 | 1823 | } |
---|
.. | .. |
---|
1802 | 1828 | DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES | |
---|
1803 | 1829 | DMA_SLAVE_BUSWIDTH_8_BYTES | DMA_SLAVE_BUSWIDTH_16_BYTES | |
---|
1804 | 1830 | DMA_SLAVE_BUSWIDTH_32_BYTES | DMA_SLAVE_BUSWIDTH_64_BYTES; |
---|
1805 | | - unsigned int channels_offset = 0; |
---|
1806 | 1831 | struct dma_device *engine; |
---|
1807 | 1832 | struct rcar_dmac *dmac; |
---|
1808 | | - struct resource *mem; |
---|
| 1833 | + const struct rcar_dmac_of_data *data; |
---|
1809 | 1834 | unsigned int i; |
---|
1810 | 1835 | int ret; |
---|
| 1836 | + |
---|
| 1837 | + data = of_device_get_match_data(&pdev->dev); |
---|
| 1838 | + if (!data) |
---|
| 1839 | + return -EINVAL; |
---|
1811 | 1840 | |
---|
1812 | 1841 | dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL); |
---|
1813 | 1842 | if (!dmac) |
---|
.. | .. |
---|
1815 | 1844 | |
---|
1816 | 1845 | dmac->dev = &pdev->dev; |
---|
1817 | 1846 | platform_set_drvdata(pdev, dmac); |
---|
1818 | | - dmac->dev->dma_parms = &dmac->parms; |
---|
1819 | | - dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); |
---|
| 1847 | + ret = dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); |
---|
| 1848 | + if (ret) |
---|
| 1849 | + return ret; |
---|
| 1850 | + |
---|
1820 | 1851 | ret = dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40)); |
---|
1821 | 1852 | if (ret) |
---|
1822 | 1853 | return ret; |
---|
.. | .. |
---|
1833 | 1864 | * level we can't disable it selectively, so ignore channel 0 for now if |
---|
1834 | 1865 | * the device is part of an IOMMU group. |
---|
1835 | 1866 | */ |
---|
1836 | | - if (pdev->dev.iommu_group) { |
---|
1837 | | - dmac->n_channels--; |
---|
1838 | | - channels_offset = 1; |
---|
1839 | | - } |
---|
| 1867 | + if (device_iommu_mapped(&pdev->dev)) |
---|
| 1868 | + dmac->channels_mask &= ~BIT(0); |
---|
1840 | 1869 | |
---|
1841 | 1870 | dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels, |
---|
1842 | 1871 | sizeof(*dmac->channels), GFP_KERNEL); |
---|
.. | .. |
---|
1844 | 1873 | return -ENOMEM; |
---|
1845 | 1874 | |
---|
1846 | 1875 | /* Request resources. */ |
---|
1847 | | - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1848 | | - dmac->iomem = devm_ioremap_resource(&pdev->dev, mem); |
---|
| 1876 | + dmac->iomem = devm_platform_ioremap_resource(pdev, 0); |
---|
1849 | 1877 | if (IS_ERR(dmac->iomem)) |
---|
1850 | 1878 | return PTR_ERR(dmac->iomem); |
---|
1851 | 1879 | |
---|
1852 | 1880 | /* Enable runtime PM and initialize the device. */ |
---|
1853 | 1881 | pm_runtime_enable(&pdev->dev); |
---|
1854 | | - ret = pm_runtime_get_sync(&pdev->dev); |
---|
| 1882 | + ret = pm_runtime_resume_and_get(&pdev->dev); |
---|
1855 | 1883 | if (ret < 0) { |
---|
1856 | 1884 | dev_err(&pdev->dev, "runtime PM get sync failed (%d)\n", ret); |
---|
1857 | 1885 | return ret; |
---|
.. | .. |
---|
1894 | 1922 | INIT_LIST_HEAD(&engine->channels); |
---|
1895 | 1923 | |
---|
1896 | 1924 | for (i = 0; i < dmac->n_channels; ++i) { |
---|
1897 | | - ret = rcar_dmac_chan_probe(dmac, &dmac->channels[i], |
---|
1898 | | - i + channels_offset); |
---|
| 1925 | + if (!(dmac->channels_mask & BIT(i))) |
---|
| 1926 | + continue; |
---|
| 1927 | + |
---|
| 1928 | + ret = rcar_dmac_chan_probe(dmac, &dmac->channels[i], data, i); |
---|
1899 | 1929 | if (ret < 0) |
---|
1900 | 1930 | goto error; |
---|
1901 | 1931 | } |
---|
.. | .. |
---|
1942 | 1972 | rcar_dmac_stop_all_chan(dmac); |
---|
1943 | 1973 | } |
---|
1944 | 1974 | |
---|
| 1975 | +static const struct rcar_dmac_of_data rcar_dmac_data = { |
---|
| 1976 | + .chan_offset_base = 0x8000, |
---|
| 1977 | + .chan_offset_stride = 0x80, |
---|
| 1978 | +}; |
---|
| 1979 | + |
---|
1945 | 1980 | static const struct of_device_id rcar_dmac_of_ids[] = { |
---|
1946 | | - { .compatible = "renesas,rcar-dmac", }, |
---|
| 1981 | + { |
---|
| 1982 | + .compatible = "renesas,rcar-dmac", |
---|
| 1983 | + .data = &rcar_dmac_data, |
---|
| 1984 | + }, |
---|
1947 | 1985 | { /* Sentinel */ } |
---|
1948 | 1986 | }; |
---|
1949 | 1987 | MODULE_DEVICE_TABLE(of, rcar_dmac_of_ids); |
---|