1 /* 2 * Platform driver for the Synopsys DesignWare DMA Controller 3 * 4 * Copyright (C) 2007-2008 Atmel Corporation 5 * Copyright (C) 2010-2011 ST Microelectronics 6 * Copyright (C) 2013 Intel Corporation 7 * 8 * Some parts of this driver are derived from the original dw_dmac. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <linux/module.h> 16 #include <linux/device.h> 17 #include <linux/clk.h> 18 #include <linux/platform_device.h> 19 #include <linux/dmaengine.h> 20 #include <linux/dma-mapping.h> 21 #include <linux/of.h> 22 #include <linux/of_dma.h> 23 #include <linux/acpi.h> 24 #include <linux/acpi_dma.h> 25 26 #include "internal.h" 27 28 struct dw_dma_of_filter_args { 29 struct dw_dma *dw; 30 unsigned int req; 31 unsigned int src; 32 unsigned int dst; 33 }; 34 35 static bool dw_dma_of_filter(struct dma_chan *chan, void *param) 36 { 37 struct dw_dma_chan *dwc = to_dw_dma_chan(chan); 38 struct dw_dma_of_filter_args *fargs = param; 39 40 /* Ensure the device matches our channel */ 41 if (chan->device != &fargs->dw->dma) 42 return false; 43 44 dwc->request_line = fargs->req; 45 dwc->src_master = fargs->src; 46 dwc->dst_master = fargs->dst; 47 48 return true; 49 } 50 51 static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, 52 struct of_dma *ofdma) 53 { 54 struct dw_dma *dw = ofdma->of_dma_data; 55 struct dw_dma_of_filter_args fargs = { 56 .dw = dw, 57 }; 58 dma_cap_mask_t cap; 59 60 if (dma_spec->args_count != 3) 61 return NULL; 62 63 fargs.req = dma_spec->args[0]; 64 fargs.src = dma_spec->args[1]; 65 fargs.dst = dma_spec->args[2]; 66 67 if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS || 68 fargs.src >= dw->nr_masters || 69 fargs.dst >= dw->nr_masters)) 70 return NULL; 71 72 dma_cap_zero(cap); 73 dma_cap_set(DMA_SLAVE, cap); 74 75 /* TODO: there should be a simpler way to do this */ 76 return dma_request_channel(cap, dw_dma_of_filter, &fargs); 77 } 78 79 #ifdef CONFIG_ACPI 80 static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param) 81 { 82 struct dw_dma_chan *dwc = to_dw_dma_chan(chan); 83 struct acpi_dma_spec *dma_spec = param; 84 85 if (chan->device->dev != dma_spec->dev || 86 chan->chan_id != dma_spec->chan_id) 87 return false; 88 89 dwc->request_line = dma_spec->slave_id; 90 dwc->src_master = dwc_get_sms(NULL); 91 dwc->dst_master = dwc_get_dms(NULL); 92 93 return true; 94 } 95 96 static void dw_dma_acpi_controller_register(struct dw_dma *dw) 97 { 98 struct device *dev = dw->dma.dev; 99 struct acpi_dma_filter_info *info; 100 int ret; 101 102 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 103 if (!info) 104 return; 105 106 dma_cap_zero(info->dma_cap); 107 dma_cap_set(DMA_SLAVE, info->dma_cap); 108 info->filter_fn = dw_dma_acpi_filter; 109 110 ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate, 111 info); 112 if (ret) 113 dev_err(dev, "could not register acpi_dma_controller\n"); 114 } 115 #else /* !CONFIG_ACPI */ 116 static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {} 117 #endif /* !CONFIG_ACPI */ 118 119 #ifdef CONFIG_OF 120 static struct dw_dma_platform_data * 121 dw_dma_parse_dt(struct platform_device *pdev) 122 { 123 struct device_node *np = pdev->dev.of_node; 124 struct dw_dma_platform_data *pdata; 125 u32 tmp, arr[4]; 126 127 if (!np) { 128 dev_err(&pdev->dev, "Missing DT data\n"); 129 return NULL; 130 } 131 132 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 133 if (!pdata) 134 return NULL; 135 136 if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels)) 137 return NULL; 138 139 if (of_property_read_bool(np, "is_private")) 140 pdata->is_private = true; 141 142 if (!of_property_read_u32(np, "chan_allocation_order", &tmp)) 143 pdata->chan_allocation_order = (unsigned char)tmp; 144 145 if (!of_property_read_u32(np, "chan_priority", &tmp)) 146 pdata->chan_priority = tmp; 147 148 if (!of_property_read_u32(np, "block_size", &tmp)) 149 pdata->block_size = tmp; 150 151 if (!of_property_read_u32(np, "dma-masters", &tmp)) { 152 if (tmp > 4) 153 return NULL; 154 155 pdata->nr_masters = tmp; 156 } 157 158 if (!of_property_read_u32_array(np, "data_width", arr, 159 pdata->nr_masters)) 160 for (tmp = 0; tmp < pdata->nr_masters; tmp++) 161 pdata->data_width[tmp] = arr[tmp]; 162 163 return pdata; 164 } 165 #else 166 static inline struct dw_dma_platform_data * 167 dw_dma_parse_dt(struct platform_device *pdev) 168 { 169 return NULL; 170 } 171 #endif 172 173 static int dw_probe(struct platform_device *pdev) 174 { 175 struct dw_dma_chip *chip; 176 struct device *dev = &pdev->dev; 177 struct resource *mem; 178 struct dw_dma_platform_data *pdata; 179 int err; 180 181 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 182 if (!chip) 183 return -ENOMEM; 184 185 chip->irq = platform_get_irq(pdev, 0); 186 if (chip->irq < 0) 187 return chip->irq; 188 189 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 190 chip->regs = devm_ioremap_resource(dev, mem); 191 if (IS_ERR(chip->regs)) 192 return PTR_ERR(chip->regs); 193 194 /* Apply default dma_mask if needed */ 195 if (!dev->dma_mask) { 196 dev->dma_mask = &dev->coherent_dma_mask; 197 dev->coherent_dma_mask = DMA_BIT_MASK(32); 198 } 199 200 pdata = dev_get_platdata(dev); 201 if (!pdata) 202 pdata = dw_dma_parse_dt(pdev); 203 204 chip->dev = dev; 205 206 err = dw_dma_probe(chip, pdata); 207 if (err) 208 return err; 209 210 platform_set_drvdata(pdev, chip); 211 212 if (pdev->dev.of_node) { 213 err = of_dma_controller_register(pdev->dev.of_node, 214 dw_dma_of_xlate, chip->dw); 215 if (err) 216 dev_err(&pdev->dev, 217 "could not register of_dma_controller\n"); 218 } 219 220 if (ACPI_HANDLE(&pdev->dev)) 221 dw_dma_acpi_controller_register(chip->dw); 222 223 return 0; 224 } 225 226 static int dw_remove(struct platform_device *pdev) 227 { 228 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 229 230 if (pdev->dev.of_node) 231 of_dma_controller_free(pdev->dev.of_node); 232 233 return dw_dma_remove(chip); 234 } 235 236 static void dw_shutdown(struct platform_device *pdev) 237 { 238 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 239 240 dw_dma_shutdown(chip); 241 } 242 243 #ifdef CONFIG_OF 244 static const struct of_device_id dw_dma_of_id_table[] = { 245 { .compatible = "snps,dma-spear1340" }, 246 {} 247 }; 248 MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); 249 #endif 250 251 #ifdef CONFIG_ACPI 252 static const struct acpi_device_id dw_dma_acpi_id_table[] = { 253 { "INTL9C60", 0 }, 254 { } 255 }; 256 MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table); 257 #endif 258 259 #ifdef CONFIG_PM_SLEEP 260 261 static int dw_suspend_noirq(struct device *dev) 262 { 263 struct platform_device *pdev = to_platform_device(dev); 264 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 265 266 return dw_dma_suspend(chip); 267 } 268 269 static int dw_resume_noirq(struct device *dev) 270 { 271 struct platform_device *pdev = to_platform_device(dev); 272 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 273 274 return dw_dma_resume(chip); 275 } 276 277 #else /* !CONFIG_PM_SLEEP */ 278 279 #define dw_suspend_noirq NULL 280 #define dw_resume_noirq NULL 281 282 #endif /* !CONFIG_PM_SLEEP */ 283 284 static const struct dev_pm_ops dw_dev_pm_ops = { 285 .suspend_noirq = dw_suspend_noirq, 286 .resume_noirq = dw_resume_noirq, 287 .freeze_noirq = dw_suspend_noirq, 288 .thaw_noirq = dw_resume_noirq, 289 .restore_noirq = dw_resume_noirq, 290 .poweroff_noirq = dw_suspend_noirq, 291 }; 292 293 static struct platform_driver dw_driver = { 294 .probe = dw_probe, 295 .remove = dw_remove, 296 .shutdown = dw_shutdown, 297 .driver = { 298 .name = "dw_dmac", 299 .pm = &dw_dev_pm_ops, 300 .of_match_table = of_match_ptr(dw_dma_of_id_table), 301 .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table), 302 }, 303 }; 304 305 static int __init dw_init(void) 306 { 307 return platform_driver_register(&dw_driver); 308 } 309 subsys_initcall(dw_init); 310 311 static void __exit dw_exit(void) 312 { 313 platform_driver_unregister(&dw_driver); 314 } 315 module_exit(dw_exit); 316 317 MODULE_LICENSE("GPL v2"); 318 MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver"); 319