aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Jones <lee.jones@linaro.org>2013-05-15 05:51:59 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-04 05:12:11 -0400
commita7dacb68b35a193d9bdaabde1e4e98140d81a991 (patch)
tree61229caedb330dba8e97ff64af7c3d0516988702
parent8cc5af1255966ed82117249a64fe8b13edabc8c5 (diff)
dmaengine: ste_dma40: Allow memcpy channels to be configured from DT
At this moment in time the memcpy channels which can be used by the D40 are fixed, as each supported platform in Mainline uses the same ones. However, platforms do exist which don't follow this convention, so these will need to be tailored. Fortunately, these platforms will be DT only, so this change has very little impact on platform data. Cc: Dan Williams <djbw@fb.com> Cc: Per Forlin <per.forlin@stericsson.com> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Vinod Koul <vinod.koul@intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/dma/ste-dma40.txt2
-rw-r--r--drivers/dma/ste_dma40.c40
-rw-r--r--include/linux/platform_data/dma-ste-dma40.h2
3 files changed, 36 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt
index 2679a873522d..aa272d866f6e 100644
--- a/Documentation/devicetree/bindings/dma/ste-dma40.txt
+++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt
@@ -6,6 +6,7 @@ Required properties:
6- reg-names: Names of the above areas to use during resource look-up 6- reg-names: Names of the above areas to use during resource look-up
7- interrupt: Should contain the DMAC interrupt number 7- interrupt: Should contain the DMAC interrupt number
8- #dma-cells: must be <3> 8- #dma-cells: must be <3>
9- memcpy-channels: Channels to be used for memcpy
9 10
10Optional properties: 11Optional properties:
11- dma-channels: Number of channels supported by hardware - if not present 12- dma-channels: Number of channels supported by hardware - if not present
@@ -21,6 +22,7 @@ Example:
21 interrupts = <0 25 0x4>; 22 interrupts = <0 25 0x4>;
22 23
23 #dma-cells = <2>; 24 #dma-cells = <2>;
25 memcpy-channels = <56 57 58 59 60>;
24 dma-channels = <8>; 26 dma-channels = <8>;
25 }; 27 };
26 28
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 76c255fcdc2d..ae462d352110 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -58,6 +58,8 @@
58#define D40_ALLOC_PHY BIT(30) 58#define D40_ALLOC_PHY BIT(30)
59#define D40_ALLOC_LOG_FREE 0 59#define D40_ALLOC_LOG_FREE 0
60 60
61#define D40_MEMCPY_MAX_CHANS 8
62
61/* Reserved event lines for memcpy only. */ 63/* Reserved event lines for memcpy only. */
62#define DB8500_DMA_MEMCPY_EV_0 51 64#define DB8500_DMA_MEMCPY_EV_0 51
63#define DB8500_DMA_MEMCPY_EV_1 56 65#define DB8500_DMA_MEMCPY_EV_1 56
@@ -522,6 +524,8 @@ struct d40_gen_dmac {
522 * @phy_start: Physical memory start of the DMA registers. 524 * @phy_start: Physical memory start of the DMA registers.
523 * @phy_size: Size of the DMA register map. 525 * @phy_size: Size of the DMA register map.
524 * @irq: The IRQ number. 526 * @irq: The IRQ number.
527 * @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem
528 * transfers).
525 * @num_phy_chans: The number of physical channels. Read from HW. This 529 * @num_phy_chans: The number of physical channels. Read from HW. This
526 * is the number of available channels for this driver, not counting "Secure 530 * is the number of available channels for this driver, not counting "Secure
527 * mode" allocated physical channels. 531 * mode" allocated physical channels.
@@ -565,6 +569,7 @@ struct d40_base {
565 phys_addr_t phy_start; 569 phys_addr_t phy_start;
566 resource_size_t phy_size; 570 resource_size_t phy_size;
567 int irq; 571 int irq;
572 int num_memcpy_chans;
568 int num_phy_chans; 573 int num_phy_chans;
569 int num_log_chans; 574 int num_log_chans;
570 struct device_dma_parameters dma_parms; 575 struct device_dma_parameters dma_parms;
@@ -2938,7 +2943,7 @@ static int __init d40_dmaengine_init(struct d40_base *base,
2938 } 2943 }
2939 2944
2940 d40_chan_init(base, &base->dma_memcpy, base->log_chans, 2945 d40_chan_init(base, &base->dma_memcpy, base->log_chans,
2941 base->num_log_chans, ARRAY_SIZE(dma40_memcpy_channels)); 2946 base->num_log_chans, base->num_memcpy_chans);
2942 2947
2943 dma_cap_zero(base->dma_memcpy.cap_mask); 2948 dma_cap_zero(base->dma_memcpy.cap_mask);
2944 dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); 2949 dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
@@ -3139,6 +3144,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
3139 struct d40_base *base = NULL; 3144 struct d40_base *base = NULL;
3140 int num_log_chans = 0; 3145 int num_log_chans = 0;
3141 int num_phy_chans; 3146 int num_phy_chans;
3147 int num_memcpy_chans;
3142 int clk_ret = -EINVAL; 3148 int clk_ret = -EINVAL;
3143 int i; 3149 int i;
3144 u32 pid; 3150 u32 pid;
@@ -3209,6 +3215,12 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
3209 else 3215 else
3210 num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; 3216 num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4;
3211 3217
3218 /* The number of channels used for memcpy */
3219 if (plat_data->num_of_memcpy_chans)
3220 num_memcpy_chans = plat_data->num_of_memcpy_chans;
3221 else
3222 num_memcpy_chans = ARRAY_SIZE(dma40_memcpy_channels);
3223
3212 num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY; 3224 num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY;
3213 3225
3214 dev_info(&pdev->dev, 3226 dev_info(&pdev->dev,
@@ -3216,7 +3228,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
3216 rev, res->start, num_phy_chans, num_log_chans); 3228 rev, res->start, num_phy_chans, num_log_chans);
3217 3229
3218 base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + 3230 base = kzalloc(ALIGN(sizeof(struct d40_base), 4) +
3219 (num_phy_chans + num_log_chans + ARRAY_SIZE(dma40_memcpy_channels)) * 3231 (num_phy_chans + num_log_chans + num_memcpy_chans) *
3220 sizeof(struct d40_chan), GFP_KERNEL); 3232 sizeof(struct d40_chan), GFP_KERNEL);
3221 3233
3222 if (base == NULL) { 3234 if (base == NULL) {
@@ -3226,6 +3238,7 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
3226 3238
3227 base->rev = rev; 3239 base->rev = rev;
3228 base->clk = clk; 3240 base->clk = clk;
3241 base->num_memcpy_chans = num_memcpy_chans;
3229 base->num_phy_chans = num_phy_chans; 3242 base->num_phy_chans = num_phy_chans;
3230 base->num_log_chans = num_log_chans; 3243 base->num_log_chans = num_log_chans;
3231 base->phy_start = res->start; 3244 base->phy_start = res->start;
@@ -3469,12 +3482,8 @@ static int __init d40_of_probe(struct platform_device *pdev,
3469 struct device_node *np) 3482 struct device_node *np)
3470{ 3483{
3471 struct stedma40_platform_data *pdata; 3484 struct stedma40_platform_data *pdata;
3472 3485 int num_memcpy = 0;
3473 /* 3486 const const __be32 *list;
3474 * FIXME: Fill in this routine as more support is added.
3475 * First platform enabled (u8500) doens't need any extra
3476 * properties to run, so this is fairly sparce currently.
3477 */
3478 3487
3479 pdata = devm_kzalloc(&pdev->dev, 3488 pdata = devm_kzalloc(&pdev->dev,
3480 sizeof(struct stedma40_platform_data), 3489 sizeof(struct stedma40_platform_data),
@@ -3482,6 +3491,21 @@ static int __init d40_of_probe(struct platform_device *pdev,
3482 if (!pdata) 3491 if (!pdata)
3483 return -ENOMEM; 3492 return -ENOMEM;
3484 3493
3494 list = of_get_property(np, "memcpy-channels", &num_memcpy);
3495 num_memcpy /= sizeof(*list);
3496
3497 if (num_memcpy > D40_MEMCPY_MAX_CHANS || num_memcpy <= 0) {
3498 d40_err(&pdev->dev,
3499 "Invalid number of memcpy channels specified (%d)\n",
3500 num_memcpy);
3501 return -EINVAL;
3502 }
3503 pdata->num_of_memcpy_chans = num_memcpy;
3504
3505 of_property_read_u32_array(np, "memcpy-channels",
3506 dma40_memcpy_channels,
3507 num_memcpy);
3508
3485 pdev->dev.platform_data = pdata; 3509 pdev->dev.platform_data = pdata;
3486 3510
3487 return 0; 3511 return 0;
diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h
index ceba6dc566a9..1bb9b1852256 100644
--- a/include/linux/platform_data/dma-ste-dma40.h
+++ b/include/linux/platform_data/dma-ste-dma40.h
@@ -132,6 +132,7 @@ struct stedma40_chan_cfg {
132 * @num_of_soft_lli_chans: The number of channels that needs to be configured 132 * @num_of_soft_lli_chans: The number of channels that needs to be configured
133 * to use SoftLLI. 133 * to use SoftLLI.
134 * @use_esram_lcla: flag for mapping the lcla into esram region 134 * @use_esram_lcla: flag for mapping the lcla into esram region
135 * @num_of_memcpy_chans: The number of channels reserved for memcpy.
135 * @num_of_phy_chans: The number of physical channels implemented in HW. 136 * @num_of_phy_chans: The number of physical channels implemented in HW.
136 * 0 means reading the number of channels from DMA HW but this is only valid 137 * 0 means reading the number of channels from DMA HW but this is only valid
137 * for 'multiple of 4' channels, like 8. 138 * for 'multiple of 4' channels, like 8.
@@ -141,6 +142,7 @@ struct stedma40_platform_data {
141 int *soft_lli_chans; 142 int *soft_lli_chans;
142 int num_of_soft_lli_chans; 143 int num_of_soft_lli_chans;
143 bool use_esram_lcla; 144 bool use_esram_lcla;
145 int num_of_memcpy_chans;
144 int num_of_phy_chans; 146 int num_of_phy_chans;
145}; 147};
146 148