aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2015-10-30 22:05:07 -0400
committerVinod Koul <vinod.koul@intel.com>2015-10-30 22:05:07 -0400
commit6df056d8e69a557ac76bc7a88960e4addbc98386 (patch)
tree6329893f9dc953d3a87a2a6a6a22356d99d0562c
parent67d25f0d4e24775418aae403610cae99e27cdc3c (diff)
parentdf5c7386f62d2db95ca48005087195e9a15e2b1f (diff)
Merge branch 'topic/dw' into for-linus
-rw-r--r--drivers/dma/dw/core.c63
-rw-r--r--drivers/dma/dw/platform.c17
-rw-r--r--include/linux/platform_data/dma-dw.h2
3 files changed, 50 insertions, 32 deletions
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 46859f738fcf..41e9554b884d 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -1499,9 +1499,8 @@ EXPORT_SYMBOL(dw_dma_cyclic_free);
1499int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) 1499int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1500{ 1500{
1501 struct dw_dma *dw; 1501 struct dw_dma *dw;
1502 bool autocfg; 1502 bool autocfg = false;
1503 unsigned int dw_params; 1503 unsigned int dw_params;
1504 unsigned int nr_channels;
1505 unsigned int max_blk_size = 0; 1504 unsigned int max_blk_size = 0;
1506 int err; 1505 int err;
1507 int i; 1506 int i;
@@ -1515,33 +1514,42 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1515 1514
1516 pm_runtime_get_sync(chip->dev); 1515 pm_runtime_get_sync(chip->dev);
1517 1516
1518 dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); 1517 if (!pdata) {
1519 autocfg = dw_params >> DW_PARAMS_EN & 0x1; 1518 dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
1519 dev_dbg(chip->dev, "DW_PARAMS: 0x%08x\n", dw_params);
1520 1520
1521 dev_dbg(chip->dev, "DW_PARAMS: 0x%08x\n", dw_params); 1521 autocfg = dw_params >> DW_PARAMS_EN & 1;
1522 if (!autocfg) {
1523 err = -EINVAL;
1524 goto err_pdata;
1525 }
1522 1526
1523 if (!pdata && autocfg) {
1524 pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL); 1527 pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL);
1525 if (!pdata) { 1528 if (!pdata) {
1526 err = -ENOMEM; 1529 err = -ENOMEM;
1527 goto err_pdata; 1530 goto err_pdata;
1528 } 1531 }
1529 1532
1533 /* Get hardware configuration parameters */
1534 pdata->nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 7) + 1;
1535 pdata->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
1536 for (i = 0; i < pdata->nr_masters; i++) {
1537 pdata->data_width[i] =
1538 (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
1539 }
1540 max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
1541
1530 /* Fill platform data with the default values */ 1542 /* Fill platform data with the default values */
1531 pdata->is_private = true; 1543 pdata->is_private = true;
1544 pdata->is_memcpy = true;
1532 pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING; 1545 pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
1533 pdata->chan_priority = CHAN_PRIORITY_ASCENDING; 1546 pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
1534 } else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) { 1547 } else if (pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) {
1535 err = -EINVAL; 1548 err = -EINVAL;
1536 goto err_pdata; 1549 goto err_pdata;
1537 } 1550 }
1538 1551
1539 if (autocfg) 1552 dw->chan = devm_kcalloc(chip->dev, pdata->nr_channels, sizeof(*dw->chan),
1540 nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
1541 else
1542 nr_channels = pdata->nr_channels;
1543
1544 dw->chan = devm_kcalloc(chip->dev, nr_channels, sizeof(*dw->chan),
1545 GFP_KERNEL); 1553 GFP_KERNEL);
1546 if (!dw->chan) { 1554 if (!dw->chan) {
1547 err = -ENOMEM; 1555 err = -ENOMEM;
@@ -1549,22 +1557,12 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1549 } 1557 }
1550 1558
1551 /* Get hardware configuration parameters */ 1559 /* Get hardware configuration parameters */
1552 if (autocfg) { 1560 dw->nr_masters = pdata->nr_masters;
1553 max_blk_size = dma_readl(dw, MAX_BLK_SIZE); 1561 for (i = 0; i < dw->nr_masters; i++)
1554 1562 dw->data_width[i] = pdata->data_width[i];
1555 dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
1556 for (i = 0; i < dw->nr_masters; i++) {
1557 dw->data_width[i] =
1558 (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
1559 }
1560 } else {
1561 dw->nr_masters = pdata->nr_masters;
1562 for (i = 0; i < dw->nr_masters; i++)
1563 dw->data_width[i] = pdata->data_width[i];
1564 }
1565 1563
1566 /* Calculate all channel mask before DMA setup */ 1564 /* Calculate all channel mask before DMA setup */
1567 dw->all_chan_mask = (1 << nr_channels) - 1; 1565 dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
1568 1566
1569 /* Force dma off, just in case */ 1567 /* Force dma off, just in case */
1570 dw_dma_off(dw); 1568 dw_dma_off(dw);
@@ -1589,7 +1587,7 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1589 goto err_pdata; 1587 goto err_pdata;
1590 1588
1591 INIT_LIST_HEAD(&dw->dma.channels); 1589 INIT_LIST_HEAD(&dw->dma.channels);
1592 for (i = 0; i < nr_channels; i++) { 1590 for (i = 0; i < pdata->nr_channels; i++) {
1593 struct dw_dma_chan *dwc = &dw->chan[i]; 1591 struct dw_dma_chan *dwc = &dw->chan[i];
1594 int r = nr_channels - i - 1; 1592 int r = nr_channels - i - 1;
1595 1593
@@ -1603,7 +1601,7 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1603 1601
1604 /* 7 is highest priority & 0 is lowest. */ 1602 /* 7 is highest priority & 0 is lowest. */
1605 if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING) 1603 if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
1606 dwc->priority = r; 1604 dwc->priority = pdata->nr_channels - i - 1;
1607 else 1605 else
1608 dwc->priority = i; 1606 dwc->priority = i;
1609 1607
@@ -1656,10 +1654,13 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1656 dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask); 1654 dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
1657 dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask); 1655 dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
1658 1656
1659 dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask); 1657 /* Set capabilities */
1660 dma_cap_set(DMA_SLAVE, dw->dma.cap_mask); 1658 dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
1661 if (pdata->is_private) 1659 if (pdata->is_private)
1662 dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask); 1660 dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
1661 if (pdata->is_memcpy)
1662 dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
1663
1663 dw->dma.dev = chip->dev; 1664 dw->dma.dev = chip->dev;
1664 dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources; 1665 dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
1665 dw->dma.device_free_chan_resources = dwc_free_chan_resources; 1666 dw->dma.device_free_chan_resources = dwc_free_chan_resources;
@@ -1687,7 +1688,7 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1687 goto err_dma_register; 1688 goto err_dma_register;
1688 1689
1689 dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n", 1690 dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n",
1690 nr_channels); 1691 pdata->nr_channels);
1691 1692
1692 pm_runtime_put_sync_suspend(chip->dev); 1693 pm_runtime_put_sync_suspend(chip->dev);
1693 1694
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index b2c3ae071429..68a4815750b5 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -155,6 +155,7 @@ static int dw_probe(struct platform_device *pdev)
155 struct dw_dma_chip *chip; 155 struct dw_dma_chip *chip;
156 struct device *dev = &pdev->dev; 156 struct device *dev = &pdev->dev;
157 struct resource *mem; 157 struct resource *mem;
158 const struct acpi_device_id *id;
158 struct dw_dma_platform_data *pdata; 159 struct dw_dma_platform_data *pdata;
159 int err; 160 int err;
160 161
@@ -178,6 +179,11 @@ static int dw_probe(struct platform_device *pdev)
178 pdata = dev_get_platdata(dev); 179 pdata = dev_get_platdata(dev);
179 if (!pdata) 180 if (!pdata)
180 pdata = dw_dma_parse_dt(pdev); 181 pdata = dw_dma_parse_dt(pdev);
182 if (!pdata && has_acpi_companion(dev)) {
183 id = acpi_match_device(dev->driver->acpi_match_table, dev);
184 if (id)
185 pdata = (struct dw_dma_platform_data *)id->driver_data;
186 }
181 187
182 chip->dev = dev; 188 chip->dev = dev;
183 189
@@ -246,8 +252,17 @@ MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
246#endif 252#endif
247 253
248#ifdef CONFIG_ACPI 254#ifdef CONFIG_ACPI
255static struct dw_dma_platform_data dw_dma_acpi_pdata = {
256 .nr_channels = 8,
257 .is_private = true,
258 .chan_allocation_order = CHAN_ALLOCATION_ASCENDING,
259 .chan_priority = CHAN_PRIORITY_ASCENDING,
260 .block_size = 4095,
261 .nr_masters = 2,
262};
263
249static const struct acpi_device_id dw_dma_acpi_id_table[] = { 264static const struct acpi_device_id dw_dma_acpi_id_table[] = {
250 { "INTL9C60", 0 }, 265 { "INTL9C60", (kernel_ulong_t)&dw_dma_acpi_pdata },
251 { } 266 { }
252}; 267};
253MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table); 268MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table);
diff --git a/include/linux/platform_data/dma-dw.h b/include/linux/platform_data/dma-dw.h
index 87ac14c584f2..03b6095d3b18 100644
--- a/include/linux/platform_data/dma-dw.h
+++ b/include/linux/platform_data/dma-dw.h
@@ -37,6 +37,7 @@ struct dw_dma_slave {
37 * @nr_channels: Number of channels supported by hardware (max 8) 37 * @nr_channels: Number of channels supported by hardware (max 8)
38 * @is_private: The device channels should be marked as private and not for 38 * @is_private: The device channels should be marked as private and not for
39 * by the general purpose DMA channel allocator. 39 * by the general purpose DMA channel allocator.
40 * @is_memcpy: The device channels do support memory-to-memory transfers.
40 * @chan_allocation_order: Allocate channels starting from 0 or 7 41 * @chan_allocation_order: Allocate channels starting from 0 or 7
41 * @chan_priority: Set channel priority increasing from 0 to 7 or 7 to 0. 42 * @chan_priority: Set channel priority increasing from 0 to 7 or 7 to 0.
42 * @block_size: Maximum block size supported by the controller 43 * @block_size: Maximum block size supported by the controller
@@ -47,6 +48,7 @@ struct dw_dma_slave {
47struct dw_dma_platform_data { 48struct dw_dma_platform_data {
48 unsigned int nr_channels; 49 unsigned int nr_channels;
49 bool is_private; 50 bool is_private;
51 bool is_memcpy;
50#define CHAN_ALLOCATION_ASCENDING 0 /* zero to seven */ 52#define CHAN_ALLOCATION_ASCENDING 0 /* zero to seven */
51#define CHAN_ALLOCATION_DESCENDING 1 /* seven to zero */ 53#define CHAN_ALLOCATION_DESCENDING 1 /* seven to zero */
52 unsigned char chan_allocation_order; 54 unsigned char chan_allocation_order;