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 err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 195 if (err) 196 return err; 197 198 pdata = dev_get_platdata(dev); 199 if (!pdata) 200 pdata = dw_dma_parse_dt(pdev); 201 202 chip->dev = dev; 203 204 err = dw_dma_probe(chip, pdata); 205 if (err) 206 return err; 207 208 platform_set_drvdata(pdev, chip); 209 210 if (pdev->dev.of_node) { 211 err = of_dma_controller_register(pdev->dev.of_node, 212 dw_dma_of_xlate, chip->dw); 213 if (err) 214 dev_err(&pdev->dev, 215 "could not register of_dma_controller\n"); 216 } 217 218 if (ACPI_HANDLE(&pdev->dev)) 219 dw_dma_acpi_controller_register(chip->dw); 220 221 return 0; 222 } 223 224 static int dw_remove(struct platform_device *pdev) 225 { 226 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 227 228 if (pdev->dev.of_node) 229 of_dma_controller_free(pdev->dev.of_node); 230 231 return dw_dma_remove(chip); 232 } 233 234 static void dw_shutdown(struct platform_device *pdev) 235 { 236 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 237 238 dw_dma_shutdown(chip); 239 } 240 241 #ifdef CONFIG_OF 242 static const struct of_device_id dw_dma_of_id_table[] = { 243 { .compatible = "snps,dma-spear1340" }, 244 {} 245 }; 246 MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); 247 #endif 248 249 #ifdef CONFIG_ACPI 250 static const struct acpi_device_id dw_dma_acpi_id_table[] = { 251 { "INTL9C60", 0 }, 252 { } 253 }; 254 MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table); 255 #endif 256 257 #ifdef CONFIG_PM_SLEEP 258 259 static int dw_suspend_noirq(struct device *dev) 260 { 261 struct platform_device *pdev = to_platform_device(dev); 262 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 263 264 return dw_dma_suspend(chip); 265 } 266 267 static int dw_resume_noirq(struct device *dev) 268 { 269 struct platform_device *pdev = to_platform_device(dev); 270 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 271 272 return dw_dma_resume(chip); 273 } 274 275 #else /* !CONFIG_PM_SLEEP */ 276 277 #define dw_suspend_noirq NULL 278 #define dw_resume_noirq NULL 279 280 #endif /* !CONFIG_PM_SLEEP */ 281 282 static const struct dev_pm_ops dw_dev_pm_ops = { 283 .suspend_noirq = dw_suspend_noirq, 284 .resume_noirq = dw_resume_noirq, 285 .freeze_noirq = dw_suspend_noirq, 286 .thaw_noirq = dw_resume_noirq, 287 .restore_noirq = dw_resume_noirq, 288 .poweroff_noirq = dw_suspend_noirq, 289 }; 290 291 static struct platform_driver dw_driver = { 292 .probe = dw_probe, 293 .remove = dw_remove, 294 .shutdown = dw_shutdown, 295 .driver = { 296 .name = "dw_dmac", 297 .pm = &dw_dev_pm_ops, 298 .of_match_table = of_match_ptr(dw_dma_of_id_table), 299 .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table), 300 }, 301 }; 302 303 static int __init dw_init(void) 304 { 305 return platform_driver_register(&dw_driver); 306 } 307 subsys_initcall(dw_init); 308 309 static void __exit dw_exit(void) 310 { 311 platform_driver_unregister(&dw_driver); 312 } 313 module_exit(dw_exit); 314 315 MODULE_LICENSE("GPL v2"); 316 MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver"); 317